@mastra/code-sdk 1.0.3-alpha.0 → 1.1.0-alpha.2

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 (258) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/dist/acp/agent.js +155 -167
  3. package/dist/acp/agent.js.map +1 -1
  4. package/dist/acp/event-mapper.js +193 -168
  5. package/dist/acp/event-mapper.js.map +1 -1
  6. package/dist/acp/index.js +60 -49
  7. package/dist/acp/index.js.map +1 -1
  8. package/dist/acp/server.js +31 -30
  9. package/dist/acp/server.js.map +1 -1
  10. package/dist/acp.js +1 -4
  11. package/dist/agents/credential-resolver.js +40 -29
  12. package/dist/agents/credential-resolver.js.map +1 -1
  13. package/dist/agents/custom-provider-source.js +16 -9
  14. package/dist/agents/custom-provider-source.js.map +1 -1
  15. package/dist/agents/instructions.js +27 -36
  16. package/dist/agents/instructions.js.map +1 -1
  17. package/dist/agents/mastracode-gateway.js +355 -428
  18. package/dist/agents/mastracode-gateway.js.map +1 -1
  19. package/dist/agents/memory.js +87 -78
  20. package/dist/agents/memory.js.map +1 -1
  21. package/dist/agents/model.js +114 -119
  22. package/dist/agents/model.js.map +1 -1
  23. package/dist/agents/modes/build.js +12 -13
  24. package/dist/agents/modes/build.js.map +1 -1
  25. package/dist/agents/modes/explore.js +14 -13
  26. package/dist/agents/modes/explore.js.map +1 -1
  27. package/dist/agents/modes/plan.js +14 -15
  28. package/dist/agents/modes/plan.js.map +1 -1
  29. package/dist/agents/prompts/agent-instructions.js +78 -69
  30. package/dist/agents/prompts/agent-instructions.js.map +1 -1
  31. package/dist/agents/prompts/build.js +19 -16
  32. package/dist/agents/prompts/build.js.map +1 -1
  33. package/dist/agents/prompts/fast.js +8 -4
  34. package/dist/agents/prompts/fast.js.map +1 -1
  35. package/dist/agents/prompts/index.js +48 -47
  36. package/dist/agents/prompts/index.js.map +1 -1
  37. package/dist/agents/prompts/model.js +6 -5
  38. package/dist/agents/prompts/model.js.map +1 -1
  39. package/dist/agents/prompts/plan.js +20 -16
  40. package/dist/agents/prompts/plan.js.map +1 -1
  41. package/dist/agents/prompts/tool-guidance.js +77 -109
  42. package/dist/agents/prompts/tool-guidance.js.map +1 -1
  43. package/dist/agents/sandbox-filesystem.js +245 -259
  44. package/dist/agents/sandbox-filesystem.js.map +1 -1
  45. package/dist/agents/sandbox-reattach.js +9 -11
  46. package/dist/agents/sandbox-reattach.js.map +1 -1
  47. package/dist/agents/thread-caveman-state.js +92 -81
  48. package/dist/agents/thread-caveman-state.js.map +1 -1
  49. package/dist/agents/tool-availability.js +62 -80
  50. package/dist/agents/tool-availability.js.map +1 -1
  51. package/dist/agents/tools.js +99 -139
  52. package/dist/agents/tools.js.map +1 -1
  53. package/dist/agents/workspace.js +232 -225
  54. package/dist/agents/workspace.js.map +1 -1
  55. package/dist/analytics.js +139 -128
  56. package/dist/analytics.js.map +1 -1
  57. package/dist/auth/authorization-input.js +39 -25
  58. package/dist/auth/authorization-input.js.map +1 -1
  59. package/dist/auth/device-code.js +112 -80
  60. package/dist/auth/device-code.js.map +1 -1
  61. package/dist/auth/index.js +2 -9
  62. package/dist/auth/pkce.js +27 -16
  63. package/dist/auth/pkce.js.map +1 -1
  64. package/dist/auth/providers/anthropic.js +107 -93
  65. package/dist/auth/providers/anthropic.js.map +1 -1
  66. package/dist/auth/providers/github-copilot.js +304 -293
  67. package/dist/auth/providers/github-copilot.js.map +1 -1
  68. package/dist/auth/providers/openai-codex.js +442 -460
  69. package/dist/auth/providers/openai-codex.js.map +1 -1
  70. package/dist/auth/providers/xai.js +179 -145
  71. package/dist/auth/providers/xai.js.map +1 -1
  72. package/dist/auth/storage.js +182 -175
  73. package/dist/auth/storage.js.map +1 -1
  74. package/dist/auth/types.js +1 -1
  75. package/dist/clipboard/index.js +206 -172
  76. package/dist/clipboard/index.js.map +1 -1
  77. package/dist/constants.js +11 -16
  78. package/dist/constants.js.map +1 -1
  79. package/dist/error-classification.js +19 -11
  80. package/dist/error-classification.js.map +1 -1
  81. package/dist/evals/context-builder.js +145 -104
  82. package/dist/evals/context-builder.js.map +1 -1
  83. package/dist/evals/index.js +4 -7
  84. package/dist/evals/scorers/classify-command.js +62 -41
  85. package/dist/evals/scorers/classify-command.js.map +1 -1
  86. package/dist/evals/scorers/efficiency.js +239 -181
  87. package/dist/evals/scorers/efficiency.js.map +1 -1
  88. package/dist/evals/scorers/extract-tools.js +51 -47
  89. package/dist/evals/scorers/extract-tools.js.map +1 -1
  90. package/dist/evals/scorers/index.js +1 -5
  91. package/dist/evals/scorers/outcome.js +321 -212
  92. package/dist/evals/scorers/outcome.js.map +1 -1
  93. package/dist/goal-manager.js +266 -261
  94. package/dist/goal-manager.js.map +1 -1
  95. package/dist/goal-signal.js +14 -13
  96. package/dist/goal-signal.js.map +1 -1
  97. package/dist/headless/cli.js +153 -154
  98. package/dist/headless/cli.js.map +1 -1
  99. package/dist/headless/flags.js +180 -178
  100. package/dist/headless/flags.js.map +1 -1
  101. package/dist/headless/format.js +72 -71
  102. package/dist/headless/format.js.map +1 -1
  103. package/dist/headless/index.js +5 -31
  104. package/dist/headless/policy.js +35 -31
  105. package/dist/headless/policy.js.map +1 -1
  106. package/dist/headless/run-mc.js +332 -334
  107. package/dist/headless/run-mc.js.map +1 -1
  108. package/dist/headless/types.js +16 -7
  109. package/dist/headless/types.js.map +1 -1
  110. package/dist/hooks/config.js +56 -61
  111. package/dist/hooks/config.js.map +1 -1
  112. package/dist/hooks/executor.js +118 -116
  113. package/dist/hooks/executor.js.map +1 -1
  114. package/dist/hooks/index.js +4 -15
  115. package/dist/hooks/manager.js +221 -280
  116. package/dist/hooks/manager.js.map +1 -1
  117. package/dist/hooks/types.js +5 -4
  118. package/dist/hooks/types.js.map +1 -1
  119. package/dist/index.d.ts.map +1 -1
  120. package/dist/index.js +632 -712
  121. package/dist/index.js.map +1 -1
  122. package/dist/ipc/ipc-reporter.js +19 -22
  123. package/dist/ipc/ipc-reporter.js.map +1 -1
  124. package/dist/lsp/client.js +248 -306
  125. package/dist/lsp/client.js.map +1 -1
  126. package/dist/lsp/index.js +1 -6
  127. package/dist/lsp/language.js +39 -43
  128. package/dist/lsp/language.js.map +1 -1
  129. package/dist/lsp/manager.js +78 -93
  130. package/dist/lsp/manager.js.map +1 -1
  131. package/dist/lsp/server.js +151 -120
  132. package/dist/lsp/server.js.map +1 -1
  133. package/dist/lsp/workspace.js +50 -47
  134. package/dist/lsp/workspace.js.map +1 -1
  135. package/dist/mcp/config.js +210 -199
  136. package/dist/mcp/config.js.map +1 -1
  137. package/dist/mcp/index.js +2 -9
  138. package/dist/mcp/manager.js +482 -475
  139. package/dist/mcp/manager.js.map +1 -1
  140. package/dist/mcp/types.js +1 -1
  141. package/dist/onboarding/custom-packs.js +14 -17
  142. package/dist/onboarding/custom-packs.js.map +1 -1
  143. package/dist/onboarding/custom-providers.js +22 -20
  144. package/dist/onboarding/custom-providers.js.map +1 -1
  145. package/dist/onboarding/index.d.ts +1 -1
  146. package/dist/onboarding/index.d.ts.map +1 -1
  147. package/dist/onboarding/index.js +3 -21
  148. package/dist/onboarding/om-settings.d.ts +5 -0
  149. package/dist/onboarding/om-settings.d.ts.map +1 -1
  150. package/dist/onboarding/om-settings.js +41 -20
  151. package/dist/onboarding/om-settings.js.map +1 -1
  152. package/dist/onboarding/packs.d.ts +4 -6
  153. package/dist/onboarding/packs.d.ts.map +1 -1
  154. package/dist/onboarding/packs.js +154 -105
  155. package/dist/onboarding/packs.js.map +1 -1
  156. package/dist/onboarding/settings.js +575 -517
  157. package/dist/onboarding/settings.js.map +1 -1
  158. package/dist/permissions.js +112 -99
  159. package/dist/permissions.js.map +1 -1
  160. package/dist/plugin.js +21 -23
  161. package/dist/plugin.js.map +1 -1
  162. package/dist/plugins/dependencies.js +64 -87
  163. package/dist/plugins/dependencies.js.map +1 -1
  164. package/dist/plugins/install.js +159 -169
  165. package/dist/plugins/install.js.map +1 -1
  166. package/dist/plugins/loader.js +170 -185
  167. package/dist/plugins/loader.js.map +1 -1
  168. package/dist/plugins/manager.js +374 -380
  169. package/dist/plugins/manager.js.map +1 -1
  170. package/dist/plugins/manifest.js +38 -63
  171. package/dist/plugins/manifest.js.map +1 -1
  172. package/dist/plugins/package-link.js +48 -64
  173. package/dist/plugins/package-link.js.map +1 -1
  174. package/dist/plugins/paths.js +18 -19
  175. package/dist/plugins/paths.js.map +1 -1
  176. package/dist/plugins/registry.js +97 -81
  177. package/dist/plugins/registry.js.map +1 -1
  178. package/dist/plugins/scaffold.js +62 -98
  179. package/dist/plugins/scaffold.js.map +1 -1
  180. package/dist/plugins/types.js +1 -1
  181. package/dist/processors/plan-rejection-abort.js +45 -44
  182. package/dist/processors/plan-rejection-abort.js.map +1 -1
  183. package/dist/providers/amazon-bedrock-gateway.js +134 -125
  184. package/dist/providers/amazon-bedrock-gateway.js.map +1 -1
  185. package/dist/providers/amazon-bedrock.js +68 -47
  186. package/dist/providers/amazon-bedrock.js.map +1 -1
  187. package/dist/providers/claude-max.js +153 -133
  188. package/dist/providers/claude-max.js.map +1 -1
  189. package/dist/providers/github-copilot.js +232 -230
  190. package/dist/providers/github-copilot.js.map +1 -1
  191. package/dist/providers/openai-codex.js +271 -260
  192. package/dist/providers/openai-codex.js.map +1 -1
  193. package/dist/providers/xai.js +57 -50
  194. package/dist/providers/xai.js.map +1 -1
  195. package/dist/schema.js +91 -89
  196. package/dist/schema.js.map +1 -1
  197. package/dist/theme-palette.js +18 -14
  198. package/dist/theme-palette.js.map +1 -1
  199. package/dist/tool-names.js +46 -37
  200. package/dist/tool-names.js.map +1 -1
  201. package/dist/tools/index.js +2 -8
  202. package/dist/tools/request-sandbox-access.js +71 -80
  203. package/dist/tools/request-sandbox-access.js.map +1 -1
  204. package/dist/tools/utils.js +26 -16
  205. package/dist/tools/utils.js.map +1 -1
  206. package/dist/tools/web-search.js +51 -55
  207. package/dist/tools/web-search.js.map +1 -1
  208. package/dist/utils/binaries.js +65 -61
  209. package/dist/utils/binaries.js.map +1 -1
  210. package/dist/utils/debug-log.js +51 -47
  211. package/dist/utils/debug-log.js.map +1 -1
  212. package/dist/utils/errors.js +157 -192
  213. package/dist/utils/errors.js.map +1 -1
  214. package/dist/utils/gateway-sync.js +49 -37
  215. package/dist/utils/gateway-sync.js.map +1 -1
  216. package/dist/utils/path-security.js +7 -6
  217. package/dist/utils/path-security.js.map +1 -1
  218. package/dist/utils/plan-diff.js +58 -39
  219. package/dist/utils/plan-diff.js.map +1 -1
  220. package/dist/utils/plans.js +92 -74
  221. package/dist/utils/plans.js.map +1 -1
  222. package/dist/utils/project.js +318 -256
  223. package/dist/utils/project.js.map +1 -1
  224. package/dist/utils/signals-pubsub.js +117 -99
  225. package/dist/utils/signals-pubsub.js.map +1 -1
  226. package/dist/utils/slash-command-loader.js +118 -154
  227. package/dist/utils/slash-command-loader.js.map +1 -1
  228. package/dist/utils/slash-command-processor.js +92 -83
  229. package/dist/utils/slash-command-processor.js.map +1 -1
  230. package/dist/utils/stdin-pipe.js +87 -63
  231. package/dist/utils/stdin-pipe.js.map +1 -1
  232. package/dist/utils/storage-factory.js +104 -84
  233. package/dist/utils/storage-factory.js.map +1 -1
  234. package/dist/utils/storage-maintenance.js +249 -211
  235. package/dist/utils/storage-maintenance.js.map +1 -1
  236. package/dist/utils/thread-lock.js +96 -92
  237. package/dist/utils/thread-lock.js.map +1 -1
  238. package/dist/utils/token-estimator.js +12 -12
  239. package/dist/utils/token-estimator.js.map +1 -1
  240. package/dist/utils/update-check.d.ts +1 -1
  241. package/dist/utils/update-check.js +341 -259
  242. package/dist/utils/update-check.js.map +1 -1
  243. package/dist/voice/stt-registry.js +131 -113
  244. package/dist/voice/stt-registry.js.map +1 -1
  245. package/package.json +11 -11
  246. package/dist/acp.js.map +0 -1
  247. package/dist/auth/index.js.map +0 -1
  248. package/dist/auth/types.js.map +0 -1
  249. package/dist/evals/index.js.map +0 -1
  250. package/dist/evals/scorers/index.js.map +0 -1
  251. package/dist/headless/index.js.map +0 -1
  252. package/dist/hooks/index.js.map +0 -1
  253. package/dist/lsp/index.js.map +0 -1
  254. package/dist/mcp/index.js.map +0 -1
  255. package/dist/mcp/types.js.map +0 -1
  256. package/dist/onboarding/index.js.map +0 -1
  257. package/dist/plugins/types.js.map +0 -1
  258. package/dist/tools/index.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,54 @@
