@mastra/code-sdk 1.0.3-alpha.1 → 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 +38 -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 +12 -12
  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
@@ -1,207 +1,172 @@
1
+ //#region src/utils/errors.ts
2
+ /**
3
+ * Parse an error and return a user-friendly representation.
4
+ */
1
5
  function summarizeErrorDetail(error) {
2
- if (error instanceof Error) {
3
- if (error.cause instanceof Error && error.cause.message) {
4
- return error.cause.message;
5
- }
6
- if (typeof error.cause === "string" && error.cause.trim().length > 0) {
7
- return error.cause;
8
- }
9
- if (error.message.trim().length > 0) {
10
- return error.message;
11
- }
12
- }
13
- if (typeof error === "string" && error.trim().length > 0) {
14
- return error;
15
- }
16
- if (error && typeof error === "object") {
17
- const errorObj = error;
18
- const candidates = [errorObj["message"], errorObj["cause"], errorObj["code"], errorObj["statusText"]];
19
- for (const candidate of candidates) {
20
- if (typeof candidate === "string" && candidate.trim().length > 0) {
21
- return candidate;
22
- }
23
- }
24
- }
25
- return void 0;
6
+ if (error instanceof Error) {
7
+ if (error.cause instanceof Error && error.cause.message) return error.cause.message;
8
+ if (typeof error.cause === "string" && error.cause.trim().length > 0) return error.cause;
9
+ if (error.message.trim().length > 0) return error.message;
10
+ }
11
+ if (typeof error === "string" && error.trim().length > 0) return error;
12
+ if (error && typeof error === "object") {
13
+ const errorObj = error;
14
+ const candidates = [
15
+ errorObj["message"],
16
+ errorObj["cause"],
17
+ errorObj["code"],
18
+ errorObj["statusText"]
19
+ ];
20
+ for (const candidate of candidates) if (typeof candidate === "string" && candidate.trim().length > 0) return candidate;
21
+ }
26
22
  }
27
23
  function extractRequestUrl(error) {
28
- if (!error || typeof error !== "object") {
29
- return void 0;
30
- }
31
- const candidates = [];
32
- const errorObj = error;
33
- candidates.push(errorObj["requestUrl"], errorObj["url"]);
34
- if (errorObj["cause"] && typeof errorObj["cause"] === "object") {
35
- const causeObj = errorObj["cause"];
36
- candidates.push(causeObj["requestUrl"], causeObj["url"]);
37
- }
38
- for (const candidate of candidates) {
39
- if (typeof candidate === "string" && candidate.trim().length > 0) {
40
- return candidate;
41
- }
42
- }
43
- return void 0;
24
+ if (!error || typeof error !== "object") return;
25
+ const candidates = [];
26
+ const errorObj = error;
27
+ candidates.push(errorObj["requestUrl"], errorObj["url"]);
28
+ if (errorObj["cause"] && typeof errorObj["cause"] === "object") {
29
+ const causeObj = errorObj["cause"];
30
+ candidates.push(causeObj["requestUrl"], causeObj["url"]);
31
+ }
32
+ for (const candidate of candidates) if (typeof candidate === "string" && candidate.trim().length > 0) return candidate;
44
33
  }
