mastracode 0.24.0-alpha.0 → 0.25.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.
Files changed (45) hide show
  1. package/CHANGELOG.md +242 -0
  2. package/dist/agents/thread-caveman-state.d.ts +3 -3
  3. package/dist/agents/thread-caveman-state.d.ts.map +1 -1
  4. package/dist/{chunk-KYA2RSC5.js → chunk-2O2ZASVX.js} +128 -129
  5. package/dist/chunk-2O2ZASVX.js.map +1 -0
  6. package/dist/{chunk-S2RM75NL.cjs → chunk-IK6NZ3MB.cjs} +167 -2
  7. package/dist/chunk-IK6NZ3MB.cjs.map +1 -0
  8. package/dist/{chunk-T7R2KIKY.cjs → chunk-LOOVXQYW.cjs} +1036 -1037
  9. package/dist/chunk-LOOVXQYW.cjs.map +1 -0
  10. package/dist/{chunk-AUIPVVAS.js → chunk-ONKJTRKR.js} +163 -4
  11. package/dist/chunk-ONKJTRKR.js.map +1 -0
  12. package/dist/{chunk-3JEAYMT5.js → chunk-TZBT6UPD.js} +54 -190
  13. package/dist/chunk-TZBT6UPD.js.map +1 -0
  14. package/dist/{chunk-XRYRSXRP.cjs → chunk-XBRRTTRT.cjs} +87 -223
  15. package/dist/chunk-XBRRTTRT.cjs.map +1 -0
  16. package/dist/cli.cjs +51 -50
  17. package/dist/cli.cjs.map +1 -1
  18. package/dist/cli.js +36 -35
  19. package/dist/cli.js.map +1 -1
  20. package/dist/evals/context-builder.d.ts +3 -1
  21. package/dist/evals/context-builder.d.ts.map +1 -1
  22. package/dist/headless.d.ts +2 -2
  23. package/dist/headless.d.ts.map +1 -1
  24. package/dist/index.cjs +3 -3
  25. package/dist/index.d.ts +2 -1
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +1 -1
  28. package/dist/onboarding/settings.d.ts.map +1 -1
  29. package/dist/tui/commands/clone.d.ts +1 -1
  30. package/dist/tui/commands/feedback.d.ts.map +1 -1
  31. package/dist/tui/commands/github.d.ts.map +1 -1
  32. package/dist/tui/commands/models-pack.d.ts.map +1 -1
  33. package/dist/tui/commands/resource.d.ts.map +1 -1
  34. package/dist/tui/render-messages.d.ts.map +1 -1
  35. package/dist/tui/state.d.ts +2 -0
  36. package/dist/tui/state.d.ts.map +1 -1
  37. package/dist/tui.cjs +19 -19
  38. package/dist/tui.js +2 -2
  39. package/package.json +16 -16
  40. package/dist/chunk-3JEAYMT5.js.map +0 -1
  41. package/dist/chunk-AUIPVVAS.js.map +0 -1
  42. package/dist/chunk-KYA2RSC5.js.map +0 -1
  43. package/dist/chunk-S2RM75NL.cjs.map +0 -1
  44. package/dist/chunk-T7R2KIKY.cjs.map +0 -1
  45. package/dist/chunk-XRYRSXRP.cjs.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,247 @@
1
1
  # mastracode
2
2
 