1
1
  # @mastra/code-sdk
2
2
 
3
+ ## 1.1.0-alpha.2
4
+
5
+ ### Minor Changes
6
+
7
+ - Added `resolveProviderOMDefault` to `@mastra/code-sdk/onboarding/packs`, which returns the small, cheap observational memory model for a provider, or the model you pass in when that provider has none. ([#20298](https://github.com/mastra-ai/mastra/pull/20298))
8
+
9
+ The built-in OM packs are now a single table, so the list offered during onboarding and the per-provider default can no longer drift apart.
10
+
11
+ ```ts
12
+ import { resolveProviderOMDefault } from '@mastra/code-sdk/onboarding/packs';
13
+
14
+ resolveProviderOMDefault('anthropic').modelId; // 'anthropic/claude-haiku-4-5'
15
+ resolveProviderOMDefault('openai-codex').modelId; // 'openai/gpt-5.4-mini'
16
+ resolveProviderOMDefault('xai', 'xai/grok-4.5').modelId; // 'xai/grok-4.5'
17
+ ```
18
+
19
+ - Added provider-aware observational memory defaults, so a controller started without a stored OM choice observes and reflects with the cheap model of a provider you can actually reach instead of the built-in Gemini default. ([#20291](https://github.com/mastra-ai/mastra/pull/20291))
20
+
21
+ The helpers behind it are exported if you build your own surface on the SDK:
22
+
23
+ ```ts
24
+ import { hasExplicitOMConfiguration } from '@mastra/code-sdk/onboarding/om-settings';
25
+ import { selectPreferredOMPack } from '@mastra/code-sdk/onboarding/packs';
26
+
27
+ // Best OM pack across everything the user can reach, preferring a given provider
28
+ selectPreferredOMPack({ anthropic: 'oauth', google: 'apikey' }, 'anthropic')?.modelId;
29
+
30
+ // True once the user picked an OM model or pack themselves — never seed over it
31
+ hasExplicitOMConfiguration(settings);
32
+ ```
33
+
34
+ ### Patch Changes
35
+
36
+ - Updated dependencies [[`a211d09`](https://github.com/mastra-ai/mastra/commit/a211d09185dc65a746534914cf38b67f21ee9bac), [`05db566`](https://github.com/mastra-ai/mastra/commit/05db566fcbdcbf33d0bffca0c72ec30129e2e3ca), [`05db566`](https://github.com/mastra-ai/mastra/commit/05db566fcbdcbf33d0bffca0c72ec30129e2e3ca), [`e075db9`](https://github.com/mastra-ai/mastra/commit/e075db9715c836bae5dfc37c50248492af397c3b), [`8124754`](https://github.com/mastra-ai/mastra/commit/8124754ae89fbc69f8136d1df4a91904d0f84c4e)]:
37
+ - @mastra/core@1.54.0-alpha.2
38
+ - @mastra/pg@1.18.0-alpha.2
39
+ - @mastra/libsql@1.18.0-alpha.1
40
+
41
+ ## 1.0.3-alpha.1
42
+
43
+ ### Patch Changes
44
+
45
+ - Updated dependencies [[`ce93a3c`](https://github.com/mastra-ai/mastra/commit/ce93a3c114ea1cbfbd576f3db41d7c26c9844f5b), [`5718a22`](https://github.com/mastra-ai/mastra/commit/5718a229281dcfd36bcd1f42a242e3717e510a33), [`5807d3a`](https://github.com/mastra-ai/mastra/commit/5807d3ae1d259b8b7d6df7e5bf2b485c694af9c8), [`57661af`](https://github.com/mastra-ai/mastra/commit/57661afeca52ff9af4e72675ede2134fa503d5a5), [`57661af`](https://github.com/mastra-ai/mastra/commit/57661afeca52ff9af4e72675ede2134fa503d5a5), [`273bb71`](https://github.com/mastra-ai/mastra/commit/273bb71e82e74b656f3906288239429899398c0c), [`57661af`](https://github.com/mastra-ai/mastra/commit/57661afeca52ff9af4e72675ede2134fa503d5a5), [`57661af`](https://github.com/mastra-ai/mastra/commit/57661afeca52ff9af4e72675ede2134fa503d5a5), [`5718a22`](https://github.com/mastra-ai/mastra/commit/5718a229281dcfd36bcd1f42a242e3717e510a33), [`57661af`](https://github.com/mastra-ai/mastra/commit/57661afeca52ff9af4e72675ede2134fa503d5a5), [`d1b7e3a`](https://github.com/mastra-ai/mastra/commit/d1b7e3a978a309a5653eeaa490d2d6c7c53bd093), [`c093146`](https://github.com/mastra-ai/mastra/commit/c0931466404d3c521308ea119cb165bb7e695155), [`d1b7e3a`](https://github.com/mastra-ai/mastra/commit/d1b7e3a978a309a5653eeaa490d2d6c7c53bd093)]:
46
+ - @mastra/core@1.54.0-alpha.1
47
+ - @mastra/pg@1.18.0-alpha.1
48
+ - @mastra/duckdb@1.5.2-alpha.0
49
+ - @mastra/observability@1.16.3-alpha.0
50
+ - @mastra/mcp@1.15.0
51
+
3
52
  ## 1.0.3-alpha.0
4
53
 
5
54
  ### Patch Changes
package/dist/acp/agent.js CHANGED
@@ -1,173 +1,161 @@
1
- import { PROTOCOL_VERSION } from "@agentclientprotocol/sdk";
2
1
  import { handleAgentControllerEvent } from "./event-mapper.js";
3
- class MastraCodeAcpAgent {
4
- connection;
5
- controller;
6
- session;
7
- modes;
8
- unsubscribeSessionEvents;
9
- sessionMap = /* @__PURE__ */ new Map();
10
- // sessionId -> threadId
11
- currentPromptState = null;
12
- promptMutex = Promise.resolve();
13
- getThreadIdOrThrow(sessionId) {
14
- const threadId = this.sessionMap.get(sessionId);
15
- if (!threadId) {
16
- throw new Error(`Unknown ACP sessionId: ${sessionId}`);
17
- }
18
- return threadId;
19
- }
20
- constructor(connection, controller, session, modes) {
21
- this.connection = connection;
22
- this.controller = controller;
23
- this.session = session;
24
- this.modes = modes;
25
- this.unsubscribeSessionEvents = this.session.subscribe((event) => {
26
- handleAgentControllerEvent(event, this.currentPromptState, this.connection, this.session);
27
- });
28
- }
29
- dispose() {
30
- this.unsubscribeSessionEvents();
31
- }
32
- async initialize(_request) {
33
- return {
34
- protocolVersion: PROTOCOL_VERSION,
35
- agentInfo: {
36
- name: "mastracode",
37
- title: "Mastra Code",
38
- version: "0.1.0"
39
- },
40
- agentCapabilities: {
41
- loadSession: false
42
- }
43
- };
44
- }
45
- async authenticate() {
46
- }
47
- async newSession(_request) {
48
- const thread = await this.session.thread.create();
49
- const sessionId = thread.id;
50
- this.sessionMap.set(sessionId, thread.id);
51
- await this.session.thread.switch({ threadId: thread.id });
52
- const availableModes = this.modes.map((m) => ({
53
- id: m.id,
54
- name: m.name ?? m.id
55
- }));
56
- const currentModeId = this.session.mode.get();
57
- let models;
58
- try {
59
- const availableModels = await this.controller.listAvailableModels();
60
- const currentModelId = this.session.model.get();
61
- models = {
62
- currentModelId: currentModelId ?? "",
63
- availableModels: availableModels.map((m) => ({
64
- modelId: m.id,
65
- name: m.modelName
66
- }))
67
- };
68
- } catch {
69
- }
70
- return {
71
- sessionId,
72
- modes: {
73
- currentModeId,
74
- availableModes
75
- },
76
- models
77
- };
78
- }
79
- async prompt(request) {
80
- const { sessionId, prompt: contentBlocks } = request;
81
- const text = extractTextFromContentBlocks(contentBlocks);
82
- const threadId = this.getThreadIdOrThrow(sessionId);
83
- const prevMutex = this.promptMutex;
84
- let resolveMutex;
85
- this.promptMutex = new Promise((resolve) => {
86
- resolveMutex = resolve;
87
- });
88
- await prevMutex;
89
- try {
90
- await this.session.thread.switch({ threadId });
91
- const result = new Promise((resolve) => {
92
- const usage2 = {
93
- promptTokens: 0,
94
- completionTokens: 0,
95
- totalTokens: 0
96
- };
97
- this.currentPromptState = {
98
- sessionId,
99
- lastTextLength: 0,
100
- usage: usage2,
101
- resolve: (reason2) => {
102
- resolve({ reason: reason2, usage: usage2 });
103
- this.currentPromptState = null;
104
- }
105
- };
106
- });
107
- try {
108
- await this.session.sendMessage({ content: text });
109
- } catch (error) {
110
- this.currentPromptState = null;
111
- throw error;
112
- }
113
- const { reason, usage } = await result;
114
- return {
115
- stopReason: mapStopReason(reason),
116
- usage: {
117
- inputTokens: usage.promptTokens,
118
- outputTokens: usage.completionTokens,
119
- totalTokens: usage.totalTokens,
120
- thoughtTokens: usage.reasoningTokens,
121
- cachedReadTokens: usage.cachedInputTokens,
122
- cachedWriteTokens: usage.cacheCreationInputTokens
123
- }
124
- };
125
- } finally {
126
- resolveMutex();
127
- }
128
- }
129
- async cancel(_notification) {
130
- this.session.abort();
131
- }
132
- async setSessionMode(params) {
133
- const threadId = this.getThreadIdOrThrow(params.sessionId);
134
- await this.session.thread.switch({ threadId });
135
- this.session.mode.set({ modeId: params.modeId });
136
- }
137
- async unstable_setSessionModel(params) {
138
- const threadId = this.getThreadIdOrThrow(params.sessionId);
139
- await this.session.thread.switch({ threadId });
140
- this.session.model.set({ modelId: params.modelId });
141
- }
142
- }
2
+ import { PROTOCOL_VERSION } from "@agentclientprotocol/sdk";
3
+ //#region src/acp/agent.ts
4
+ /**
5
+ * ACP Agent implementation that wraps a mastracode Controller.
6
+ * Each instance represents one ACP connection from a client.
7
+ */
8
+ var MastraCodeAcpAgent = class {
9
+ connection;
10
+ controller;
11
+ session;
12
+ modes;
13
+ unsubscribeSessionEvents;
14
+ sessionMap = /* @__PURE__ */ new Map();
15
+ currentPromptState = null;
16
+ promptMutex = Promise.resolve();
17
+ getThreadIdOrThrow(sessionId) {
18
+ const threadId = this.sessionMap.get(sessionId);
19
+ if (!threadId) throw new Error(`Unknown ACP sessionId: ${sessionId}`);
20
+ return threadId;
21
+ }
22
+ constructor(connection, controller, session, modes) {
23
+ this.connection = connection;
24
+ this.controller = controller;
25
+ this.session = session;
26
+ this.modes = modes;
27
+ this.unsubscribeSessionEvents = this.session.subscribe((event) => {
28
+ handleAgentControllerEvent(event, this.currentPromptState, this.connection, this.session);
29
+ });
30
+ }
31
+ dispose() {
32
+ this.unsubscribeSessionEvents();
33
+ }
34
+ async initialize(_request) {
35
+ return {
36
+ protocolVersion: PROTOCOL_VERSION,
37
+ agentInfo: {
38
+ name: "mastracode",
39
+ title: "Mastra Code",
40
+ version: "0.1.0"
41
+ },
42
+ agentCapabilities: { loadSession: false }
43
+ };
44
+ }
45
+ async authenticate() {}
46
+ async newSession(_request) {
47
+ const thread = await this.session.thread.create();
48
+ const sessionId = thread.id;
49
+ this.sessionMap.set(sessionId, thread.id);
50
+ await this.session.thread.switch({ threadId: thread.id });
51
+ const availableModes = this.modes.map((m) => ({
52
+ id: m.id,
53
+ name: m.name ?? m.id
54
+ }));
55
+ const currentModeId = this.session.mode.get();
56
+ let models;
57
+ try {
58
+ const availableModels = await this.controller.listAvailableModels();
59
+ models = {
60
+ currentModelId: this.session.model.get() ?? "",
61
+ availableModels: availableModels.map((m) => ({
62
+ modelId: m.id,
63
+ name: m.modelName
64
+ }))
65
+ };
66
+ } catch {}
67
+ return {
68
+ sessionId,
69
+ modes: {
70
+ currentModeId,
71
+ availableModes
72
+ },
73
+ models
74
+ };
75
+ }
76
+ async prompt(request) {
77
+ const { sessionId, prompt: contentBlocks } = request;
78
+ const text = extractTextFromContentBlocks(contentBlocks);
79
+ const threadId = this.getThreadIdOrThrow(sessionId);
80
+ const prevMutex = this.promptMutex;
81
+ let resolveMutex;
82
+ this.promptMutex = new Promise((resolve) => {
83
+ resolveMutex = resolve;
84
+ });
85
+ await prevMutex;
86
+ try {
87
+ await this.session.thread.switch({ threadId });
88
+ const result = new Promise((resolve) => {
89
+ const usage = {
90
+ promptTokens: 0,
91
+ completionTokens: 0,
92
+ totalTokens: 0
93
+ };
94
+ this.currentPromptState = {
95
+ sessionId,
96
+ lastTextLength: 0,
97
+ usage,
98
+ resolve: (reason) => {
99
+ resolve({
100
+ reason,
101
+ usage
102
+ });
103
+ this.currentPromptState = null;
104
+ }
105
+ };
106
+ });
107
+ try {
108
+ await this.session.sendMessage({ content: text });
109
+ } catch (error) {
110
+ this.currentPromptState = null;
111
+ throw error;
112
+ }
113
+ const { reason, usage } = await result;
114
+ return {
115
+ stopReason: mapStopReason(reason),
116
+ usage: {
117
+ inputTokens: usage.promptTokens,
118
+ outputTokens: usage.completionTokens,
119
+ totalTokens: usage.totalTokens,
120
+ thoughtTokens: usage.reasoningTokens,
121
+ cachedReadTokens: usage.cachedInputTokens,
122
+ cachedWriteTokens: usage.cacheCreationInputTokens
123
+ }
124
+ };
125
+ } finally {
126
+ resolveMutex();
127
+ }
128
+ }
129
+ async cancel(_notification) {
130
+ this.session.abort();
131
+ }
132
+ async setSessionMode(params) {
133
+ const threadId = this.getThreadIdOrThrow(params.sessionId);
134
+ await this.session.thread.switch({ threadId });
135
+ this.session.mode.set({ modeId: params.modeId });
136
+ }
137
+ async unstable_setSessionModel(params) {
138
+ const threadId = this.getThreadIdOrThrow(params.sessionId);
139
+ await this.session.thread.switch({ threadId });
140
+ this.session.model.set({ modelId: params.modelId });
141
+ }
142
+ };
143
143
  function extractTextFromContentBlocks(blocks) {
144
- const parts = [];
145
- for (const block of blocks) {
146
- if (block.type === "text") {
147
- parts.push(block.text);
148
- } else if (block.type === "resource_link") {
149
- parts.push(`[resource: ${block.uri}]`);
150
- } else if (block.type === "resource") {
151
- parts.push(`[resource: ${block.resource.uri}]`);
152
- }
153
- }
154
- return parts.join("\n");
144
+ const parts = [];
145
+ for (const block of blocks) if (block.type === "text") parts.push(block.text);
146
+ else if (block.type === "resource_link") parts.push(`[resource: ${block.uri}]`);
147
+ else if (block.type === "resource") parts.push(`[resource: ${block.resource.uri}]`);
148
+ return parts.join("\n");
155
149
  }
156
150
  function mapStopReason(reason) {
157
- switch (reason) {
158
- case "complete":
159
- return "end_turn";
160
- case "aborted":
161
- return "cancelled";
162
- case "error":
163
- return "end_turn";
164
- case "suspended":
165
- return "end_turn";
166
- }
151
+ switch (reason) {
152
+ case "complete": return "end_turn";
153
+ case "aborted": return "cancelled";
154
+ case "error": return "end_turn";
155
+ case "suspended": return "end_turn";
156
+ }
167
157
  }
168
- export {
169
- MastraCodeAcpAgent,
170
- extractTextFromContentBlocks,
171
- mapStopReason
172
- };
158
+ //#endregion
159
+ export { MastraCodeAcpAgent, extractTextFromContentBlocks, mapStopReason };
160
+
173
161
  //# sourceMappingURL=agent.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/acp/agent.ts"],"sourcesContent":["import type {\n Agent,\n AgentSideConnection,\n InitializeRequest,\n InitializeResponse,\n NewSessionRequest,\n NewSessionResponse,\n PromptRequest,\n PromptResponse,\n CancelNotification,\n ContentBlock,\n} from '@agentclientprotocol/sdk';\nimport { PROTOCOL_VERSION } from '@agentclientprotocol/sdk';\nimport type { AgentController, AgentControllerMode, Session } from '@mastra/core/agent-controller';\nimport { handleAgentControllerEvent } from './event-mapper.js';\nimport type { PromptState } from './event-mapper.js';\n\n/**\n * ACP Agent implementation that wraps a mastracode Controller.\n * Each instance represents one ACP connection from a client.\n */\nexport class MastraCodeAcpAgent implements Agent {\n private readonly connection: AgentSideConnection;\n private readonly controller: AgentController;\n private readonly session: Session;\n private readonly modes: AgentControllerMode[];\n private readonly unsubscribeSessionEvents: () => void;\n private readonly sessionMap = new Map<string, string>(); // sessionId -> threadId\n private currentPromptState: PromptState | null = null;\n private promptMutex: Promise<void> = Promise.resolve();\n\n private getThreadIdOrThrow(sessionId: string): string {\n const threadId = this.sessionMap.get(sessionId);\n if (!threadId) {\n throw new Error(`Unknown ACP sessionId: ${sessionId}`);\n }\n return threadId;\n }\n\n constructor(\n connection: AgentSideConnection,\n controller: AgentController,\n session: Session,\n modes: AgentControllerMode[],\n ) {\n this.connection = connection;\n this.controller = controller;\n this.session = session;\n this.modes = modes;\n\n // Register persistent event listener\n this.unsubscribeSessionEvents = this.session.subscribe(event => {\n handleAgentControllerEvent(event, this.currentPromptState, this.connection, this.session);\n });\n }\n\n dispose(): void {\n this.unsubscribeSessionEvents();\n }\n\n async initialize(_request: InitializeRequest): Promise<InitializeResponse> {\n return {\n protocolVersion: PROTOCOL_VERSION,\n agentInfo: {\n name: 'mastracode',\n title: 'Mastra Code',\n version: '0.1.0',\n },\n agentCapabilities: {\n loadSession: false,\n },\n };\n }\n\n async authenticate(): Promise<void> {\n // No-op: mastracode handles its own auth\n }\n\n async newSession(_request: NewSessionRequest): Promise<NewSessionResponse> {\n const thread = await this.session.thread.create();\n const sessionId = thread.id;\n this.sessionMap.set(sessionId, thread.id);\n\n // Switch to the new thread\n await this.session.thread.switch({ threadId: thread.id });\n\n // Build modes list from constructor param\n const availableModes = this.modes.map((m: AgentControllerMode) => ({\n id: m.id,\n name: m.name ?? m.id,\n }));\n\n const currentModeId = this.session.mode.get();\n\n // Build models list (best-effort)\n let models: NewSessionResponse['models'];\n try {\n const availableModels = await this.controller.listAvailableModels();\n const currentModelId = this.session.model.get();\n models = {\n currentModelId: currentModelId ?? '',\n availableModels: availableModels.map(m => ({\n modelId: m.id,\n name: m.modelName,\n })),\n };\n } catch {\n // Model listing may fail if no providers are configured\n }\n\n return {\n sessionId,\n modes: {\n currentModeId,\n availableModes,\n },\n models,\n };\n }\n\n async prompt(request: PromptRequest): Promise<PromptResponse> {\n const { sessionId, prompt: contentBlocks } = request;\n\n // Extract text from content blocks\n const text = extractTextFromContentBlocks(contentBlocks);\n\n const threadId = this.getThreadIdOrThrow(sessionId);\n\n // Serialize prompts via mutex\n const prevMutex = this.promptMutex;\n let resolveMutex: () => void;\n this.promptMutex = new Promise<void>(resolve => {\n resolveMutex = resolve;\n });\n\n await prevMutex;\n\n try {\n // Ensure we're on the right thread while prompts are serialized\n await this.session.thread.switch({ threadId });\n\n // Create prompt state that will be resolved when agent_end fires\n const result = new Promise<{\n reason: 'complete' | 'aborted' | 'error' | 'suspended';\n usage: PromptState['usage'];\n }>(resolve => {\n const usage: PromptState['usage'] = {\n promptTokens: 0,\n completionTokens: 0,\n totalTokens: 0,\n };\n\n this.currentPromptState = {\n sessionId,\n lastTextLength: 0,\n usage,\n resolve: reason => {\n resolve({ reason, usage });\n this.currentPromptState = null;\n },\n };\n });\n\n // Send the message to the session\n try {\n await this.session.sendMessage({ content: text });\n } catch (error) {\n this.currentPromptState = null;\n throw error;\n }\n\n // Wait for agent_end to resolve\n const { reason, usage } = await result;\n\n return {\n stopReason: mapStopReason(reason),\n usage: {\n inputTokens: usage.promptTokens,\n outputTokens: usage.completionTokens,\n totalTokens: usage.totalTokens,\n thoughtTokens: usage.reasoningTokens,\n cachedReadTokens: usage.cachedInputTokens,\n cachedWriteTokens: usage.cacheCreationInputTokens,\n },\n };\n } finally {\n resolveMutex!();\n }\n }\n\n async cancel(_notification: CancelNotification): Promise<void> {\n this.session.abort();\n }\n\n async setSessionMode(params: { sessionId: string; modeId: string }): Promise<void> {\n const threadId = this.getThreadIdOrThrow(params.sessionId);\n await this.session.thread.switch({ threadId });\n this.session.mode.set({ modeId: params.modeId });\n }\n\n async unstable_setSessionModel(params: { sessionId: string; modelId: string }): Promise<void> {\n const threadId = this.getThreadIdOrThrow(params.sessionId);\n await this.session.thread.switch({ threadId });\n this.session.model.set({ modelId: params.modelId });\n }\n}\n\nexport function extractTextFromContentBlocks(blocks: ContentBlock[]): string {\n const parts: string[] = [];\n for (const block of blocks) {\n if (block.type === 'text') {\n parts.push(block.text);\n } else if (block.type === 'resource_link') {\n parts.push(`[resource: ${block.uri}]`);\n } else if (block.type === 'resource') {\n parts.push(`[resource: ${block.resource.uri}]`);\n }\n }\n return parts.join('\\n');\n}\n\nexport function mapStopReason(\n reason: 'complete' | 'aborted' | 'error' | 'suspended',\n): 'end_turn' | 'cancelled' | 'max_tokens' | 'max_turn_requests' | 'refusal' {\n switch (reason) {\n case 'complete':\n return 'end_turn';\n case 'aborted':\n return 'cancelled';\n case 'error':\n return 'end_turn';\n case 'suspended':\n return 'end_turn';\n }\n}\n"],"mappings":"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","names":["usage","reason"]}
1
+ {"version":3,"file":"agent.js","names":[],"sources":["../../src/acp/agent.ts"],"sourcesContent":["import type {\n Agent,\n AgentSideConnection,\n InitializeRequest,\n InitializeResponse,\n NewSessionRequest,\n NewSessionResponse,\n PromptRequest,\n PromptResponse,\n CancelNotification,\n ContentBlock,\n} from '@agentclientprotocol/sdk';\nimport { PROTOCOL_VERSION } from '@agentclientprotocol/sdk';\nimport type { AgentController, AgentControllerMode, Session } from '@mastra/core/agent-controller';\nimport { handleAgentControllerEvent } from './event-mapper.js';\nimport type { PromptState } from './event-mapper.js';\n\n/**\n * ACP Agent implementation that wraps a mastracode Controller.\n * Each instance represents one ACP connection from a client.\n */\nexport class MastraCodeAcpAgent implements Agent {\n private readonly connection: AgentSideConnection;\n private readonly controller: AgentController;\n private readonly session: Session;\n private readonly modes: AgentControllerMode[];\n private readonly unsubscribeSessionEvents: () => void;\n private readonly sessionMap = new Map<string, string>(); // sessionId -> threadId\n private currentPromptState: PromptState | null = null;\n private promptMutex: Promise<void> = Promise.resolve();\n\n private getThreadIdOrThrow(sessionId: string): string {\n const threadId = this.sessionMap.get(sessionId);\n if (!threadId) {\n throw new Error(`Unknown ACP sessionId: ${sessionId}`);\n }\n return threadId;\n }\n\n constructor(\n connection: AgentSideConnection,\n controller: AgentController,\n session: Session,\n modes: AgentControllerMode[],\n ) {\n this.connection = connection;\n this.controller = controller;\n this.session = session;\n this.modes = modes;\n\n // Register persistent event listener\n this.unsubscribeSessionEvents = this.session.subscribe(event => {\n handleAgentControllerEvent(event, this.currentPromptState, this.connection, this.session);\n });\n }\n\n dispose(): void {\n this.unsubscribeSessionEvents();\n }\n\n async initialize(_request: InitializeRequest): Promise<InitializeResponse> {\n return {\n protocolVersion: PROTOCOL_VERSION,\n agentInfo: {\n name: 'mastracode',\n title: 'Mastra Code',\n version: '0.1.0',\n },\n agentCapabilities: {\n loadSession: false,\n },\n };\n }\n\n async authenticate(): Promise<void> {\n // No-op: mastracode handles its own auth\n }\n\n async newSession(_request: NewSessionRequest): Promise<NewSessionResponse> {\n const thread = await this.session.thread.create();\n const sessionId = thread.id;\n this.sessionMap.set(sessionId, thread.id);\n\n // Switch to the new thread\n await this.session.thread.switch({ threadId: thread.id });\n\n // Build modes list from constructor param\n const availableModes = this.modes.map((m: AgentControllerMode) => ({\n id: m.id,\n name: m.name ?? m.id,\n }));\n\n const currentModeId = this.session.mode.get();\n\n // Build models list (best-effort)\n let models: NewSessionResponse['models'];\n try {\n const availableModels = await this.controller.listAvailableModels();\n const currentModelId = this.session.model.get();\n models = {\n currentModelId: currentModelId ?? '',\n availableModels: availableModels.map(m => ({\n modelId: m.id,\n name: m.modelName,\n })),\n };\n } catch {\n // Model listing may fail if no providers are configured\n }\n\n return {\n sessionId,\n modes: {\n currentModeId,\n availableModes,\n },\n models,\n };\n }\n\n async prompt(request: PromptRequest): Promise<PromptResponse> {\n const { sessionId, prompt: contentBlocks } = request;\n\n // Extract text from content blocks\n const text = extractTextFromContentBlocks(contentBlocks);\n\n const threadId = this.getThreadIdOrThrow(sessionId);\n\n // Serialize prompts via mutex\n const prevMutex = this.promptMutex;\n let resolveMutex: () => void;\n this.promptMutex = new Promise<void>(resolve => {\n resolveMutex = resolve;\n });\n\n await prevMutex;\n\n try {\n // Ensure we're on the right thread while prompts are serialized\n await this.session.thread.switch({ threadId });\n\n // Create prompt state that will be resolved when agent_end fires\n const result = new Promise<{\n reason: 'complete' | 'aborted' | 'error' | 'suspended';\n usage: PromptState['usage'];\n }>(resolve => {\n const usage: PromptState['usage'] = {\n promptTokens: 0,\n completionTokens: 0,\n totalTokens: 0,\n };\n\n this.currentPromptState = {\n sessionId,\n lastTextLength: 0,\n usage,\n resolve: reason => {\n resolve({ reason, usage });\n this.currentPromptState = null;\n },\n };\n });\n\n // Send the message to the session\n try {\n await this.session.sendMessage({ content: text });\n } catch (error) {\n this.currentPromptState = null;\n throw error;\n }\n\n // Wait for agent_end to resolve\n const { reason, usage } = await result;\n\n return {\n stopReason: mapStopReason(reason),\n usage: {\n inputTokens: usage.promptTokens,\n outputTokens: usage.completionTokens,\n totalTokens: usage.totalTokens,\n thoughtTokens: usage.reasoningTokens,\n cachedReadTokens: usage.cachedInputTokens,\n cachedWriteTokens: usage.cacheCreationInputTokens,\n },\n };\n } finally {\n resolveMutex!();\n }\n }\n\n async cancel(_notification: CancelNotification): Promise<void> {\n this.session.abort();\n }\n\n async setSessionMode(params: { sessionId: string; modeId: string }): Promise<void> {\n const threadId = this.getThreadIdOrThrow(params.sessionId);\n await this.session.thread.switch({ threadId });\n this.session.mode.set({ modeId: params.modeId });\n }\n\n async unstable_setSessionModel(params: { sessionId: string; modelId: string }): Promise<void> {\n const threadId = this.getThreadIdOrThrow(params.sessionId);\n await this.session.thread.switch({ threadId });\n this.session.model.set({ modelId: params.modelId });\n }\n}\n\nexport function extractTextFromContentBlocks(blocks: ContentBlock[]): string {\n const parts: string[] = [];\n for (const block of blocks) {\n if (block.type === 'text') {\n parts.push(block.text);\n } else if (block.type === 'resource_link') {\n parts.push(`[resource: ${block.uri}]`);\n } else if (block.type === 'resource') {\n parts.push(`[resource: ${block.resource.uri}]`);\n }\n }\n return parts.join('\\n');\n}\n\nexport function mapStopReason(\n reason: 'complete' | 'aborted' | 'error' | 'suspended',\n): 'end_turn' | 'cancelled' | 'max_tokens' | 'max_turn_requests' | 'refusal' {\n switch (reason) {\n case 'complete':\n return 'end_turn';\n case 'aborted':\n return 'cancelled';\n case 'error':\n return 'end_turn';\n case 'suspended':\n return 'end_turn';\n }\n}\n"],"mappings":"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"}