45
34
  function parseError(error) {
46
- const err = error instanceof Error ? error : new Error(String(error));
47
- const message = err.message.toLowerCase();
48
- const errorObj = error;
49
- const detail = summarizeErrorDetail(error);
50
- const requestUrl = extractRequestUrl(error);
51
- if (message.includes("rate limit") || message.includes("rate_limit") || message.includes("429") || errorObj.statusCode === 429 || errorObj.status === 429) {
52
- const retryAfter = extractRetryAfter(errorObj);
53
- return {
54
- message: "Rate limited. Please wait a moment before trying again.",
55
- type: "rate_limit",
56
- retryable: true,
57
- retryDelay: retryAfter || 5e3,
58
- originalError: err
59
- };
60
- }
61
- if (message.includes("unauthorized") || message.includes("authentication") || message.includes("invalid api key") || message.includes("invalid_api_key") || message.includes("api key") || errorObj.statusCode === 401 || errorObj.status === 401) {
62
- return {
63
- message: "Authentication failed. Please check your API key or login with /login.",
64
- detail,
65
- requestUrl,
66
- type: "auth",
67
- retryable: false,
68
- originalError: err
69
- };
70
- }
71
- if (errorObj.statusCode === 403 || errorObj.status === 403) {
72
- return {
73
- message: "Access denied. You may not have permission to use this model.",
74
- detail,
75
- requestUrl,
76
- type: "auth",
77
- retryable: false,
78
- originalError: err
79
- };
80
- }
81
- if (message.includes("network") || message.includes("econnrefused") || message.includes("enotfound") || message.includes("fetch failed") || message.includes("connection")) {
82
- return {
83
- message: "Network error while contacting the provider or gateway.",
84
- detail,
85
- requestUrl,
86
- type: "network",
87
- retryable: true,
88
- retryDelay: 2e3,
89
- originalError: err
90
- };
91
- }
92
- if (message.includes("timeout") || message.includes("timed out") || message.includes("etimedout")) {
93
- return {
94
- message: "Request timed out. The server may be overloaded.",
95
- type: "timeout",
96
- retryable: true,
97
- retryDelay: 3e3,
98
- originalError: err
99
- };
100
- }
101
- if (message.includes("model not found") || message.includes("model_not_found") || message.includes("does not exist") || message.includes("invalid model")) {
102
- return {
103
- message: "Model not found. Please select a different model with /models.",
104
- type: "model_not_found",
105
- retryable: false,
106
- originalError: err
107
- };
108
- }
109
- if (message.includes("context length") || message.includes("context_length") || message.includes("too many tokens") || message.includes("maximum context") || message.includes("token limit")) {
110
- return {
111
- message: "Message too long. Try starting a new thread with /new.",
112
- type: "context_length",
113
- retryable: false,
114
- originalError: err
115
- };
116
- }
117
- if (message.includes("content filter") || message.includes("content_filter") || message.includes("content policy") || message.includes("safety") || message.includes("prohibited")) {
118
- return {
119
- message: "Content was filtered by the model's safety system.",
120
- type: "content_filter",
121
- retryable: false,
122
- originalError: err
123
- };
124
- }
125
- if (message.includes("internal server") || message.includes("server error") || errorObj.statusCode === 500 || errorObj.status === 500 || errorObj.statusCode === 502 || errorObj.status === 502 || errorObj.statusCode === 503 || errorObj.status === 503) {
126
- return {
127
- message: "Server error. The API may be experiencing issues.",
128
- type: "server_error",
129
- retryable: true,
130
- retryDelay: 5e3,
131
- originalError: err
132
- };
133
- }
134
- if (message.includes("invalid request") || message.includes("bad request") || errorObj.statusCode === 400 || errorObj.status === 400) {
135
- return {
136
- message: `Invalid request: ${extractErrorDetail(err)}`,
137
- type: "invalid_request",
138
- retryable: false,
139
- originalError: err
140
- };
141
- }
142
- return {
143
- message: extractErrorDetail(err),
144
- type: "unknown",
145
- retryable: false,
146
- originalError: err
147
- };
35
+ const err = error instanceof Error ? error : new Error(String(error));
36
+ const message = err.message.toLowerCase();
37
+ const errorObj = error;
38
+ const detail = summarizeErrorDetail(error);
39
+ const requestUrl = extractRequestUrl(error);
40
+ if (message.includes("rate limit") || message.includes("rate_limit") || message.includes("429") || errorObj.statusCode === 429 || errorObj.status === 429) return {
41
+ message: "Rate limited. Please wait a moment before trying again.",
42
+ type: "rate_limit",
43
+ retryable: true,
44
+ retryDelay: extractRetryAfter(errorObj) || 5e3,
45
+ originalError: err
46
+ };
47
+ if (message.includes("unauthorized") || message.includes("authentication") || message.includes("invalid api key") || message.includes("invalid_api_key") || message.includes("api key") || errorObj.statusCode === 401 || errorObj.status === 401) return {
48
+ message: "Authentication failed. Please check your API key or login with /login.",
49
+ detail,
50
+ requestUrl,
51
+ type: "auth",
52
+ retryable: false,
53
+ originalError: err
54
+ };
55
+ if (errorObj.statusCode === 403 || errorObj.status === 403) return {
56
+ message: "Access denied. You may not have permission to use this model.",
57
+ detail,
58
+ requestUrl,
59
+ type: "auth",
60
+ retryable: false,
61
+ originalError: err
62
+ };
63
+ if (message.includes("network") || message.includes("econnrefused") || message.includes("enotfound") || message.includes("fetch failed") || message.includes("connection")) return {
64
+ message: "Network error while contacting the provider or gateway.",
65
+ detail,
66
+ requestUrl,
67
+ type: "network",
68
+ retryable: true,
69
+ retryDelay: 2e3,
70
+ originalError: err
71
+ };
72
+ if (message.includes("timeout") || message.includes("timed out") || message.includes("etimedout")) return {
73
+ message: "Request timed out. The server may be overloaded.",
74
+ type: "timeout",
75
+ retryable: true,
76
+ retryDelay: 3e3,
77
+ originalError: err
78
+ };
79
+ if (message.includes("model not found") || message.includes("model_not_found") || message.includes("does not exist") || message.includes("invalid model")) return {
80
+ message: "Model not found. Please select a different model with /models.",
81
+ type: "model_not_found",
82
+ retryable: false,
83
+ originalError: err
84
+ };
85
+ if (message.includes("context length") || message.includes("context_length") || message.includes("too many tokens") || message.includes("maximum context") || message.includes("token limit")) return {
86
+ message: "Message too long. Try starting a new thread with /new.",
87
+ type: "context_length",
88
+ retryable: false,
89
+ originalError: err
90
+ };
91
+ if (message.includes("content filter") || message.includes("content_filter") || message.includes("content policy") || message.includes("safety") || message.includes("prohibited")) return {
92
+ message: "Content was filtered by the model's safety system.",
93
+ type: "content_filter",
94
+ retryable: false,
95
+ originalError: err
96
+ };
97
+ if (message.includes("internal server") || message.includes("server error") || errorObj.statusCode === 500 || errorObj.status === 500 || errorObj.statusCode === 502 || errorObj.status === 502 || errorObj.statusCode === 503 || errorObj.status === 503) return {
98
+ message: "Server error. The API may be experiencing issues.",
99
+ type: "server_error",
100
+ retryable: true,
101
+ retryDelay: 5e3,
102
+ originalError: err
103
+ };
104
+ if (message.includes("invalid request") || message.includes("bad request") || errorObj.statusCode === 400 || errorObj.status === 400) return {
105
+ message: `Invalid request: ${extractErrorDetail(err)}`,
106
+ type: "invalid_request",
107
+ retryable: false,
108
+ originalError: err
109
+ };
110
+ return {
111
+ message: extractErrorDetail(err),
112
+ type: "unknown",
113
+ retryable: false,
114
+ originalError: err
115
+ };
148
116
  }
117
+ /**
118
+ * Extract retry-after header value from error.
119
+ */
149
120
  function extractRetryAfter(error) {
150
- const headers = error.headers;
151
- const retryAfter = error.retryAfter || headers?.["retry-after"];
152
- if (typeof retryAfter === "number") {
153
- return retryAfter * 1e3;
154
- }
155
- if (typeof retryAfter === "string") {
156
- const seconds = parseInt(retryAfter, 10);
157
- if (!isNaN(seconds)) {
158
- return seconds * 1e3;
159
- }
160
- }
161
- return void 0;
121
+ const headers = error.headers;
122
+ const retryAfter = error.retryAfter || headers?.["retry-after"];
123
+ if (typeof retryAfter === "number") return retryAfter * 1e3;
124
+ if (typeof retryAfter === "string") {
125
+ const seconds = parseInt(retryAfter, 10);
126
+ if (!isNaN(seconds)) return seconds * 1e3;
127
+ }
162
128
  }