3
+ ## 0.25.0-alpha.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Added automatic OpenAI subscription support for Stagehand browser automation. When a user has an active OpenAI subscription (authenticated via /login), Stagehand now uses the subscription credentials for its AI operations (act/extract/observe) instead of requiring a separate OPENAI_API_KEY. ([#18233](https://github.com/mastra-ai/mastra/pull/18233))
8
+
9
+ ### Patch Changes
10
+
11
+ - Removed the deprecated `Harness.getState()` and `Harness.setState()` compatibility wrappers, along with the unused private `updateState`. Harness state has lived on the session for a while; these were thin proxies marked `@deprecated`. ([#18200](https://github.com/mastra-ai/mastra/pull/18200))
12
+
13
+ **Before**
14
+
15
+ ```typescript
16
+ const state = harness.getState();
17
+ await harness.setState({ count: 1 });
18
+ ```
19
+
20
+ **After**
21
+
22
+ ```typescript
23
+ const state = harness.session.state.get();
24
+ await harness.session.state.set({ count: 1 });
25
+ ```
26
+
27
+ This does not affect the tool-facing harness context, which continues to expose `state` / `getState` / `setState` / `updateState` alongside `session.state`.
28
+
29
+ `mastracode` is updated to set browser settings via `session.state.set()`.
30
+
31
+ - Moved the observational-memory model accessors off the Harness onto `session.om`. Reading and switching the observer/reflector models and reading observation/reflection thresholds now live on the session, next to the state they read and write. ([#18200](https://github.com/mastra-ai/mastra/pull/18200))
32
+
33
+ **Before**
34
+
35
+ ```typescript
36
+ const observer = harness.getObserverModelId();
37
+ await harness.switchObserverModel({ modelId: 'openai/gpt-4o' });
38
+ ```
39
+
40
+ **After**
41
+
42
+ ```typescript
43
+ const observer = harness.session.om.observer.modelId();
44
+ await harness.session.om.observer.switchModel({ modelId: 'openai/gpt-4o' });
45
+ ```
46
+
47
+ The accessors are grouped by role under `session.om.observer` and `session.om.reflector`, each exposing `modelId()`, `threshold()`, `resolvedModel()`, and `switchModel({ modelId })`.
48
+
49
+ Removed `Harness.getObserverModelId`, `getReflectorModelId`, `getObservationThreshold`, `getReflectionThreshold`, `getResolvedObserverModel`, `getResolvedReflectorModel`, `switchObserverModel`, and `switchReflectorModel`.
50
+
51
+ `mastracode` is updated to consume the new API: the `/om` command and status line now read and switch observer/reflector models via `session.om`.
52
+
53
+ - Moved the run-control surface off the Harness onto the `Session`. Sending messages and signals, steering, following up, aborting, responding to tool suspensions, and saving system reminders now live on the session that owns the run state they drive, instead of being delegated through the Harness. This is the final step of the single-session extraction series and a prerequisite for the upcoming multi-session (`createSession`) work: every per-session operation now lives on `Session`, while the Harness retains only genuinely shared machinery (agent, config builders, storage/lock gateway), which it injects into each session via the `SessionMachinery` provider. ([#18213](https://github.com/mastra-ai/mastra/pull/18213))
54
+
55
+ **Before**
56
+
57
+ ```typescript
58
+ await harness.sendMessage({ content: 'hello' });
59
+ harness.sendSignal({ content: 'steer the run' });
60
+ harness.abort();
61
+ await harness.respondToToolSuspension({ toolCallId, approved: true });
62
+ ```
63
+
64
+ **After**
65
+
66
+ ```typescript
67
+ const session = await harness.createSession();
68
+ await session.sendMessage({ content: 'hello' });
69
+ session.sendSignal({ content: 'steer the run' });
70
+ session.abort();
71
+ await session.respondToToolSuspension({ toolCallId, approved: true });
72
+ ```
73
+
74
+ Removed `Harness.sendMessage`, `Harness.sendSignal`, `Harness.sendNotificationSignal`, `Harness.steer`, `Harness.followUp`, `Harness.abort`, `Harness.respondToToolSuspension`, `Harness.saveSystemReminderMessage`, and `Harness.waitForCurrentThreadStreamIdle`. The `Session` reaches Harness-owned machinery through the injected `SessionMachinery` provider, so the heavy run loop is still constructed and owned by the Harness while being parameterized by the session it runs on.
75
+
76
+ `mastracode` is updated to consume the new API: the TUI run loop, slash-command dispatch, goal lifecycle, prompt handlers, and headless entry points all drive run-control through the session returned by `harness.createSession()`.
77
+
78
+ - The Harness event bus now lives on the Session. Each `Session` owns its own listeners and emit pipeline (`session.subscribe()` / internal `session.emit()`), so events emitted on one session are delivered only to that session's subscribers — never to another session's. This is the isolation foundation for serving a single Harness to multiple concurrent sessions (e.g. one Harness backing many channel threads). ([#18213](https://github.com/mastra-ai/mastra/pull/18213))
79
+
80
+ Breaking (Harness is under active development): `Harness.subscribe()` is removed. Subscribe on the session instead:
81
+
82
+ ```diff
83
+ - harness.subscribe(listener)
84
+ + harness.session.subscribe(listener)
85
+ ```
86
+
87
+ Session subsystems (mode/model/om/permissions/subagents/state) no longer receive an injected `emit` callback — they emit directly to their session's bus. `mastracode` is updated to subscribe via `harness.session.subscribe()`.
88
+
89
+ - Replaced `Harness.switchModel()` with `harness.session.model.switch()`. Model switching now lives on the session, alongside the active mode/model state it already owns. ([#18197](https://github.com/mastra-ai/mastra/pull/18197))
90
+
91
+ **Before**
92
+
93
+ ```typescript
94
+ await harness.switchModel({ modelId: 'openai/gpt-5' });
95
+ ```
96
+
97
+ **After**
98
+
99
+ ```typescript
100
+ await harness.session.model.switch({ modelId: 'openai/gpt-5' });
101
+ ```
102
+
103
+ - Replaced `Harness.switchMode()` with `harness.session.mode.switch()`. Switching modes now lives on the session, alongside the active mode/model state it already owns. ([#18197](https://github.com/mastra-ai/mastra/pull/18197))
104
+
105
+ **Before**
106
+
107
+ ```typescript
108
+ await harness.switchMode({ modeId: 'build' });
109
+ ```
110
+
111
+ **After**
112
+
113
+ ```typescript
114
+ await harness.session.mode.switch({ modeId: 'build' });
115
+ ```
116
+
117
+ `mastracode` is updated to consume the new API: the TUI and headless callers now invoke `harness.session.mode.switch()` instead of the removed `harness.switchMode()`.
118
+
119
+ - Made the Harness a pure factory + shared-resource owner and removed its singleton session. The Harness no longer holds a `#session` field or exposes a `harness.session` getter; instead, callers create fully isolated sessions via `harness.createSession()`. Each session owns its own mode, model, state, thread, run-control, event bus, and stream engine, so a single Harness can now serve many concurrent sessions (e.g. one per user/thread in a server or channel adapter) without cross-session state or event leakage. ([#18213](https://github.com/mastra-ai/mastra/pull/18213))
120
+
121
+ `harness.createSession({ resourceId? })` constructs and wires a new `Session`, replays the current workspace status onto it, and selects or creates its thread before returning. Harness methods that previously read the singleton session are now parameterized by an explicit `session` argument (`setResourceId`, `getKnownResourceIds`, `getCurrentModelAuthStatus`, `loadOMProgress`, `getObservationalMemoryRecord`, `destroy`). `harness.init()` is now idempotent, so repeated calls reuse the same initialization instead of rebuilding internal state.
122
+
123
+ **Before**
124
+
125
+ ```typescript
126
+ const harness = new Harness(config);
127
+ await harness.init();
128
+ const session = harness.session; // singleton
129
+ await session.sendMessage({ content: 'hello' });
130
+ ```
131
+
132
+ **After**
133
+
134
+ ```typescript
135
+ const harness = new Harness(config);
136
+ await harness.init();
137
+ const session = await harness.createSession({ resourceId });
138
+ await session.sendMessage({ content: 'hello' });
139
+
140
+ // A second, fully isolated session from the same Harness:
141
+ const other = await harness.createSession({ resourceId: otherUser });
142
+ ```
143
+
144
+ Removed `harness.session`, `harness.getSession()`, the singleton `#session` field, and the deprecated `harness.subscribe`/`harness.emit`/`harness.memory` delegators.
145
+
146
+ `mastracode` is updated to consume the new API: composition roots call `createSession()` once at startup and store the result on `state.session`, and all per-session operations flow through that session object.
147
+
148
+ - Migrate TUI thread operations to the session-scoped `session.thread.*` APIs following the core thread lifecycle migration. ([#18213](https://github.com/mastra-ai/mastra/pull/18213))
149
+
150
+ - Resolve notification stream options from the target resource's session (falling back to the active session's model, then the mode default) so a woken GitHub-signal notification always has a model to run with. ([#18213](https://github.com/mastra-ai/mastra/pull/18213))
151
+
152
+ - Moved the tool-permission rule accessors off the Harness onto `session.permissions`. Reading and writing the persisted per-category / per-tool approval policies now lives on the session, next to the state it reads and writes. ([#18200](https://github.com/mastra-ai/mastra/pull/18200))
153
+
154
+ **Before**
155
+
156
+ ```typescript
157
+ const rules = harness.getPermissionRules();
158
+ harness.setPermissionForCategory({ category: 'execute', policy: 'ask' });
159
+ harness.setPermissionForTool({ toolName: 'dangerous_tool', policy: 'deny' });
160
+ ```
161
+
162
+ **After**
163
+
164
+ ```typescript
165
+ const rules = harness.session.permissions.getRules();
166
+ await harness.session.permissions.setForCategory({ category: 'execute', policy: 'ask' });
167
+ await harness.session.permissions.setForTool({ toolName: 'dangerous_tool', policy: 'deny' });
168
+ ```
169
+
170
+ Removed `Harness.getPermissionRules`, `Harness.setPermissionForCategory`, and `Harness.setPermissionForTool`. The setters now return a promise that resolves once the change is persisted to session state, so callers that read the rules back can await the write. Tool-category resolution stays on the harness as `harness.getToolCategory()` since it reads harness config rather than session state.
171
+
172
+ `mastracode` is updated to consume the new API: the `/permissions` command reads and sets policies via `session.permissions`.
173
+
174
+ - Replaced `Harness.getModelName()` and `Harness.getFullModelId()` with session accessors. The full model id is read via the existing `harness.session.model.get()`, and the short display name moves to a new `harness.session.model.displayName()`. ([#18200](https://github.com/mastra-ai/mastra/pull/18200))
175
+
176
+ **Before**
177
+
178
+ ```typescript
179
+ const name = harness.getModelName();
180
+ const fullId = harness.getFullModelId();
181
+ ```
182
+
183
+ **After**
184
+
185
+ ```typescript
186
+ const name = harness.session.model.displayName();
187
+ const fullId = harness.session.model.get();
188
+ ```
189
+
190
+ `mastracode` is updated to consume the new API: the TUI status line and message renderer now read the model id via `harness.session.model.get()`.
191
+
192
+ - Moved the subagent model accessors off the Harness onto `session.subagents.model`. Reading and setting the global or per-`agentType` subagent model now lives on the session, next to the state it reads and writes, and is grouped under `session.subagents` to leave room for future subagent settings. ([#18200](https://github.com/mastra-ai/mastra/pull/18200))
193
+
194
+ **Before**
195
+
196
+ ```typescript
197
+ const modelId = harness.getSubagentModelId({ agentType: 'explore' });
198
+ await harness.setSubagentModelId({ modelId: 'anthropic/claude-sonnet-4', agentType: 'explore' });
199
+ ```
200
+
201
+ **After**
202
+
203
+ ```typescript
204
+ const modelId = harness.session.subagents.model.get({ agentType: 'explore' });
205
+ await harness.session.subagents.model.set({ modelId: 'anthropic/claude-sonnet-4', agentType: 'explore' });
206
+ ```
207
+
208
+ `get()` prefers the per-`agentType` value, then the global subagent model, returning `null` when neither is set. `set()` persists to thread settings and emits a `subagent_model_changed` event. Removed `Harness.getSubagentModelId` and `Harness.setSubagentModelId`.
209
+
210
+ `mastracode` is updated to consume the new API: the `/subagents` command, model-pack activation, and startup model restoration read and set subagent models via `session.subagents.model`.
211
+
212
+ - Updated dependencies [[`5bd72d2`](https://github.com/mastra-ai/mastra/commit/5bd72d255f45b5ea8ab342643bd463814a980a24), [`1cc9ee1`](https://github.com/mastra-ai/mastra/commit/1cc9ee1ba51db53020a735626d33017a60b4b5b3), [`417baae`](https://github.com/mastra-ai/mastra/commit/417baae40b995db5819c845036947f0c27dc1c00), [`74955f9`](https://github.com/mastra-ai/mastra/commit/74955f9120cde8b1d8ce4399232b4033236be858), [`30ebaf0`](https://github.com/mastra-ai/mastra/commit/30ebaf07bed5f4d30f2f257836c15d1bf7e40aae), [`5704634`](https://github.com/mastra-ai/mastra/commit/5704634b22133167dea337a942a34f57aaa3fa14), [`417baae`](https://github.com/mastra-ai/mastra/commit/417baae40b995db5819c845036947f0c27dc1c00), [`74955f9`](https://github.com/mastra-ai/mastra/commit/74955f9120cde8b1d8ce4399232b4033236be858), [`74955f9`](https://github.com/mastra-ai/mastra/commit/74955f9120cde8b1d8ce4399232b4033236be858), [`c0eda2b`](https://github.com/mastra-ai/mastra/commit/c0eda2bcd91a228427314b12c91d8b147f3a739f), [`c0eda2b`](https://github.com/mastra-ai/mastra/commit/c0eda2bcd91a228427314b12c91d8b147f3a739f), [`b13925b`](https://github.com/mastra-ai/mastra/commit/b13925bfa91aa8700f56fa54a9ce707ee7e4ba62), [`bf94ec6`](https://github.com/mastra-ai/mastra/commit/bf94ec68192d9f16e46ef7e5ac36370aeeddf35d), [`a29f371`](https://github.com/mastra-ai/mastra/commit/a29f371aef629ac8562661524a497127e93b5131), [`6075e17`](https://github.com/mastra-ai/mastra/commit/6075e173c4f11b889df5a592e0a708d6307220eb), [`74955f9`](https://github.com/mastra-ai/mastra/commit/74955f9120cde8b1d8ce4399232b4033236be858), [`073f910`](https://github.com/mastra-ai/mastra/commit/073f910481e7d94b95ba3830f96531774ae95d33), [`ebbe1d3`](https://github.com/mastra-ai/mastra/commit/ebbe1d31a965a3adb0e728758f326b8122b4b55f), [`1f97ce5`](https://github.com/mastra-ai/mastra/commit/1f97ce5695463bebb4eaacf501da6fb403e20885), [`74955f9`](https://github.com/mastra-ai/mastra/commit/74955f9120cde8b1d8ce4399232b4033236be858), [`64f58c0`](https://github.com/mastra-ai/mastra/commit/64f58c04e78b40137497d47f781e897e416f22a5), [`74955f9`](https://github.com/mastra-ai/mastra/commit/74955f9120cde8b1d8ce4399232b4033236be858), [`ebbe1d3`](https://github.com/mastra-ai/mastra/commit/ebbe1d31a965a3adb0e728758f326b8122b4b55f), [`417baae`](https://github.com/mastra-ai/mastra/commit/417baae40b995db5819c845036947f0c27dc1c00), [`b89fbd1`](https://github.com/mastra-ai/mastra/commit/b89fbd15bfdceeee469651c81133f70cc22a6fb9), [`8e25a78`](https://github.com/mastra-ai/mastra/commit/8e25a78e0597575f0b0729bae8c5e190c84869b5), [`417baae`](https://github.com/mastra-ai/mastra/commit/417baae40b995db5819c845036947f0c27dc1c00), [`a5b22d3`](https://github.com/mastra-ai/mastra/commit/a5b22d314d62a68d801886a8d3d0eb6c089473db), [`417baae`](https://github.com/mastra-ai/mastra/commit/417baae40b995db5819c845036947f0c27dc1c00), [`74955f9`](https://github.com/mastra-ai/mastra/commit/74955f9120cde8b1d8ce4399232b4033236be858), [`74955f9`](https://github.com/mastra-ai/mastra/commit/74955f9120cde8b1d8ce4399232b4033236be858)]:
213
+ - @mastra/core@1.46.0-alpha.0
214
+ - @mastra/github-signals@0.2.1-alpha.0
215
+ - @mastra/memory@1.21.1-alpha.0
216
+ - @mastra/mcp@1.12.0-alpha.0
217
+
218
+ ## 0.24.0
219
+
220
+ ### Minor Changes
221
+
222
+ - Random bump ([#18178](https://github.com/mastra-ai/mastra/pull/18178))
223
+
224
+ ### Patch Changes
225
+
226
+ - 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))
227
+
228
+ - 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))
229
+
230
+ - 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)]:
231
+ - @mastra/core@1.45.0
232
+ - @mastra/agent-browser@0.4.0
233
+ - @mastra/stagehand@0.3.0
234
+ - @mastra/tavily@1.1.0
235
+ - @mastra/observability@1.15.0
236
+ - @mastra/fastembed@1.2.0
237
+ - @mastra/mcp@1.11.0
238
+ - @mastra/memory@1.21.0
239
+ - @mastra/schema-compat@1.3.0
240
+ - @mastra/github-signals@0.2.0
241
+ - @mastra/duckdb@1.5.0
242
+ - @mastra/libsql@1.14.0
243
+ - @mastra/pg@1.14.0
244
+
3
245
  ## 0.24.0-alpha.0
4
246
 
5
247
  ### Minor Changes
@@ -1,4 +1,4 @@
1
- import type { Harness } from '@mastra/core/harness';
1
+ import type { Session } from '@mastra/core/harness';
2
2
  /**
3
3
  * Wires MastraCode-owned OM settings into harness thread events so they persist
4
4
  * per-thread and new threads inherit the most recent value.
@@ -7,11 +7,11 @@ import type { Harness } from '@mastra/core/harness';
7
7
  * settings are mastracode-specific OM concepts, so persistence stays scoped to
8
8
  * the host.
9
9
  */
10
- export declare function attachOMThreadStatePersistence(harness: Harness<Record<string, unknown>>): void;
10
+ export declare function attachOMThreadStatePersistence(session: Session<Record<string, unknown>>): void;
11
11
  /**
12
12
  * Eagerly restores MastraCode-owned OM settings for the currently-selected
13
13
  * thread. Called once at TUI startup after the initial thread is selected,
14
14
  * since the subscription set up later misses the startup `thread_changed` event.
15
15
  */
16
- export declare function restoreOMThreadStateForCurrentThread(harness: Harness<Record<string, unknown>>): Promise<void>;
16
+ export declare function restoreOMThreadStateForCurrentThread(session: Session<Record<string, unknown>>): Promise<void>;
17
17
  //# sourceMappingURL=thread-caveman-state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"thread-caveman-state.d.ts","sourceRoot":"","sources":["../../src/agents/thread-caveman-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAiB,MAAM,sBAAsB,CAAC;AAqEnE;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI,CAS9F;AAED;;;;GAIG;AACH,wBAAsB,oCAAoC,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAInH"}
1
+ {"version":3,"file":"thread-caveman-state.d.ts","sourceRoot":"","sources":["../../src/agents/thread-caveman-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAuEnE;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI,CAS9F;AAED;;;;GAIG;AACH,wBAAsB,oCAAoC,CAAC,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAInH"}