129
+ /**
130
+ * Extract a useful error detail from an error object.
131
+ */
163
132
  function extractErrorDetail(error) {
164
- const errorObj = error;
165
- if (errorObj.error && typeof errorObj.error === "object") {
166
- const apiError = errorObj.error;
167
- if (apiError.message) return String(apiError.message);
168
- }
169
- if (errorObj.message) return String(errorObj.message);
170
- if (errorObj.detail) return String(errorObj.detail);
171
- if (errorObj.reason) return String(errorObj.reason);
172
- let message = error.message;
173
- message = message.replace(/^(error|exception|failed):\s*/i, "");
174
- if (message.length > 200) {
175
- message = message.substring(0, 200) + "...";
176
- }
177
- return message || "An unknown error occurred";
133
+ const errorObj = error;
134
+ if (errorObj.error && typeof errorObj.error === "object") {
135
+ const apiError = errorObj.error;
136
+ if (apiError.message) return String(apiError.message);
137
+ }
138
+ if (errorObj.message) return String(errorObj.message);
139
+ if (errorObj.detail) return String(errorObj.detail);
140
+ if (errorObj.reason) return String(errorObj.reason);
141
+ let message = error.message;
142
+ message = message.replace(/^(error|exception|failed):\s*/i, "");
143
+ if (message.length > 200) message = message.substring(0, 200) + "...";
144
+ return message || "An unknown error occurred";
178
145
  }
146
+ /**
147
+ * Sleep for a given number of milliseconds.
148
+ */
179
149
  function sleep(ms) {
180
- return new Promise((resolve) => setTimeout(resolve, ms));
150
+ return new Promise((resolve) => setTimeout(resolve, ms));
181
151
  }
152
+ /**
153
+ * Retry a function with exponential backoff.
154
+ */
182
155
  async function withRetry(fn, options = {}) {
183
- const { maxRetries = 3, initialDelay = 1e3, maxDelay = 3e4, onRetry } = options;
184
- let lastError;
185
- for (let attempt = 0; attempt <= maxRetries; attempt++) {
186
- try {
187
- return await fn();
188
- } catch (error) {
189
- lastError = parseError(error);
190
- if (!lastError.retryable || attempt === maxRetries) {
191
- throw lastError.originalError;
192
- }
193
- const delay = Math.min(lastError.retryDelay || initialDelay * Math.pow(2, attempt), maxDelay);
194
- if (onRetry) {
195
- onRetry(lastError, attempt + 1);
196
- }
197
- await sleep(delay);
198
- }
199
- }
200
- throw lastError?.originalError || new Error("Retry failed");
156
+ const { maxRetries = 3, initialDelay = 1e3, maxDelay = 3e4, onRetry } = options;
157
+ let lastError;
158
+ for (let attempt = 0; attempt <= maxRetries; attempt++) try {
159
+ return await fn();
160
+ } catch (error) {
161
+ lastError = parseError(error);
162
+ if (!lastError.retryable || attempt === maxRetries) throw lastError.originalError;
163
+ const delay = Math.min(lastError.retryDelay || initialDelay * Math.pow(2, attempt), maxDelay);
164
+ if (onRetry) onRetry(lastError, attempt + 1);
165
+ await sleep(delay);
166
+ }
167
+ throw lastError?.originalError || /* @__PURE__ */ new Error("Retry failed");
201
168
  }
202
- export {
203
- parseError,
204
- sleep,
205
- withRetry
206
- };
169
+ //#endregion
170
+ export { parseError, sleep, withRetry };
171
+
207
172
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/errors.ts"],"sourcesContent":["/**\n * Error handling utilities for the Mastra Code TUI.\n * Parses API errors and provides user-friendly messages.\n */\n\nexport interface ParsedError {\n /** User-friendly error message */\n message: string;\n /** Extra diagnostic detail to surface to the user */\n detail?: string;\n /** Request URL involved in the failure, when available */\n requestUrl?: string;\n /** Error type for categorization */\n type: ErrorType;\n /** Whether this error is retryable */\n retryable: boolean;\n /** Suggested retry delay in ms (if retryable) */\n retryDelay?: number;\n /** Original error for debugging */\n originalError: Error;\n}\n\nexport type ErrorType =\n | 'rate_limit'\n | 'auth'\n | 'network'\n | 'timeout'\n | 'invalid_request'\n | 'server_error'\n | 'model_not_found'\n | 'context_length'\n | 'content_filter'\n | 'unknown';\n\n/**\n * Parse an error and return a user-friendly representation.\n */\nfunction summarizeErrorDetail(error: unknown): string | undefined {\n if (error instanceof Error) {\n if (error.cause instanceof Error && error.cause.message) {\n return error.cause.message;\n }\n\n if (typeof error.cause === 'string' && error.cause.trim().length > 0) {\n return error.cause;\n }\n\n if (error.message.trim().length > 0) {\n return error.message;\n }\n }\n\n if (typeof error === 'string' && error.trim().length > 0) {\n return error;\n }\n\n if (error && typeof error === 'object') {\n const errorObj = error as Record<string, unknown>;\n const candidates = [errorObj['message'], errorObj['cause'], errorObj['code'], errorObj['statusText']];\n\n for (const candidate of candidates) {\n if (typeof candidate === 'string' && candidate.trim().length > 0) {\n return candidate;\n }\n }\n }\n\n return undefined;\n}\n\nfunction extractRequestUrl(error: unknown): string | undefined {\n if (!error || typeof error !== 'object') {\n return undefined;\n }\n\n const candidates: unknown[] = [];\n const errorObj = error as Record<string, unknown>;\n candidates.push(errorObj['requestUrl'], errorObj['url']);\n\n if (errorObj['cause'] && typeof errorObj['cause'] === 'object') {\n const causeObj = errorObj['cause'] as Record<string, unknown>;\n candidates.push(causeObj['requestUrl'], causeObj['url']);\n }\n\n for (const candidate of candidates) {\n if (typeof candidate === 'string' && candidate.trim().length > 0) {\n return candidate;\n }\n }\n\n return undefined;\n}\n\nexport function parseError(error: unknown): ParsedError {\n const err = error instanceof Error ? error : new Error(String(error));\n const message = err.message.toLowerCase();\n const errorObj = error as Record<string, unknown>;\n const detail = summarizeErrorDetail(error);\n const requestUrl = extractRequestUrl(error);\n\n // Check for rate limiting\n if (\n message.includes('rate limit') ||\n message.includes('rate_limit') ||\n message.includes('429') ||\n errorObj.statusCode === 429 ||\n errorObj.status === 429\n ) {\n const retryAfter = extractRetryAfter(errorObj);\n return {\n message: 'Rate limited. Please wait a moment before trying again.',\n type: 'rate_limit',\n retryable: true,\n retryDelay: retryAfter || 5000,\n originalError: err,\n };\n }\n\n // Check for authentication errors\n if (\n message.includes('unauthorized') ||\n message.includes('authentication') ||\n message.includes('invalid api key') ||\n message.includes('invalid_api_key') ||\n message.includes('api key') ||\n errorObj.statusCode === 401 ||\n errorObj.status === 401\n ) {\n return {\n message: 'Authentication failed. Please check your API key or login with /login.',\n detail,\n requestUrl,\n type: 'auth',\n retryable: false,\n originalError: err,\n };\n }\n\n // Check for forbidden/permission errors\n if (errorObj.statusCode === 403 || errorObj.status === 403) {\n return {\n message: 'Access denied. You may not have permission to use this model.',\n detail,\n requestUrl,\n type: 'auth',\n retryable: false,\n originalError: err,\n };\n }\n\n // Check for network errors\n if (\n message.includes('network') ||\n message.includes('econnrefused') ||\n message.includes('enotfound') ||\n message.includes('fetch failed') ||\n message.includes('connection')\n ) {\n return {\n message: 'Network error while contacting the provider or gateway.',\n detail,\n requestUrl,\n type: 'network',\n retryable: true,\n retryDelay: 2000,\n originalError: err,\n };\n }\n\n // Check for timeout errors\n if (message.includes('timeout') || message.includes('timed out') || message.includes('etimedout')) {\n return {\n message: 'Request timed out. The server may be overloaded.',\n type: 'timeout',\n retryable: true,\n retryDelay: 3000,\n originalError: err,\n };\n }\n\n // Check for model not found\n if (\n message.includes('model not found') ||\n message.includes('model_not_found') ||\n message.includes('does not exist') ||\n message.includes('invalid model')\n ) {\n return {\n message: 'Model not found. Please select a different model with /models.',\n type: 'model_not_found',\n retryable: false,\n originalError: err,\n };\n }\n\n // Check for context length errors\n if (\n message.includes('context length') ||\n message.includes('context_length') ||\n message.includes('too many tokens') ||\n message.includes('maximum context') ||\n message.includes('token limit')\n ) {\n return {\n message: 'Message too long. Try starting a new thread with /new.',\n type: 'context_length',\n retryable: false,\n originalError: err,\n };\n }\n\n // Check for content filter errors\n if (\n message.includes('content filter') ||\n message.includes('content_filter') ||\n message.includes('content policy') ||\n message.includes('safety') ||\n message.includes('prohibited')\n ) {\n return {\n message: \"Content was filtered by the model's safety system.\",\n type: 'content_filter',\n retryable: false,\n originalError: err,\n };\n }\n\n // Check for server errors\n if (\n message.includes('internal server') ||\n message.includes('server error') ||\n errorObj.statusCode === 500 ||\n errorObj.status === 500 ||\n errorObj.statusCode === 502 ||\n errorObj.status === 502 ||\n errorObj.statusCode === 503 ||\n errorObj.status === 503\n ) {\n return {\n message: 'Server error. The API may be experiencing issues.',\n type: 'server_error',\n retryable: true,\n retryDelay: 5000,\n originalError: err,\n };\n }\n\n // Check for invalid request errors\n if (\n message.includes('invalid request') ||\n message.includes('bad request') ||\n errorObj.statusCode === 400 ||\n errorObj.status === 400\n ) {\n return {\n message: `Invalid request: ${extractErrorDetail(err)}`,\n type: 'invalid_request',\n retryable: false,\n originalError: err,\n };\n }\n\n // Unknown error - try to extract useful info\n return {\n message: extractErrorDetail(err),\n type: 'unknown',\n retryable: false,\n originalError: err,\n };\n}\n\n/**\n * Extract retry-after header value from error.\n */\nfunction extractRetryAfter(error: Record<string, unknown>): number | undefined {\n const headers = error.headers as Record<string, unknown> | undefined;\n const retryAfter = error.retryAfter || headers?.['retry-after'];\n if (typeof retryAfter === 'number') {\n return retryAfter * 1000; // Convert seconds to ms\n }\n if (typeof retryAfter === 'string') {\n const seconds = parseInt(retryAfter, 10);\n if (!isNaN(seconds)) {\n return seconds * 1000;\n }\n }\n return undefined;\n}\n\n/**\n * Extract a useful error detail from an error object.\n */\nfunction extractErrorDetail(error: Error): string {\n const errorObj = error as unknown as Record<string, unknown>;\n\n // Try to get a specific error message from common API error formats\n if (errorObj.error && typeof errorObj.error === 'object') {\n const apiError = errorObj.error as Record<string, unknown>;\n if (apiError.message) return String(apiError.message);\n }\n\n if (errorObj.message) return String(errorObj.message);\n if (errorObj.detail) return String(errorObj.detail);\n if (errorObj.reason) return String(errorObj.reason);\n\n // Clean up the error message\n let message = error.message;\n\n // Remove common prefixes\n message = message.replace(/^(error|exception|failed):\\s*/i, '');\n\n // Truncate very long messages\n if (message.length > 200) {\n message = message.substring(0, 200) + '...';\n }\n\n return message || 'An unknown error occurred';\n}\n\n/**\n * Sleep for a given number of milliseconds.\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n/**\n * Retry a function with exponential backoff.\n */\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n options: {\n maxRetries?: number;\n initialDelay?: number;\n maxDelay?: number;\n onRetry?: (error: ParsedError, attempt: number) => void;\n } = {},\n): Promise<T> {\n const { maxRetries = 3, initialDelay = 1000, maxDelay = 30000, onRetry } = options;\n\n let lastError: ParsedError | undefined;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = parseError(error);\n\n // Don't retry non-retryable errors\n if (!lastError.retryable || attempt === maxRetries) {\n throw lastError.originalError;\n }\n\n // Calculate delay with exponential backoff\n const delay = Math.min(lastError.retryDelay || initialDelay * Math.pow(2, attempt), maxDelay);\n\n if (onRetry) {\n onRetry(lastError, attempt + 1);\n }\n\n await sleep(delay);\n }\n }\n\n // Should never reach here, but TypeScript needs this\n throw lastError?.originalError || new Error('Retry failed');\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"file":"errors.js","names":[],"sources":["../../src/utils/errors.ts"],"sourcesContent":["/**\n * Error handling utilities for the Mastra Code TUI.\n * Parses API errors and provides user-friendly messages.\n */\n\nexport interface ParsedError {\n /** User-friendly error message */\n message: string;\n /** Extra diagnostic detail to surface to the user */\n detail?: string;\n /** Request URL involved in the failure, when available */\n requestUrl?: string;\n /** Error type for categorization */\n type: ErrorType;\n /** Whether this error is retryable */\n retryable: boolean;\n /** Suggested retry delay in ms (if retryable) */\n retryDelay?: number;\n /** Original error for debugging */\n originalError: Error;\n}\n\nexport type ErrorType =\n | 'rate_limit'\n | 'auth'\n | 'network'\n | 'timeout'\n | 'invalid_request'\n | 'server_error'\n | 'model_not_found'\n | 'context_length'\n | 'content_filter'\n | 'unknown';\n\n/**\n * Parse an error and return a user-friendly representation.\n */\nfunction summarizeErrorDetail(error: unknown): string | undefined {\n if (error instanceof Error) {\n if (error.cause instanceof Error && error.cause.message) {\n return error.cause.message;\n }\n\n if (typeof error.cause === 'string' && error.cause.trim().length > 0) {\n return error.cause;\n }\n\n if (error.message.trim().length > 0) {\n return error.message;\n }\n }\n\n if (typeof error === 'string' && error.trim().length > 0) {\n return error;\n }\n\n if (error && typeof error === 'object') {\n const errorObj = error as Record<string, unknown>;\n const candidates = [errorObj['message'], errorObj['cause'], errorObj['code'], errorObj['statusText']];\n\n for (const candidate of candidates) {\n if (typeof candidate === 'string' && candidate.trim().length > 0) {\n return candidate;\n }\n }\n }\n\n return undefined;\n}\n\nfunction extractRequestUrl(error: unknown): string | undefined {\n if (!error || typeof error !== 'object') {\n return undefined;\n }\n\n const candidates: unknown[] = [];\n const errorObj = error as Record<string, unknown>;\n candidates.push(errorObj['requestUrl'], errorObj['url']);\n\n if (errorObj['cause'] && typeof errorObj['cause'] === 'object') {\n const causeObj = errorObj['cause'] as Record<string, unknown>;\n candidates.push(causeObj['requestUrl'], causeObj['url']);\n }\n\n for (const candidate of candidates) {\n if (typeof candidate === 'string' && candidate.trim().length > 0) {\n return candidate;\n }\n }\n\n return undefined;\n}\n\nexport function parseError(error: unknown): ParsedError {\n const err = error instanceof Error ? error : new Error(String(error));\n const message = err.message.toLowerCase();\n const errorObj = error as Record<string, unknown>;\n const detail = summarizeErrorDetail(error);\n const requestUrl = extractRequestUrl(error);\n\n // Check for rate limiting\n if (\n message.includes('rate limit') ||\n message.includes('rate_limit') ||\n message.includes('429') ||\n errorObj.statusCode === 429 ||\n errorObj.status === 429\n ) {\n const retryAfter = extractRetryAfter(errorObj);\n return {\n message: 'Rate limited. Please wait a moment before trying again.',\n type: 'rate_limit',\n retryable: true,\n retryDelay: retryAfter || 5000,\n originalError: err,\n };\n }\n\n // Check for authentication errors\n if (\n message.includes('unauthorized') ||\n message.includes('authentication') ||\n message.includes('invalid api key') ||\n message.includes('invalid_api_key') ||\n message.includes('api key') ||\n errorObj.statusCode === 401 ||\n errorObj.status === 401\n ) {\n return {\n message: 'Authentication failed. Please check your API key or login with /login.',\n detail,\n requestUrl,\n type: 'auth',\n retryable: false,\n originalError: err,\n };\n }\n\n // Check for forbidden/permission errors\n if (errorObj.statusCode === 403 || errorObj.status === 403) {\n return {\n message: 'Access denied. You may not have permission to use this model.',\n detail,\n requestUrl,\n type: 'auth',\n retryable: false,\n originalError: err,\n };\n }\n\n // Check for network errors\n if (\n message.includes('network') ||\n message.includes('econnrefused') ||\n message.includes('enotfound') ||\n message.includes('fetch failed') ||\n message.includes('connection')\n ) {\n return {\n message: 'Network error while contacting the provider or gateway.',\n detail,\n requestUrl,\n type: 'network',\n retryable: true,\n retryDelay: 2000,\n originalError: err,\n };\n }\n\n // Check for timeout errors\n if (message.includes('timeout') || message.includes('timed out') || message.includes('etimedout')) {\n return {\n message: 'Request timed out. The server may be overloaded.',\n type: 'timeout',\n retryable: true,\n retryDelay: 3000,\n originalError: err,\n };\n }\n\n // Check for model not found\n if (\n message.includes('model not found') ||\n message.includes('model_not_found') ||\n message.includes('does not exist') ||\n message.includes('invalid model')\n ) {\n return {\n message: 'Model not found. Please select a different model with /models.',\n type: 'model_not_found',\n retryable: false,\n originalError: err,\n };\n }\n\n // Check for context length errors\n if (\n message.includes('context length') ||\n message.includes('context_length') ||\n message.includes('too many tokens') ||\n message.includes('maximum context') ||\n message.includes('token limit')\n ) {\n return {\n message: 'Message too long. Try starting a new thread with /new.',\n type: 'context_length',\n retryable: false,\n originalError: err,\n };\n }\n\n // Check for content filter errors\n if (\n message.includes('content filter') ||\n message.includes('content_filter') ||\n message.includes('content policy') ||\n message.includes('safety') ||\n message.includes('prohibited')\n ) {\n return {\n message: \"Content was filtered by the model's safety system.\",\n type: 'content_filter',\n retryable: false,\n originalError: err,\n };\n }\n\n // Check for server errors\n if (\n message.includes('internal server') ||\n message.includes('server error') ||\n errorObj.statusCode === 500 ||\n errorObj.status === 500 ||\n errorObj.statusCode === 502 ||\n errorObj.status === 502 ||\n errorObj.statusCode === 503 ||\n errorObj.status === 503\n ) {\n return {\n message: 'Server error. The API may be experiencing issues.',\n type: 'server_error',\n retryable: true,\n retryDelay: 5000,\n originalError: err,\n };\n }\n\n // Check for invalid request errors\n if (\n message.includes('invalid request') ||\n message.includes('bad request') ||\n errorObj.statusCode === 400 ||\n errorObj.status === 400\n ) {\n return {\n message: `Invalid request: ${extractErrorDetail(err)}`,\n type: 'invalid_request',\n retryable: false,\n originalError: err,\n };\n }\n\n // Unknown error - try to extract useful info\n return {\n message: extractErrorDetail(err),\n type: 'unknown',\n retryable: false,\n originalError: err,\n };\n}\n\n/**\n * Extract retry-after header value from error.\n */\nfunction extractRetryAfter(error: Record<string, unknown>): number | undefined {\n const headers = error.headers as Record<string, unknown> | undefined;\n const retryAfter = error.retryAfter || headers?.['retry-after'];\n if (typeof retryAfter === 'number') {\n return retryAfter * 1000; // Convert seconds to ms\n }\n if (typeof retryAfter === 'string') {\n const seconds = parseInt(retryAfter, 10);\n if (!isNaN(seconds)) {\n return seconds * 1000;\n }\n }\n return undefined;\n}\n\n/**\n * Extract a useful error detail from an error object.\n */\nfunction extractErrorDetail(error: Error): string {\n const errorObj = error as unknown as Record<string, unknown>;\n\n // Try to get a specific error message from common API error formats\n if (errorObj.error && typeof errorObj.error === 'object') {\n const apiError = errorObj.error as Record<string, unknown>;\n if (apiError.message) return String(apiError.message);\n }\n\n if (errorObj.message) return String(errorObj.message);\n if (errorObj.detail) return String(errorObj.detail);\n if (errorObj.reason) return String(errorObj.reason);\n\n // Clean up the error message\n let message = error.message;\n\n // Remove common prefixes\n message = message.replace(/^(error|exception|failed):\\s*/i, '');\n\n // Truncate very long messages\n if (message.length > 200) {\n message = message.substring(0, 200) + '...';\n }\n\n return message || 'An unknown error occurred';\n}\n\n/**\n * Sleep for a given number of milliseconds.\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n/**\n * Retry a function with exponential backoff.\n */\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n options: {\n maxRetries?: number;\n initialDelay?: number;\n maxDelay?: number;\n onRetry?: (error: ParsedError, attempt: number) => void;\n } = {},\n): Promise<T> {\n const { maxRetries = 3, initialDelay = 1000, maxDelay = 30000, onRetry } = options;\n\n let lastError: ParsedError | undefined;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = parseError(error);\n\n // Don't retry non-retryable errors\n if (!lastError.retryable || attempt === maxRetries) {\n throw lastError.originalError;\n }\n\n // Calculate delay with exponential backoff\n const delay = Math.min(lastError.retryDelay || initialDelay * Math.pow(2, attempt), maxDelay);\n\n if (onRetry) {\n onRetry(lastError, attempt + 1);\n }\n\n await sleep(delay);\n }\n }\n\n // Should never reach here, but TypeScript needs this\n throw lastError?.originalError || new Error('Retry failed');\n}\n"],"mappings":"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"}
@@ -1,49 +1,61 @@
1
1
  import { GatewayRegistry } from "@mastra/core/llm";
2
- const DEFAULT_SYNC_INTERVAL_MS = 5 * 60 * 1e3;
2
+ //#region src/utils/gateway-sync.ts
3
+ /**
4
+ * Gateway sync utility for keeping the model registry up to date.
5
+ *
6
+ * This is a thin wrapper around `@mastra/core/llm`'s `GatewayRegistry` so
7
+ * mastracode and `mastra dev` share a single implementation for fetching
8
+ * providers, generating types, and writing to the global cache. Keep this
9
+ * file small — provider/registry logic belongs in `@mastra/core`.
10
+ */
11
+ const DEFAULT_SYNC_INTERVAL_MS = 300 * 1e3;
3
12
  let syncInterval = null;
4
13
  let isSyncing = false;
5
14
  function getRegistry() {
6
- return GatewayRegistry.getInstance({ useDynamicLoading: true });
15
+ return GatewayRegistry.getInstance({ useDynamicLoading: true });
7
16
  }
17
+ /**
18
+ * Sync gateways and update the global cache via `@mastra/core`'s registry.
19
+ *
20
+ * Skips the sync if the global cache was refreshed within the last
21
+ * `DEFAULT_SYNC_INTERVAL_MS`, unless `force` is set. Multiple calls in
22
+ * the same process coalesce while a sync is in flight.
23
+ */
8
24
  async function syncGateways(force = false) {
9
- if (isSyncing && !force) {
10
- return;
11
- }
12
- if (!force) {
13
- const lastSync = getRegistry().getLastRefreshTime();
14
- if (lastSync && Date.now() - lastSync.getTime() < DEFAULT_SYNC_INTERVAL_MS) {
15
- return;
16
- }
17
- }
18
- isSyncing = true;
19
- try {
20
- await getRegistry().syncGateways(true);
21
- } catch {
22
- } finally {
23
- isSyncing = false;
24
- }
25
+ if (isSyncing && !force) return;
26
+ if (!force) {
27
+ const lastSync = getRegistry().getLastRefreshTime();
28
+ if (lastSync && Date.now() - lastSync.getTime() < DEFAULT_SYNC_INTERVAL_MS) return;
29
+ }
30
+ isSyncing = true;
31
+ try {
32
+ await getRegistry().syncGateways(true);
33
+ } catch {} finally {
34
+ isSyncing = false;
35
+ }
25
36
  }
37
+ /**
38
+ * Start periodic gateway sync.
39
+ * @param intervalMs Sync interval in milliseconds (default: 5 minutes)
40
+ */
26
41
  function startGatewaySync(intervalMs = DEFAULT_SYNC_INTERVAL_MS) {
27
- if (syncInterval) {
28
- return;
29
- }
30
- syncGateways().catch(() => {
31
- });
32
- syncInterval = setInterval(() => {
33
- syncGateways().catch(() => {
34
- });
35
- }, intervalMs);
36
- syncInterval.unref();
42
+ if (syncInterval) return;
43
+ syncGateways().catch(() => {});
44
+ syncInterval = setInterval(() => {
45
+ syncGateways().catch(() => {});
46
+ }, intervalMs);
47
+ syncInterval.unref();
37
48
  }
49
+ /**
50
+ * Stop periodic gateway sync.
51
+ */
38
52
  function stopGatewaySync() {
39
- if (syncInterval) {
40
- clearInterval(syncInterval);
41
- syncInterval = null;
42
- }
53
+ if (syncInterval) {
54
+ clearInterval(syncInterval);
55
+ syncInterval = null;
56
+ }
43
57
  }
44
- export {
45
- startGatewaySync,
46
- stopGatewaySync,
47
- syncGateways
48
- };
58
+ //#endregion
59
+ export { startGatewaySync, stopGatewaySync, syncGateways };
60
+
49
61
  //# sourceMappingURL=gateway-sync.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/gateway-sync.ts"],"sourcesContent":["/**\n * Gateway sync utility for keeping the model registry up to date.\n *\n * This is a thin wrapper around `@mastra/core/llm`'s `GatewayRegistry` so\n * mastracode and `mastra dev` share a single implementation for fetching\n * providers, generating types, and writing to the global cache. Keep this\n * file small — provider/registry logic belongs in `@mastra/core`.\n */\n\nimport { GatewayRegistry } from '@mastra/core/llm';\n\nconst DEFAULT_SYNC_INTERVAL_MS = 5 * 60 * 1000;\n\nlet syncInterval: NodeJS.Timeout | null = null;\nlet isSyncing = false;\n\nfunction getRegistry(): GatewayRegistry {\n return GatewayRegistry.getInstance({ useDynamicLoading: true });\n}\n\n/**\n * Sync gateways and update the global cache via `@mastra/core`'s registry.\n *\n * Skips the sync if the global cache was refreshed within the last\n * `DEFAULT_SYNC_INTERVAL_MS`, unless `force` is set. Multiple calls in\n * the same process coalesce while a sync is in flight.\n */\nexport async function syncGateways(force = false): Promise<void> {\n if (isSyncing && !force) {\n return;\n }\n\n if (!force) {\n const lastSync = getRegistry().getLastRefreshTime();\n if (lastSync && Date.now() - lastSync.getTime() < DEFAULT_SYNC_INTERVAL_MS) {\n return;\n }\n }\n\n isSyncing = true;\n try {\n await getRegistry().syncGateways(true);\n } catch {\n // Silently ignore — the bundled registry already contains all model\n // data so a failed network fetch is non-critical.\n } finally {\n isSyncing = false;\n }\n}\n\n/**\n * Start periodic gateway sync.\n * @param intervalMs Sync interval in milliseconds (default: 5 minutes)\n */\nexport function startGatewaySync(intervalMs = DEFAULT_SYNC_INTERVAL_MS): void {\n if (syncInterval) {\n return;\n }\n\n // Do an initial sync (will skip if recently synced)\n syncGateways().catch(() => {});\n\n // Set up periodic sync\n syncInterval = setInterval(() => {\n syncGateways().catch(() => {});\n }, intervalMs);\n\n // Don't prevent process exit\n syncInterval.unref();\n}\n\n/**\n * Stop periodic gateway sync.\n */\nexport function stopGatewaySync(): void {\n if (syncInterval) {\n clearInterval(syncInterval);\n syncInterval = null;\n }\n}\n"],"mappings":"AASA,SAAS,uBAAuB;AAEhC,MAAM,2BAA2B,IAAI,KAAK;AAE1C,IAAI,eAAsC;AAC1C,IAAI,YAAY;AAEhB,SAAS,cAA+B;AACtC,SAAO,gBAAgB,YAAY,EAAE,mBAAmB,KAAK,CAAC;AAChE;AASA,eAAsB,aAAa,QAAQ,OAAsB;AAC/D,MAAI,aAAa,CAAC,OAAO;AACvB;AAAA,EACF;AAEA,MAAI,CAAC,OAAO;AACV,UAAM,WAAW,YAAY,EAAE,mBAAmB;AAClD,QAAI,YAAY,KAAK,IAAI,IAAI,SAAS,QAAQ,IAAI,0BAA0B;AAC1E;AAAA,IACF;AAAA,EACF;AAEA,cAAY;AACZ,MAAI;AACF,UAAM,YAAY,EAAE,aAAa,IAAI;AAAA,EACvC,QAAQ;AAAA,EAGR,UAAE;AACA,gBAAY;AAAA,EACd;AACF;AAMO,SAAS,iBAAiB,aAAa,0BAAgC;AAC5E,MAAI,cAAc;AAChB;AAAA,EACF;AAGA,eAAa,EAAE,MAAM,MAAM;AAAA,EAAC,CAAC;AAG7B,iBAAe,YAAY,MAAM;AAC/B,iBAAa,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAAA,EAC/B,GAAG,UAAU;AAGb,eAAa,MAAM;AACrB;AAKO,SAAS,kBAAwB;AACtC,MAAI,cAAc;AAChB,kBAAc,YAAY;AAC1B,mBAAe;AAAA,EACjB;AACF;","names":[]}
1
+ {"version":3,"file":"gateway-sync.js","names":[],"sources":["../../src/utils/gateway-sync.ts"],"sourcesContent":["/**\n * Gateway sync utility for keeping the model registry up to date.\n *\n * This is a thin wrapper around `@mastra/core/llm`'s `GatewayRegistry` so\n * mastracode and `mastra dev` share a single implementation for fetching\n * providers, generating types, and writing to the global cache. Keep this\n * file small — provider/registry logic belongs in `@mastra/core`.\n */\n\nimport { GatewayRegistry } from '@mastra/core/llm';\n\nconst DEFAULT_SYNC_INTERVAL_MS = 5 * 60 * 1000;\n\nlet syncInterval: NodeJS.Timeout | null = null;\nlet isSyncing = false;\n\nfunction getRegistry(): GatewayRegistry {\n return GatewayRegistry.getInstance({ useDynamicLoading: true });\n}\n\n/**\n * Sync gateways and update the global cache via `@mastra/core`'s registry.\n *\n * Skips the sync if the global cache was refreshed within the last\n * `DEFAULT_SYNC_INTERVAL_MS`, unless `force` is set. Multiple calls in\n * the same process coalesce while a sync is in flight.\n */\nexport async function syncGateways(force = false): Promise<void> {\n if (isSyncing && !force) {\n return;\n }\n\n if (!force) {\n const lastSync = getRegistry().getLastRefreshTime();\n if (lastSync && Date.now() - lastSync.getTime() < DEFAULT_SYNC_INTERVAL_MS) {\n return;\n }\n }\n\n isSyncing = true;\n try {\n await getRegistry().syncGateways(true);\n } catch {\n // Silently ignore — the bundled registry already contains all model\n // data so a failed network fetch is non-critical.\n } finally {\n isSyncing = false;\n }\n}\n\n/**\n * Start periodic gateway sync.\n * @param intervalMs Sync interval in milliseconds (default: 5 minutes)\n */\nexport function startGatewaySync(intervalMs = DEFAULT_SYNC_INTERVAL_MS): void {\n if (syncInterval) {\n return;\n }\n\n // Do an initial sync (will skip if recently synced)\n syncGateways().catch(() => {});\n\n // Set up periodic sync\n syncInterval = setInterval(() => {\n syncGateways().catch(() => {});\n }, intervalMs);\n\n // Don't prevent process exit\n syncInterval.unref();\n}\n\n/**\n * Stop periodic gateway sync.\n */\nexport function stopGatewaySync(): void {\n if (syncInterval) {\n clearInterval(syncInterval);\n syncInterval = null;\n }\n}\n"],"mappings":";;;;;;;;;;AAWA,MAAM,2BAA2B,MAAS;AAE1C,IAAI,eAAsC;AAC1C,IAAI,YAAY;AAEhB,SAAS,cAA+B;CACtC,OAAO,gBAAgB,YAAY,EAAE,mBAAmB,KAAK,CAAC;AAChE;;;;;;;;AASA,eAAsB,aAAa,QAAQ,OAAsB;CAC/D,IAAI,aAAa,CAAC,OAChB;CAGF,IAAI,CAAC,OAAO;EACV,MAAM,WAAW,YAAY,CAAC,CAAC,mBAAmB;EAClD,IAAI,YAAY,KAAK,IAAI,IAAI,SAAS,QAAQ,IAAI,0BAChD;CAEJ;CAEA,YAAY;CACZ,IAAI;EACF,MAAM,YAAY,CAAC,CAAC,aAAa,IAAI;CACvC,QAAQ,CAGR,UAAU;EACR,YAAY;CACd;AACF;;;;;AAMA,SAAgB,iBAAiB,aAAa,0BAAgC;CAC5E,IAAI,cACF;CAIF,aAAa,CAAC,CAAC,YAAY,CAAC,CAAC;CAG7B,eAAe,kBAAkB;EAC/B,aAAa,CAAC,CAAC,YAAY,CAAC,CAAC;CAC/B,GAAG,UAAU;CAGb,aAAa,MAAM;AACrB;;;;AAKA,SAAgB,kBAAwB;CACtC,IAAI,cAAc;EAChB,cAAc,YAAY;EAC1B,eAAe;CACjB;AACF"}
@@ -1,9 +1,10 @@
1
- import path from "node:path";
1
+ import path from "path";
2
+ //#region src/utils/path-security.ts
2
3
  function isPathWithinRoot(candidatePath, rootPath) {
3
- const relativePath = path.relative(rootPath, candidatePath);
4
- return relativePath === "" || !relativePath.startsWith(`..${path.sep}`) && relativePath !== ".." && !path.isAbsolute(relativePath);
4
+ const relativePath = path.relative(rootPath, candidatePath);
5
+ return relativePath === "" || !relativePath.startsWith(`..${path.sep}`) && relativePath !== ".." && !path.isAbsolute(relativePath);
5
6
  }
6
- export {
7
- isPathWithinRoot
8
- };
7
+ //#endregion
8
+ export { isPathWithinRoot };
9
+
9
10
  //# sourceMappingURL=path-security.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/path-security.ts"],"sourcesContent":["import path from 'node:path';\n\nexport function isPathWithinRoot(candidatePath: string, rootPath: string): boolean {\n const relativePath = path.relative(rootPath, candidatePath);\n return (\n relativePath === '' ||\n (!relativePath.startsWith(`..${path.sep}`) && relativePath !== '..' && !path.isAbsolute(relativePath))\n );\n}\n"],"mappings":"AAAA,OAAO,UAAU;AAEV,SAAS,iBAAiB,eAAuB,UAA2B;AACjF,QAAM,eAAe,KAAK,SAAS,UAAU,aAAa;AAC1D,SACE,iBAAiB,MAChB,CAAC,aAAa,WAAW,KAAK,KAAK,GAAG,EAAE,KAAK,iBAAiB,QAAQ,CAAC,KAAK,WAAW,YAAY;AAExG;","names":[]}
1
+ {"version":3,"file":"path-security.js","names":[],"sources":["../../src/utils/path-security.ts"],"sourcesContent":["import path from 'node:path';\n\nexport function isPathWithinRoot(candidatePath: string, rootPath: string): boolean {\n const relativePath = path.relative(rootPath, candidatePath);\n return (\n relativePath === '' ||\n (!relativePath.startsWith(`..${path.sep}`) && relativePath !== '..' && !path.isAbsolute(relativePath))\n );\n}\n"],"mappings":";;AAEA,SAAgB,iBAAiB,eAAuB,UAA2B;CACjF,MAAM,eAAe,KAAK,SAAS,UAAU,aAAa;CAC1D,OACE,iBAAiB,MAChB,CAAC,aAAa,WAAW,KAAK,KAAK,KAAK,KAAK,iBAAiB,QAAQ,CAAC,KAAK,WAAW,YAAY;AAExG"}