@mastra/cursor 0.3.0-alpha.0 → 0.3.1-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,1099 +1,897 @@
1
- 'use strict';
2
-
3
- var crypto = require('crypto');
4
- var web = require('stream/web');
5
- var sdk = require('@cursor/sdk');
6
- var agent = require('@mastra/core/agent');
7
- var requestContext = require('@mastra/core/request-context');
8
- var stream = require('@mastra/core/stream');
9
- var messageList = require('@mastra/core/agent/message-list');
10
- var observability = require('@mastra/core/observability');
11
-
12
- // src/index.ts
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ let crypto = require("crypto");
3
+ let stream_web = require("stream/web");
4
+ let _cursor_sdk = require("@cursor/sdk");
5
+ let _mastra_core_agent = require("@mastra/core/agent");
6
+ let _mastra_core_request_context = require("@mastra/core/request-context");
7
+ let _mastra_core_stream = require("@mastra/core/stream");
8
+ let _mastra_core_agent_message_list = require("@mastra/core/agent/message-list");
9
+ let _mastra_core_observability = require("@mastra/core/observability");
10
+ //#region src/utils.ts
13
11
  function createNoopModel({ modelId, provider }) {
14
- return {
15
- modelId,
16
- provider,
17
- specificationVersion: "v3",
18
- supportedUrls: {},
19
- doGenerate: async () => createNoopStreamResult(),
20
- doStream: async () => createNoopStreamResult()
21
- };
12
+ return {
13
+ modelId,
14
+ provider,
15
+ specificationVersion: "v3",
16
+ supportedUrls: {},
17
+ doGenerate: async () => createNoopStreamResult(),
18
+ doStream: async () => createNoopStreamResult()
19
+ };
22
20
  }
23
21
  function createNoopStreamResult() {
24
- return {
25
- stream: new web.ReadableStream({
26
- start: (controller) => controller.close()
27
- })
28
- };
29
- }
30
- function createCompletedMastraStream({
31
- runId,
32
- prompt,
33
- text,
34
- responseId,
35
- modelId,
36
- usage,
37
- providerMetadata,
38
- costContext,
39
- object
40
- }) {
41
- return new web.ReadableStream({
42
- start(controller) {
43
- const textId = crypto.randomUUID();
44
- enqueueStartChunks(controller, {
45
- runId,
46
- prompt,
47
- textId,
48
- responseId,
49
- modelId,
50
- providerMetadata
51
- });
52
- if (text) {
53
- enqueueTextDelta(controller, runId, textId, text);
54
- }
55
- enqueueFinishChunks(controller, {
56
- runId,
57
- prompt,
58
- textId,
59
- text,
60
- responseId,
61
- modelId,
62
- usage,
63
- providerMetadata,
64
- costContext,
65
- object
66
- });
67
- controller.close();
68
- }
69
- });
70
- }
71
- function createMastraOutput({
72
- messages,
73
- runId,
74
- modelId,
75
- provider,
76
- stream: stream$1,
77
- options
78
- }) {
79
- const messageList$1 = new messageList.MessageList();
80
- messageList$1.add(messages, "input");
81
- messageList$1.add([{ role: "assistant", content: "" }], "response");
82
- return new stream.MastraModelOutput({
83
- model: {
84
- modelId,
85
- provider,
86
- version: "v3"
87
- },
88
- stream: stream$1,
89
- messageList: messageList$1,
90
- messageId: crypto.randomUUID(),
91
- options: {
92
- ...options,
93
- runId
94
- }
95
- });
96
- }
97
- function toFullOutput({
98
- messages,
99
- runId,
100
- provider,
101
- result,
102
- options
103
- }) {
104
- const text = result.content.map((part) => part.text).join("");
105
- const stream = createCompletedMastraStream({
106
- runId,
107
- prompt: promptToText(messages),
108
- text,
109
- responseId: result.response.id,
110
- modelId: result.response.modelId,
111
- usage: toLanguageModelUsage(result.usage),
112
- providerMetadata: result.providerMetadata,
113
- costContext: result.costContext,
114
- object: result.object
115
- });
116
- return createMastraOutput({
117
- messages,
118
- runId,
119
- modelId: result.response.modelId,
120
- provider,
121
- stream,
122
- options
123
- }).getFullOutput();
124
- }
125
- function createSDKAgentTelemetry({
126
- agentId,
127
- agentName,
128
- provider,
129
- modelId,
130
- messages,
131
- prompt,
132
- runId,
133
- streaming,
134
- method,
135
- requestContext,
136
- instructions,
137
- maxSteps,
138
- tracingOptions,
139
- tracingContext,
140
- onFinish,
141
- onStepFinish,
142
- mastra
143
- }) {
144
- const agentSpan = observability.getOrCreateSpan({
145
- type: observability.SpanType.AGENT_RUN,
146
- name: `agent run: '${agentId}'`,
147
- entityType: observability.EntityType.AGENT,
148
- entityId: agentId,
149
- entityName: agentName,
150
- input: messages,
151
- attributes: {
152
- prompt,
153
- instructions,
154
- maxSteps
155
- },
156
- metadata: {
157
- runId,
158
- sdkAgent: true,
159
- sdkProvider: provider,
160
- sdkMethod: method
161
- },
162
- tracingOptions,
163
- tracingContext,
164
- requestContext,
165
- mastra
166
- });
167
- const modelSpan = agentSpan?.createChildSpan({
168
- type: observability.SpanType.MODEL_GENERATION,
169
- name: `llm: '${modelId}'`,
170
- input: {
171
- messages
172
- },
173
- attributes: {
174
- model: modelId,
175
- provider,
176
- streaming
177
- },
178
- metadata: {
179
- runId,
180
- sdkAgent: true,
181
- sdkProvider: provider,
182
- sdkMethod: method
183
- },
184
- requestContext
185
- });
186
- const modelSpanTracker = getModelSpanTracker(modelSpan);
187
- const toolSpans = /* @__PURE__ */ new Map();
188
- let ended = false;
189
- const startToolCall = ({ toolCallId, toolName, input }) => {
190
- if (toolSpans.has(toolCallId)) {
191
- return;
192
- }
193
- const parentSpan = agentSpan ?? modelSpan;
194
- if (!parentSpan) {
195
- return;
196
- }
197
- const mcp = parseMcpToolName(toolName);
198
- const span = mcp ? parentSpan.createChildSpan({
199
- type: observability.SpanType.MCP_TOOL_CALL,
200
- name: `mcp_tool: '${toolName}' on '${mcp.serverName}'`,
201
- input,
202
- entityType: observability.EntityType.TOOL,
203
- entityId: toolName,
204
- entityName: toolName,
205
- attributes: {
206
- mcpServer: mcp.serverName
207
- },
208
- metadata: {
209
- runId,
210
- sdkAgent: true,
211
- sdkProvider: provider,
212
- sdkMethod: method,
213
- toolCallId
214
- },
215
- requestContext
216
- }) : parentSpan.createChildSpan({
217
- type: observability.SpanType.TOOL_CALL,
218
- name: `tool: '${toolName}'`,
219
- input,
220
- entityType: observability.EntityType.TOOL,
221
- entityId: toolName,
222
- entityName: toolName,
223
- attributes: {
224
- toolType: "tool"
225
- },
226
- metadata: {
227
- runId,
228
- sdkAgent: true,
229
- sdkProvider: provider,
230
- sdkMethod: method,
231
- toolCallId
232
- },
233
- requestContext
234
- });
235
- toolSpans.set(toolCallId, span);
236
- };
237
- const endToolCall = ({ toolCallId, output, isError }) => {
238
- const span = toolSpans.get(toolCallId);
239
- if (!span) {
240
- return;
241
- }
242
- toolSpans.delete(toolCallId);
243
- if (isError) {
244
- span.error({
245
- error: output instanceof Error ? output : new Error(typeof output === "string" ? output : "SDK tool call failed"),
246
- attributes: { success: false }
247
- });
248
- return;
249
- }
250
- span.end({
251
- output,
252
- attributes: { success: true }
253
- });
254
- };
255
- const closeOpenToolSpans = (success, error) => {
256
- for (const [toolCallId, span] of toolSpans) {
257
- toolSpans.delete(toolCallId);
258
- if (success) {
259
- span.end({ attributes: { success: true } });
260
- continue;
261
- }
262
- const normalized = error instanceof Error ? error : new Error(String(error ?? "SDK agent run failed"));
263
- span.error({ error: normalized, attributes: { success: false } });
264
- }
265
- };
266
- const endModel = ({
267
- text,
268
- usage,
269
- providerMetadata,
270
- finishReason = "stop",
271
- responseId,
272
- responseModel,
273
- costContext
274
- }) => {
275
- if (modelSpanTracker) {
276
- modelSpanTracker.endGeneration({
277
- output: {
278
- text
279
- },
280
- attributes: {
281
- finishReason,
282
- responseId,
283
- responseModel,
284
- costContext
285
- },
286
- usage,
287
- providerMetadata
288
- });
289
- return;
290
- }
291
- modelSpan?.end({
292
- output: {
293
- text
294
- },
295
- attributes: {
296
- finishReason,
297
- responseId,
298
- responseModel,
299
- usage: usage ? toUsageStats(usage) : void 0,
300
- costContext
301
- }
302
- });
303
- };
304
- const end = (result) => {
305
- if (ended) {
306
- return;
307
- }
308
- ended = true;
309
- closeOpenToolSpans(true);
310
- endModel(result);
311
- agentSpan?.end({
312
- output: {
313
- text: result.text
314
- }
315
- });
316
- };
317
- const fail = (error) => {
318
- if (ended) {
319
- return;
320
- }
321
- ended = true;
322
- const normalized = error instanceof Error ? error : new Error(String(error));
323
- closeOpenToolSpans(false, normalized);
324
- if (modelSpanTracker) {
325
- modelSpanTracker.reportGenerationError({ error: normalized });
326
- } else {
327
- modelSpan?.error({ error: normalized });
328
- }
329
- agentSpan?.error({ error: normalized });
330
- };
331
- return {
332
- execute: (fn) => observability.executeWithContext({ span: modelSpan ?? agentSpan, fn }),
333
- endGenerate(result) {
334
- end({
335
- text: result.content.map((part) => part.text).join(""),
336
- usage: toLanguageModelUsage(result.usage),
337
- providerMetadata: result.providerMetadata,
338
- finishReason: result.finishReason.unified,
339
- responseId: result.response.id,
340
- responseModel: result.response.modelId,
341
- costContext: result.costContext
342
- });
343
- },
344
- fail,
345
- startToolCall,
346
- endToolCall,
347
- wrapStream(stream) {
348
- const trackedStream = modelSpanTracker?.wrapStream(stream) ?? stream;
349
- return wrapStreamForAgentSpan(trackedStream, {
350
- end,
351
- fail
352
- });
353
- },
354
- outputOptions() {
355
- return {
356
- onFinish,
357
- onStepFinish,
358
- requestContext,
359
- tracingContext: agentSpan ? { currentSpan: agentSpan } : tracingContext
360
- };
361
- }
362
- };
22
+ return { stream: new stream_web.ReadableStream({ start: (controller) => controller.close() }) };
23
+ }
24
+ function createCompletedMastraStream({ runId, prompt, text, responseId, modelId, usage, providerMetadata, costContext, object }) {
25
+ return new stream_web.ReadableStream({ start(controller) {
26
+ const textId = (0, crypto.randomUUID)();
27
+ enqueueStartChunks(controller, {
28
+ runId,
29
+ prompt,
30
+ textId,
31
+ responseId,
32
+ modelId,
33
+ providerMetadata
34
+ });
35
+ if (text) enqueueTextDelta(controller, runId, textId, text);
36
+ enqueueFinishChunks(controller, {
37
+ runId,
38
+ prompt,
39
+ textId,
40
+ text,
41
+ responseId,
42
+ modelId,
43
+ usage,
44
+ providerMetadata,
45
+ costContext,
46
+ object
47
+ });
48
+ controller.close();
49
+ } });
50
+ }
51
+ function createMastraOutput({ messages, runId, modelId, provider, stream, options }) {
52
+ const messageList = new _mastra_core_agent_message_list.MessageList();
53
+ messageList.add(messages, "input");
54
+ messageList.add([{
55
+ role: "assistant",
56
+ content: ""
57
+ }], "response");
58
+ return new _mastra_core_stream.MastraModelOutput({
59
+ model: {
60
+ modelId,
61
+ provider,
62
+ version: "v3"
63
+ },
64
+ stream,
65
+ messageList,
66
+ messageId: (0, crypto.randomUUID)(),
67
+ options: {
68
+ ...options,
69
+ runId
70
+ }
71
+ });
72
+ }
73
+ function toFullOutput({ messages, runId, provider, result, options }) {
74
+ const text = result.content.map((part) => part.text).join("");
75
+ const stream = createCompletedMastraStream({
76
+ runId,
77
+ prompt: promptToText(messages),
78
+ text,
79
+ responseId: result.response.id,
80
+ modelId: result.response.modelId,
81
+ usage: toLanguageModelUsage(result.usage),
82
+ providerMetadata: result.providerMetadata,
83
+ costContext: result.costContext,
84
+ object: result.object
85
+ });
86
+ return createMastraOutput({
87
+ messages,
88
+ runId,
89
+ modelId: result.response.modelId,
90
+ provider,
91
+ stream,
92
+ options
93
+ }).getFullOutput();
94
+ }
95
+ function createSDKAgentTelemetry({ agentId, agentName, provider, modelId, messages, prompt, runId, streaming, method, requestContext, instructions, maxSteps, tracingOptions, tracingContext, onFinish, onStepFinish, mastra }) {
96
+ const agentSpan = (0, _mastra_core_observability.getOrCreateSpan)({
97
+ type: _mastra_core_observability.SpanType.AGENT_RUN,
98
+ name: `agent run: '${agentId}'`,
99
+ entityType: _mastra_core_observability.EntityType.AGENT,
100
+ entityId: agentId,
101
+ entityName: agentName,
102
+ input: messages,
103
+ attributes: {
104
+ prompt,
105
+ instructions,
106
+ maxSteps
107
+ },
108
+ metadata: {
109
+ runId,
110
+ sdkAgent: true,
111
+ sdkProvider: provider,
112
+ sdkMethod: method
113
+ },
114
+ tracingOptions,
115
+ tracingContext,
116
+ requestContext,
117
+ mastra
118
+ });
119
+ const modelSpan = agentSpan?.createChildSpan({
120
+ type: _mastra_core_observability.SpanType.MODEL_GENERATION,
121
+ name: `llm: '${modelId}'`,
122
+ input: { messages },
123
+ attributes: {
124
+ model: modelId,
125
+ provider,
126
+ streaming
127
+ },
128
+ metadata: {
129
+ runId,
130
+ sdkAgent: true,
131
+ sdkProvider: provider,
132
+ sdkMethod: method
133
+ },
134
+ requestContext
135
+ });
136
+ const modelSpanTracker = getModelSpanTracker(modelSpan);
137
+ const toolSpans = /* @__PURE__ */ new Map();
138
+ let ended = false;
139
+ const startToolCall = ({ toolCallId, toolName, input }) => {
140
+ if (toolSpans.has(toolCallId)) return;
141
+ const parentSpan = agentSpan ?? modelSpan;
142
+ if (!parentSpan) return;
143
+ const mcp = parseMcpToolName(toolName);
144
+ const span = mcp ? parentSpan.createChildSpan({
145
+ type: _mastra_core_observability.SpanType.MCP_TOOL_CALL,
146
+ name: `mcp_tool: '${toolName}' on '${mcp.serverName}'`,
147
+ input,
148
+ entityType: _mastra_core_observability.EntityType.TOOL,
149
+ entityId: toolName,
150
+ entityName: toolName,
151
+ attributes: { mcpServer: mcp.serverName },
152
+ metadata: {
153
+ runId,
154
+ sdkAgent: true,
155
+ sdkProvider: provider,
156
+ sdkMethod: method,
157
+ toolCallId
158
+ },
159
+ requestContext
160
+ }) : parentSpan.createChildSpan({
161
+ type: _mastra_core_observability.SpanType.TOOL_CALL,
162
+ name: `tool: '${toolName}'`,
163
+ input,
164
+ entityType: _mastra_core_observability.EntityType.TOOL,
165
+ entityId: toolName,
166
+ entityName: toolName,
167
+ attributes: { toolType: "tool" },
168
+ metadata: {
169
+ runId,
170
+ sdkAgent: true,
171
+ sdkProvider: provider,
172
+ sdkMethod: method,
173
+ toolCallId
174
+ },
175
+ requestContext
176
+ });
177
+ toolSpans.set(toolCallId, span);
178
+ };
179
+ const endToolCall = ({ toolCallId, output, isError }) => {
180
+ const span = toolSpans.get(toolCallId);
181
+ if (!span) return;
182
+ toolSpans.delete(toolCallId);
183
+ if (isError) {
184
+ span.error({
185
+ error: output instanceof Error ? output : new Error(typeof output === "string" ? output : "SDK tool call failed"),
186
+ attributes: { success: false }
187
+ });
188
+ return;
189
+ }
190
+ span.end({
191
+ output,
192
+ attributes: { success: true }
193
+ });
194
+ };
195
+ const closeOpenToolSpans = (success, error) => {
196
+ for (const [toolCallId, span] of toolSpans) {
197
+ toolSpans.delete(toolCallId);
198
+ if (success) {
199
+ span.end({ attributes: { success: true } });
200
+ continue;
201
+ }
202
+ const normalized = error instanceof Error ? error : new Error(String(error ?? "SDK agent run failed"));
203
+ span.error({
204
+ error: normalized,
205
+ attributes: { success: false }
206
+ });
207
+ }
208
+ };
209
+ const endModel = ({ text, usage, providerMetadata, finishReason = "stop", responseId, responseModel, costContext }) => {
210
+ if (modelSpanTracker) {
211
+ modelSpanTracker.endGeneration({
212
+ output: { text },
213
+ attributes: {
214
+ finishReason,
215
+ responseId,
216
+ responseModel,
217
+ costContext
218
+ },
219
+ usage,
220
+ providerMetadata
221
+ });
222
+ return;
223
+ }
224
+ modelSpan?.end({
225
+ output: { text },
226
+ attributes: {
227
+ finishReason,
228
+ responseId,
229
+ responseModel,
230
+ usage: usage ? toUsageStats(usage) : void 0,
231
+ costContext
232
+ }
233
+ });
234
+ };
235
+ const end = (result) => {
236
+ if (ended) return;
237
+ ended = true;
238
+ closeOpenToolSpans(true);
239
+ endModel(result);
240
+ agentSpan?.end({ output: { text: result.text } });
241
+ };
242
+ const fail = (error) => {
243
+ if (ended) return;
244
+ ended = true;
245
+ const normalized = error instanceof Error ? error : new Error(String(error));
246
+ closeOpenToolSpans(false, normalized);
247
+ if (modelSpanTracker) modelSpanTracker.reportGenerationError({ error: normalized });
248
+ else modelSpan?.error({ error: normalized });
249
+ agentSpan?.error({ error: normalized });
250
+ };
251
+ return {
252
+ execute: (fn) => (0, _mastra_core_observability.executeWithContext)({
253
+ span: modelSpan ?? agentSpan,
254
+ fn
255
+ }),
256
+ endGenerate(result) {
257
+ end({
258
+ text: result.content.map((part) => part.text).join(""),
259
+ usage: toLanguageModelUsage(result.usage),
260
+ providerMetadata: result.providerMetadata,
261
+ finishReason: result.finishReason.unified,
262
+ responseId: result.response.id,
263
+ responseModel: result.response.modelId,
264
+ costContext: result.costContext
265
+ });
266
+ },
267
+ fail,
268
+ startToolCall,
269
+ endToolCall,
270
+ wrapStream(stream) {
271
+ return wrapStreamForAgentSpan(modelSpanTracker?.wrapStream(stream) ?? stream, {
272
+ end,
273
+ fail
274
+ });
275
+ },
276
+ outputOptions() {
277
+ return {
278
+ onFinish,
279
+ onStepFinish,
280
+ requestContext,
281
+ tracingContext: agentSpan ? { currentSpan: agentSpan } : tracingContext
282
+ };
283
+ }
284
+ };
363
285
  }
364
286
  function parseMcpToolName(toolName) {
365
- const match = /^mcp__([^_].*?)__(.+)$/.exec(toolName);
366
- if (!match?.[1] || !match[2]) {
367
- return void 0;
368
- }
369
- return {
370
- serverName: match[1],
371
- toolName: match[2]
372
- };
287
+ const match = /^mcp__([^_].*?)__(.+)$/.exec(toolName);
288
+ if (!match?.[1] || !match[2]) return;
289
+ return {
290
+ serverName: match[1],
291
+ toolName: match[2]
292
+ };
373
293
  }
374
294
  function getModelSpanTracker(modelSpan) {
375
- if (!modelSpan || !("createTracker" in modelSpan)) {
376
- return void 0;
377
- }
378
- return modelSpan.createTracker();
295
+ if (!modelSpan || !("createTracker" in modelSpan)) return;
296
+ return modelSpan.createTracker();
379
297
  }
380
298
  function wrapStreamForAgentSpan(stream, telemetry) {
381
- let text = "";
382
- return stream.pipeThrough(
383
- new web.TransformStream({
384
- transform(chunk, controller) {
385
- if (chunk.type === "text-delta") {
386
- text += chunk.payload.text;
387
- }
388
- if (chunk.type === "finish") {
389
- telemetry.end({
390
- text,
391
- usage: chunk.payload.output.usage,
392
- providerMetadata: chunk.payload.providerMetadata,
393
- finishReason: chunk.payload.stepResult.reason,
394
- responseId: chunk.payload.response?.id,
395
- responseModel: chunk.payload.response?.modelId,
396
- costContext: getCostContext(chunk.payload.metadata?.costContext)
397
- });
398
- }
399
- if (chunk.type === "error") {
400
- telemetry.fail(chunk.payload.error);
401
- }
402
- controller.enqueue(chunk);
403
- },
404
- flush() {
405
- telemetry.end({ text });
406
- }
407
- })
408
- );
299
+ let text = "";
300
+ return stream.pipeThrough(new stream_web.TransformStream({
301
+ transform(chunk, controller) {
302
+ if (chunk.type === "text-delta") text += chunk.payload.text;
303
+ if (chunk.type === "finish") telemetry.end({
304
+ text,
305
+ usage: chunk.payload.output.usage,
306
+ providerMetadata: chunk.payload.providerMetadata,
307
+ finishReason: chunk.payload.stepResult.reason,
308
+ responseId: chunk.payload.response?.id,
309
+ responseModel: chunk.payload.response?.modelId,
310
+ costContext: getCostContext(chunk.payload.metadata?.costContext)
311
+ });
312
+ if (chunk.type === "error") telemetry.fail(chunk.payload.error);
313
+ controller.enqueue(chunk);
314
+ },
315
+ flush() {
316
+ telemetry.end({ text });
317
+ }
318
+ }));
409
319
  }
410
320
  function toUsageStats(usage) {
411
- return {
412
- inputTokens: usage.inputTokens,
413
- outputTokens: usage.outputTokens,
414
- inputDetails: {
415
- cacheRead: usage.cachedInputTokens,
416
- cacheWrite: usage.cacheCreationInputTokens
417
- },
418
- outputDetails: {
419
- text: usage.outputTokens,
420
- reasoning: usage.reasoningTokens
421
- }
422
- };
321
+ return {
322
+ inputTokens: usage.inputTokens,
323
+ outputTokens: usage.outputTokens,
324
+ inputDetails: {
325
+ cacheRead: usage.cachedInputTokens,
326
+ cacheWrite: usage.cacheCreationInputTokens
327
+ },
328
+ outputDetails: {
329
+ text: usage.outputTokens,
330
+ reasoning: usage.reasoningTokens
331
+ }
332
+ };
423
333
  }
424
334
  function getCostContext(value) {
425
- if (!value || typeof value !== "object") {
426
- return void 0;
427
- }
428
- return value;
429
- }
430
- function enqueueStartChunks(controller, {
431
- runId,
432
- prompt,
433
- textId,
434
- responseId,
435
- modelId,
436
- providerMetadata
437
- }) {
438
- controller.enqueue({
439
- type: "start",
440
- runId,
441
- from: stream.ChunkFrom.AGENT,
442
- payload: {}
443
- });
444
- controller.enqueue({
445
- type: "step-start",
446
- runId,
447
- from: stream.ChunkFrom.AGENT,
448
- payload: {
449
- request: { body: prompt }
450
- }
451
- });
452
- controller.enqueue({
453
- type: "response-metadata",
454
- runId,
455
- from: stream.ChunkFrom.AGENT,
456
- payload: {
457
- id: responseId,
458
- modelId,
459
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
460
- }
461
- });
462
- controller.enqueue({
463
- type: "text-start",
464
- runId,
465
- from: stream.ChunkFrom.AGENT,
466
- payload: {
467
- id: textId,
468
- providerMetadata
469
- }
470
- });
335
+ if (!value || typeof value !== "object") return;
336
+ return value;
337
+ }
338
+ function enqueueStartChunks(controller, { runId, prompt, textId, responseId, modelId, providerMetadata }) {
339
+ controller.enqueue({
340
+ type: "start",
341
+ runId,
342
+ from: _mastra_core_stream.ChunkFrom.AGENT,
343
+ payload: {}
344
+ });
345
+ controller.enqueue({
346
+ type: "step-start",
347
+ runId,
348
+ from: _mastra_core_stream.ChunkFrom.AGENT,
349
+ payload: { request: { body: prompt } }
350
+ });
351
+ controller.enqueue({
352
+ type: "response-metadata",
353
+ runId,
354
+ from: _mastra_core_stream.ChunkFrom.AGENT,
355
+ payload: {
356
+ id: responseId,
357
+ modelId,
358
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
359
+ }
360
+ });
361
+ controller.enqueue({
362
+ type: "text-start",
363
+ runId,
364
+ from: _mastra_core_stream.ChunkFrom.AGENT,
365
+ payload: {
366
+ id: textId,
367
+ providerMetadata
368
+ }
369
+ });
471
370
  }
472
371
  function enqueueTextDelta(controller, runId, textId, text) {
473
- controller.enqueue({
474
- type: "text-delta",
475
- runId,
476
- from: stream.ChunkFrom.AGENT,
477
- payload: {
478
- id: textId,
479
- text
480
- }
481
- });
482
- }
483
- function enqueueFinishChunks(controller, {
484
- runId,
485
- prompt,
486
- textId,
487
- text,
488
- responseId,
489
- modelId,
490
- usage,
491
- providerMetadata,
492
- costContext,
493
- object
494
- }) {
495
- const timestamp = /* @__PURE__ */ new Date();
496
- const response = {
497
- id: responseId,
498
- modelId,
499
- timestamp
500
- };
501
- const metadata = {
502
- providerMetadata,
503
- costContext,
504
- request: { body: prompt },
505
- modelId,
506
- timestamp
507
- };
508
- controller.enqueue({
509
- type: "text-end",
510
- runId,
511
- from: stream.ChunkFrom.AGENT,
512
- payload: {
513
- id: textId,
514
- providerMetadata
515
- }
516
- });
517
- if (object !== void 0) {
518
- controller.enqueue({
519
- type: "object-result",
520
- runId,
521
- from: stream.ChunkFrom.AGENT,
522
- object
523
- });
524
- }
525
- controller.enqueue({
526
- type: "step-finish",
527
- runId,
528
- from: stream.ChunkFrom.AGENT,
529
- payload: {
530
- id: responseId,
531
- providerMetadata,
532
- totalUsage: usage,
533
- response,
534
- stepResult: {
535
- reason: "stop",
536
- warnings: []
537
- },
538
- output: {
539
- text,
540
- usage,
541
- steps: []
542
- },
543
- metadata
544
- }
545
- });
546
- controller.enqueue({
547
- type: "finish",
548
- runId,
549
- from: stream.ChunkFrom.AGENT,
550
- payload: {
551
- stepResult: {
552
- reason: "stop",
553
- warnings: []
554
- },
555
- output: {
556
- usage,
557
- steps: []
558
- },
559
- metadata,
560
- providerMetadata,
561
- messages: {
562
- all: [],
563
- user: [],
564
- nonUser: []
565
- },
566
- response
567
- }
568
- });
372
+ controller.enqueue({
373
+ type: "text-delta",
374
+ runId,
375
+ from: _mastra_core_stream.ChunkFrom.AGENT,
376
+ payload: {
377
+ id: textId,
378
+ text
379
+ }
380
+ });
381
+ }
382
+ function enqueueFinishChunks(controller, { runId, prompt, textId, text, responseId, modelId, usage, providerMetadata, costContext, object }) {
383
+ const timestamp = /* @__PURE__ */ new Date();
384
+ const response = {
385
+ id: responseId,
386
+ modelId,
387
+ timestamp
388
+ };
389
+ const metadata = {
390
+ providerMetadata,
391
+ costContext,
392
+ request: { body: prompt },
393
+ modelId,
394
+ timestamp
395
+ };
396
+ controller.enqueue({
397
+ type: "text-end",
398
+ runId,
399
+ from: _mastra_core_stream.ChunkFrom.AGENT,
400
+ payload: {
401
+ id: textId,
402
+ providerMetadata
403
+ }
404
+ });
405
+ if (object !== void 0) controller.enqueue({
406
+ type: "object-result",
407
+ runId,
408
+ from: _mastra_core_stream.ChunkFrom.AGENT,
409
+ object
410
+ });
411
+ controller.enqueue({
412
+ type: "step-finish",
413
+ runId,
414
+ from: _mastra_core_stream.ChunkFrom.AGENT,
415
+ payload: {
416
+ id: responseId,
417
+ providerMetadata,
418
+ totalUsage: usage,
419
+ response,
420
+ stepResult: {
421
+ reason: "stop",
422
+ warnings: []
423
+ },
424
+ output: {
425
+ text,
426
+ usage,
427
+ steps: []
428
+ },
429
+ metadata
430
+ }
431
+ });
432
+ controller.enqueue({
433
+ type: "finish",
434
+ runId,
435
+ from: _mastra_core_stream.ChunkFrom.AGENT,
436
+ payload: {
437
+ stepResult: {
438
+ reason: "stop",
439
+ warnings: []
440
+ },
441
+ output: {
442
+ usage,
443
+ steps: []
444
+ },
445
+ metadata,
446
+ providerMetadata,
447
+ messages: {
448
+ all: [],
449
+ user: [],
450
+ nonUser: []
451
+ },
452
+ response
453
+ }
454
+ });
569
455
  }
570
456
  function toLanguageModelUsage(usage) {
571
- const inputTokens = usage.inputTokens.total ?? 0;
572
- const outputTokens = usage.outputTokens.total ?? 0;
573
- return {
574
- inputTokens,
575
- outputTokens,
576
- totalTokens: inputTokens + outputTokens,
577
- cachedInputTokens: usage.inputTokens.cacheRead,
578
- cacheCreationInputTokens: usage.inputTokens.cacheWrite,
579
- raw: usage
580
- };
457
+ const inputTokens = usage.inputTokens.total ?? 0;
458
+ const outputTokens = usage.outputTokens.total ?? 0;
459
+ return {
460
+ inputTokens,
461
+ outputTokens,
462
+ totalTokens: inputTokens + outputTokens,
463
+ cachedInputTokens: usage.inputTokens.cacheRead,
464
+ cacheCreationInputTokens: usage.inputTokens.cacheWrite,
465
+ raw: usage
466
+ };
581
467
  }
582
468
  function createProviderMetadata(provider, metadata) {
583
- return {
584
- [provider]: toJsonRecord(metadata)
585
- };
469
+ return { [provider]: toJsonRecord(metadata) };
586
470
  }
587
471
  function toJsonRecord(record) {
588
- return Object.fromEntries(
589
- Object.entries(record).filter((entry) => entry[1] !== void 0).map(([key, value]) => [key, toJsonValue(value)])
590
- );
472
+ return Object.fromEntries(Object.entries(record).filter((entry) => entry[1] !== void 0).map(([key, value]) => [key, toJsonValue(value)]));
591
473
  }
592
474
  function toJsonValue(value) {
593
- if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
594
- return value;
595
- }
596
- if (Array.isArray(value)) {
597
- return value.filter((item) => item !== void 0).map(toJsonValue);
598
- }
599
- if (value instanceof Date) {
600
- return value.toISOString();
601
- }
602
- if (typeof value === "object") {
603
- return toJsonRecord(value);
604
- }
605
- return String(value);
475
+ if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
476
+ if (Array.isArray(value)) return value.filter((item) => item !== void 0).map(toJsonValue);
477
+ if (value instanceof Date) return value.toISOString();
478
+ if (typeof value === "object") return toJsonRecord(value);
479
+ return String(value);
606
480
  }
607
481
  function promptToText(prompt) {
608
- if (typeof prompt === "string") {
609
- return prompt;
610
- }
611
- if (Array.isArray(prompt)) {
612
- return prompt.map(promptToText).filter(Boolean).join("\n");
613
- }
614
- if (!prompt || typeof prompt !== "object") {
615
- return "";
616
- }
617
- const record = prompt;
618
- if (typeof record.text === "string") {
619
- return record.text;
620
- }
621
- if (typeof record.content === "string") {
622
- return record.content;
623
- }
624
- if (record.content) {
625
- return promptToText(record.content);
626
- }
627
- return "";
482
+ if (typeof prompt === "string") return prompt;
483
+ if (Array.isArray(prompt)) return prompt.map(promptToText).filter(Boolean).join("\n");
484
+ if (!prompt || typeof prompt !== "object") return "";
485
+ const record = prompt;
486
+ if (typeof record.text === "string") return record.text;
487
+ if (typeof record.content === "string") return record.content;
488
+ if (record.content) return promptToText(record.content);
489
+ return "";
628
490
  }
629
491
  function sumDefined(...values) {
630
- const defined = values.filter((value) => typeof value === "number");
631
- if (defined.length === 0) {
632
- return void 0;
633
- }
634
- return defined.reduce((sum, value) => sum + value, 0);
635
- }
636
-
637
- // src/index.ts
638
- var PROVIDER = "@cursor/sdk";
639
- var MODEL_ID = "cursor-agent-sdk";
640
- var CursorSDKAgent = class extends agent.Agent {
641
- options;
642
- #mastra;
643
- #createdAgent;
644
- constructor(options) {
645
- super({
646
- id: options.id,
647
- name: options.name ?? options.id,
648
- description: options.description,
649
- instructions: "",
650
- model: createNoopModel({
651
- modelId: getModelId(getRequestedModel(options)),
652
- provider: PROVIDER
653
- })
654
- });
655
- this.options = options;
656
- }
657
- __registerMastra(mastra) {
658
- super.__registerMastra(mastra);
659
- this.#mastra = mastra;
660
- }
661
- supportsMemory() {
662
- return false;
663
- }
664
- async generate(messages, options) {
665
- assertStructuredOutputUnsupported(options);
666
- const sdkAgent = await this.resolveCursorAgent();
667
- return this.generateWithAgent(messages, sdkAgent, options);
668
- }
669
- async generateWithAgent(messages, sdkAgent, options) {
670
- const prompt = promptToText(messages);
671
- const runId = options?.runId ?? crypto.randomUUID();
672
- const modelId = getCursorModelId(this.options, sdkAgent);
673
- const requestContext$1 = options?.requestContext ?? new requestContext.RequestContext();
674
- const instructions = options?.instructions ? promptToText(options.instructions) : void 0;
675
- const telemetry = createSDKAgentTelemetry({
676
- agentId: this.id,
677
- agentName: this.name,
678
- provider: PROVIDER,
679
- modelId,
680
- messages,
681
- prompt,
682
- runId,
683
- streaming: false,
684
- method: "generate",
685
- requestContext: requestContext$1,
686
- instructions,
687
- maxSteps: options?.maxSteps,
688
- tracingOptions: options?.tracingOptions,
689
- tracingContext: options?.tracingContext,
690
- onFinish: options?.onFinish,
691
- onStepFinish: options?.onStepFinish,
692
- mastra: this.#mastra
693
- });
694
- let result;
695
- try {
696
- result = await telemetry.execute(() => runCursorGenerate(prompt, this.options, sdkAgent, telemetry));
697
- telemetry.endGenerate(result);
698
- } catch (error) {
699
- telemetry.fail(error);
700
- throw error;
701
- }
702
- return toFullOutput({
703
- messages,
704
- runId,
705
- provider: PROVIDER,
706
- result,
707
- options: telemetry.outputOptions()
708
- });
709
- }
710
- async stream(messages, options) {
711
- assertStructuredOutputUnsupported(options);
712
- const sdkAgent = await this.resolveCursorAgent();
713
- return this.streamWithAgent(messages, sdkAgent, options);
714
- }
715
- async streamWithAgent(messages, sdkAgent, options) {
716
- const runId = options?.runId ?? crypto.randomUUID();
717
- const prompt = promptToText(messages);
718
- const modelId = getCursorModelId(this.options, sdkAgent);
719
- const requestContext$1 = options?.requestContext ?? new requestContext.RequestContext();
720
- const instructions = options?.instructions ? promptToText(options.instructions) : void 0;
721
- const telemetry = createSDKAgentTelemetry({
722
- agentId: this.id,
723
- agentName: this.name,
724
- provider: PROVIDER,
725
- modelId,
726
- messages,
727
- prompt,
728
- runId,
729
- streaming: true,
730
- method: "stream",
731
- requestContext: requestContext$1,
732
- instructions,
733
- maxSteps: options?.maxSteps,
734
- tracingOptions: options?.tracingOptions,
735
- tracingContext: options?.tracingContext,
736
- onFinish: options?.onFinish,
737
- onStepFinish: options?.onStepFinish,
738
- mastra: this.#mastra
739
- });
740
- return createMastraOutput({
741
- messages,
742
- runId,
743
- modelId,
744
- provider: PROVIDER,
745
- stream: telemetry.wrapStream(runCursorAsMastraStream(prompt, this.options, sdkAgent, runId, telemetry)),
746
- options: telemetry.outputOptions()
747
- });
748
- }
749
- async resumeGenerate(resumeData, options) {
750
- assertStructuredOutputUnsupported(options);
751
- const data = validateCursorResumeData(resumeData);
752
- const sdkAgent = await this.resolveResumeCursorAgent(data);
753
- return this.generateWithAgent(data.message, sdkAgent, options);
754
- }
755
- async resumeStream(resumeData, options) {
756
- assertStructuredOutputUnsupported(options);
757
- const data = validateCursorResumeData(resumeData);
758
- const sdkAgent = await this.resolveResumeCursorAgent(data);
759
- return this.streamWithAgent(data.message, sdkAgent, options);
760
- }
761
- resolveCursorAgent() {
762
- this.#createdAgent ??= resolveCursorAgent(this.options.agent, this.options).catch((error) => {
763
- this.#createdAgent = void 0;
764
- throw error;
765
- });
766
- return this.#createdAgent;
767
- }
768
- async resolveResumeCursorAgent(resumeData) {
769
- if (!resumeData.agentId) {
770
- return this.resolveCursorAgent();
771
- }
772
- return sdk.Agent.resume(resumeData.agentId, {
773
- ...toCursorCreateOptions(this.options),
774
- ...resumeData.sdkOptions
775
- });
776
- }
492
+ const defined = values.filter((value) => typeof value === "number");
493
+ if (defined.length === 0) return;
494
+ return defined.reduce((sum, value) => sum + value, 0);
495
+ }
496
+ //#endregion
497
+ //#region src/index.ts
498
+ const PROVIDER = "@cursor/sdk";
499
+ const MODEL_ID = "cursor-agent-sdk";
500
+ var CursorSDKAgent = class extends _mastra_core_agent.Agent {
501
+ options;
502
+ #mastra;
503
+ #createdAgent;
504
+ constructor(options) {
505
+ super({
506
+ id: options.id,
507
+ name: options.name ?? options.id,
508
+ description: options.description,
509
+ instructions: "",
510
+ model: createNoopModel({
511
+ modelId: getModelId(getRequestedModel(options)),
512
+ provider: PROVIDER
513
+ })
514
+ });
515
+ this.options = options;
516
+ }
517
+ __registerMastra(mastra) {
518
+ super.__registerMastra(mastra);
519
+ this.#mastra = mastra;
520
+ }
521
+ supportsMemory() {
522
+ return false;
523
+ }
524
+ async generate(messages, options) {
525
+ assertStructuredOutputUnsupported(options);
526
+ const sdkAgent = await this.resolveCursorAgent();
527
+ return this.generateWithAgent(messages, sdkAgent, options);
528
+ }
529
+ async generateWithAgent(messages, sdkAgent, options) {
530
+ const prompt = promptToText(messages);
531
+ const runId = options?.runId ?? (0, crypto.randomUUID)();
532
+ const modelId = getCursorModelId(this.options, sdkAgent);
533
+ const requestContext = options?.requestContext ?? new _mastra_core_request_context.RequestContext();
534
+ const instructions = options?.instructions ? promptToText(options.instructions) : void 0;
535
+ const telemetry = createSDKAgentTelemetry({
536
+ agentId: this.id,
537
+ agentName: this.name,
538
+ provider: PROVIDER,
539
+ modelId,
540
+ messages,
541
+ prompt,
542
+ runId,
543
+ streaming: false,
544
+ method: "generate",
545
+ requestContext,
546
+ instructions,
547
+ maxSteps: options?.maxSteps,
548
+ tracingOptions: options?.tracingOptions,
549
+ tracingContext: options?.tracingContext,
550
+ onFinish: options?.onFinish,
551
+ onStepFinish: options?.onStepFinish,
552
+ mastra: this.#mastra
553
+ });
554
+ let result;
555
+ try {
556
+ result = await telemetry.execute(() => runCursorGenerate(prompt, this.options, sdkAgent, telemetry));
557
+ telemetry.endGenerate(result);
558
+ } catch (error) {
559
+ telemetry.fail(error);
560
+ throw error;
561
+ }
562
+ return toFullOutput({
563
+ messages,
564
+ runId,
565
+ provider: PROVIDER,
566
+ result,
567
+ options: telemetry.outputOptions()
568
+ });
569
+ }
570
+ async stream(messages, options) {
571
+ assertStructuredOutputUnsupported(options);
572
+ const sdkAgent = await this.resolveCursorAgent();
573
+ return this.streamWithAgent(messages, sdkAgent, options);
574
+ }
575
+ async streamWithAgent(messages, sdkAgent, options) {
576
+ const runId = options?.runId ?? (0, crypto.randomUUID)();
577
+ const prompt = promptToText(messages);
578
+ const modelId = getCursorModelId(this.options, sdkAgent);
579
+ const requestContext = options?.requestContext ?? new _mastra_core_request_context.RequestContext();
580
+ const instructions = options?.instructions ? promptToText(options.instructions) : void 0;
581
+ const telemetry = createSDKAgentTelemetry({
582
+ agentId: this.id,
583
+ agentName: this.name,
584
+ provider: PROVIDER,
585
+ modelId,
586
+ messages,
587
+ prompt,
588
+ runId,
589
+ streaming: true,
590
+ method: "stream",
591
+ requestContext,
592
+ instructions,
593
+ maxSteps: options?.maxSteps,
594
+ tracingOptions: options?.tracingOptions,
595
+ tracingContext: options?.tracingContext,
596
+ onFinish: options?.onFinish,
597
+ onStepFinish: options?.onStepFinish,
598
+ mastra: this.#mastra
599
+ });
600
+ return createMastraOutput({
601
+ messages,
602
+ runId,
603
+ modelId,
604
+ provider: PROVIDER,
605
+ stream: telemetry.wrapStream(runCursorAsMastraStream(prompt, this.options, sdkAgent, runId, telemetry)),
606
+ options: telemetry.outputOptions()
607
+ });
608
+ }
609
+ async resumeGenerate(resumeData, options) {
610
+ assertStructuredOutputUnsupported(options);
611
+ const data = validateCursorResumeData(resumeData);
612
+ const sdkAgent = await this.resolveResumeCursorAgent(data);
613
+ return this.generateWithAgent(data.message, sdkAgent, options);
614
+ }
615
+ async resumeStream(resumeData, options) {
616
+ assertStructuredOutputUnsupported(options);
617
+ const data = validateCursorResumeData(resumeData);
618
+ const sdkAgent = await this.resolveResumeCursorAgent(data);
619
+ return this.streamWithAgent(data.message, sdkAgent, options);
620
+ }
621
+ resolveCursorAgent() {
622
+ this.#createdAgent ??= resolveCursorAgent(this.options.agent, this.options).catch((error) => {
623
+ this.#createdAgent = void 0;
624
+ throw error;
625
+ });
626
+ return this.#createdAgent;
627
+ }
628
+ async resolveResumeCursorAgent(resumeData) {
629
+ if (!resumeData.agentId) return this.resolveCursorAgent();
630
+ return _cursor_sdk.Agent.resume(resumeData.agentId, {
631
+ ...toCursorCreateOptions(this.options),
632
+ ...resumeData.sdkOptions
633
+ });
634
+ }
777
635
  };
778
636
  function validateCursorResumeData(resumeData) {
779
- if (!toRecord(resumeData) || !("message" in resumeData)) {
780
- throw new Error("CursorSDKAgent resumeData must include a message.");
781
- }
782
- if (resumeData.agentId !== void 0 && typeof resumeData.agentId !== "string") {
783
- throw new Error("CursorSDKAgent resumeData.agentId must be a string when provided.");
784
- }
785
- return resumeData;
637
+ if (!toRecord(resumeData) || !("message" in resumeData)) throw new Error("CursorSDKAgent resumeData must include a message.");
638
+ if (resumeData.agentId !== void 0 && typeof resumeData.agentId !== "string") throw new Error("CursorSDKAgent resumeData.agentId must be a string when provided.");
639
+ return resumeData;
786
640
  }
787
641
  function assertStructuredOutputUnsupported(options) {
788
- const structuredOutput = toRecord(toRecord(options)?.structuredOutput);
789
- if (structuredOutput && "schema" in structuredOutput) {
790
- throw new Error(
791
- "CursorSDKAgent does not support structuredOutput because the Cursor TypeScript SDK does not expose a schema-constrained output API."
792
- );
793
- }
642
+ const structuredOutput = toRecord(toRecord(options)?.structuredOutput);
643
+ if (structuredOutput && "schema" in structuredOutput) throw new Error("CursorSDKAgent does not support structuredOutput because the Cursor TypeScript SDK does not expose a schema-constrained output API.");
794
644
  }
795
645
  async function runCursorGenerate(prompt, options, agent, telemetry) {
796
- const usage = createCursorUsageCollector();
797
- const run = await agent.send(prompt, createCursorSendOptions(options, usage, telemetry));
798
- const result = await run.wait();
799
- if (result.status === "error" || result.status === "cancelled") {
800
- throw new Error(`Cursor run ${result.id} ended with status ${result.status}`);
801
- }
802
- const responseModel = getModelId(result.model ?? run.model ?? getRequestedModel(options) ?? agent.model);
803
- const providerMetadata = getCursorProviderMetadata(
804
- options,
805
- agent.agentId,
806
- result.id,
807
- result.status,
808
- result.durationMs,
809
- usage.totals(),
810
- responseModel
811
- );
812
- return {
813
- content: [{ type: "text", text: result.result ?? "" }],
814
- finishReason: { unified: "stop", raw: "stop" },
815
- usage: usage.toV3Usage(),
816
- response: {
817
- id: result.id,
818
- modelId: responseModel,
819
- timestamp: /* @__PURE__ */ new Date()
820
- },
821
- providerMetadata
822
- };
646
+ const usage = createCursorUsageCollector();
647
+ const run = await agent.send(prompt, createCursorSendOptions(options, usage, telemetry));
648
+ const result = await run.wait();
649
+ if (result.status === "error" || result.status === "cancelled") throw new Error(`Cursor run ${result.id} ended with status ${result.status}`);
650
+ const responseModel = getModelId(result.model ?? run.model ?? getRequestedModel(options) ?? agent.model);
651
+ const providerMetadata = getCursorProviderMetadata(options, agent.agentId, result.id, result.status, result.durationMs, usage.totals(), responseModel);
652
+ return {
653
+ content: [{
654
+ type: "text",
655
+ text: result.result ?? ""
656
+ }],
657
+ finishReason: {
658
+ unified: "stop",
659
+ raw: "stop"
660
+ },
661
+ usage: usage.toV3Usage(),
662
+ response: {
663
+ id: result.id,
664
+ modelId: responseModel,
665
+ timestamp: /* @__PURE__ */ new Date()
666
+ },
667
+ providerMetadata
668
+ };
823
669
  }
824
670
  function runCursorAsMastraStream(prompt, options, agent, runId, telemetry) {
825
- return new web.ReadableStream({
826
- start: async (controller) => {
827
- const textId = crypto.randomUUID();
828
- const usage = createCursorUsageCollector();
829
- let text = "";
830
- try {
831
- const run = await agent.send(prompt, createCursorSendOptions(options, usage, telemetry));
832
- const responseId = run.id;
833
- const responseModel = getModelId(run.model ?? getRequestedModel(options) ?? agent.model);
834
- enqueueStartChunks(controller, {
835
- runId,
836
- prompt,
837
- textId,
838
- responseId,
839
- modelId: responseModel,
840
- providerMetadata: getCursorProviderMetadata(
841
- options,
842
- agent.agentId,
843
- run.id,
844
- run.status,
845
- run.durationMs,
846
- usage.totals(),
847
- responseModel
848
- )
849
- });
850
- let result;
851
- if (run.supports("stream")) {
852
- for await (const message of run.stream()) {
853
- const delta = getTextFromCursorMessage(message);
854
- if (delta) {
855
- text += delta;
856
- enqueueTextDelta(controller, runId, textId, delta);
857
- }
858
- }
859
- result = await run.wait();
860
- } else {
861
- result = await run.wait();
862
- if (result.status === "error" || result.status === "cancelled") {
863
- throw new Error(`Cursor run ${result.id} ended with status ${result.status}`);
864
- }
865
- if (result.result) {
866
- text += result.result;
867
- enqueueTextDelta(controller, runId, textId, result.result);
868
- }
869
- }
870
- if (result.status === "error" || result.status === "cancelled") {
871
- throw new Error(`Cursor run ${result.id} ended with status ${result.status}`);
872
- }
873
- if (!text && result.result) {
874
- text = result.result;
875
- enqueueTextDelta(controller, runId, textId, result.result);
876
- }
877
- const providerMetadata = getCursorProviderMetadata(
878
- options,
879
- agent.agentId,
880
- run.id,
881
- result.status,
882
- result.durationMs,
883
- usage.totals(),
884
- getModelId(result.model ?? run.model ?? getRequestedModel(options) ?? agent.model)
885
- );
886
- enqueueFinishChunks(controller, {
887
- runId,
888
- prompt,
889
- textId,
890
- text,
891
- responseId,
892
- modelId: getModelId(result.model ?? run.model ?? getRequestedModel(options) ?? agent.model),
893
- usage: usage.toLanguageModelUsage(),
894
- providerMetadata
895
- });
896
- controller.close();
897
- } catch (error) {
898
- controller.enqueue({
899
- type: "error",
900
- runId,
901
- from: stream.ChunkFrom.AGENT,
902
- payload: { error }
903
- });
904
- controller.close();
905
- }
906
- }
907
- });
671
+ return new stream_web.ReadableStream({ start: async (controller) => {
672
+ const textId = (0, crypto.randomUUID)();
673
+ const usage = createCursorUsageCollector();
674
+ let text = "";
675
+ try {
676
+ const run = await agent.send(prompt, createCursorSendOptions(options, usage, telemetry));
677
+ const responseId = run.id;
678
+ const responseModel = getModelId(run.model ?? getRequestedModel(options) ?? agent.model);
679
+ enqueueStartChunks(controller, {
680
+ runId,
681
+ prompt,
682
+ textId,
683
+ responseId,
684
+ modelId: responseModel,
685
+ providerMetadata: getCursorProviderMetadata(options, agent.agentId, run.id, run.status, run.durationMs, usage.totals(), responseModel)
686
+ });
687
+ let result;
688
+ if (run.supports("stream")) {
689
+ for await (const message of run.stream()) {
690
+ const delta = getTextFromCursorMessage(message);
691
+ if (delta) {
692
+ text += delta;
693
+ enqueueTextDelta(controller, runId, textId, delta);
694
+ }
695
+ }
696
+ result = await run.wait();
697
+ } else {
698
+ result = await run.wait();
699
+ if (result.status === "error" || result.status === "cancelled") throw new Error(`Cursor run ${result.id} ended with status ${result.status}`);
700
+ if (result.result) {
701
+ text += result.result;
702
+ enqueueTextDelta(controller, runId, textId, result.result);
703
+ }
704
+ }
705
+ if (result.status === "error" || result.status === "cancelled") throw new Error(`Cursor run ${result.id} ended with status ${result.status}`);
706
+ if (!text && result.result) {
707
+ text = result.result;
708
+ enqueueTextDelta(controller, runId, textId, result.result);
709
+ }
710
+ const providerMetadata = getCursorProviderMetadata(options, agent.agentId, run.id, result.status, result.durationMs, usage.totals(), getModelId(result.model ?? run.model ?? getRequestedModel(options) ?? agent.model));
711
+ enqueueFinishChunks(controller, {
712
+ runId,
713
+ prompt,
714
+ textId,
715
+ text,
716
+ responseId,
717
+ modelId: getModelId(result.model ?? run.model ?? getRequestedModel(options) ?? agent.model),
718
+ usage: usage.toLanguageModelUsage(),
719
+ providerMetadata
720
+ });
721
+ controller.close();
722
+ } catch (error) {
723
+ controller.enqueue({
724
+ type: "error",
725
+ runId,
726
+ from: _mastra_core_stream.ChunkFrom.AGENT,
727
+ payload: { error }
728
+ });
729
+ controller.close();
730
+ }
731
+ } });
908
732
  }
909
733
  async function resolveCursorAgent(agent, options) {
910
- if (!agent) {
911
- return sdk.Agent.create(toCursorCreateOptions(options));
912
- }
913
- return typeof agent === "function" ? agent(toCursorCreateOptions(options)) : agent;
734
+ if (!agent) return _cursor_sdk.Agent.create(toCursorCreateOptions(options));
735
+ return typeof agent === "function" ? agent(toCursorCreateOptions(options)) : agent;
914
736
  }
915
737
  function toCursorCreateOptions(options) {
916
- const createOptions = { ...options.sdkOptions };
917
- const apiKey = createOptions.apiKey ?? process.env["CURSOR_API_KEY"];
918
- if (apiKey) createOptions.apiKey = apiKey;
919
- if (options.name && !createOptions.name) createOptions.name = options.name;
920
- return createOptions;
738
+ const createOptions = { ...options.sdkOptions };
739
+ const apiKey = createOptions.apiKey ?? process.env["CURSOR_API_KEY"];
740
+ if (apiKey) createOptions.apiKey = apiKey;
741
+ if (options.name && !createOptions.name) createOptions.name = options.name;
742
+ return createOptions;
921
743
  }
922
744
  function createCursorSendOptions(options, usage, telemetry) {
923
- return {
924
- mcpServers: options.sdkOptions?.mcpServers,
925
- onDelta: async (args) => {
926
- usage.record(args.update);
927
- recordCursorToolTelemetry(args.update, telemetry);
928
- }
929
- };
745
+ return {
746
+ mcpServers: options.sdkOptions?.mcpServers,
747
+ onDelta: async (args) => {
748
+ usage.record(args.update);
749
+ recordCursorToolTelemetry(args.update, telemetry);
750
+ }
751
+ };
930
752
  }
931
753
  function createCursorUsageCollector() {
932
- const totals = {
933
- inputTokens: 0,
934
- outputTokens: 0,
935
- cacheReadTokens: 0,
936
- cacheWriteTokens: 0
937
- };
938
- return {
939
- record(update) {
940
- if (update.type !== "turn-ended" || !update.usage) {
941
- return;
942
- }
943
- totals.inputTokens += update.usage.inputTokens;
944
- totals.outputTokens += update.usage.outputTokens;
945
- totals.cacheReadTokens += update.usage.cacheReadTokens;
946
- totals.cacheWriteTokens += update.usage.cacheWriteTokens;
947
- },
948
- totals() {
949
- return {
950
- inputTokens: totals.inputTokens || void 0,
951
- outputTokens: totals.outputTokens || void 0,
952
- cacheReadTokens: totals.cacheReadTokens || void 0,
953
- cacheWriteTokens: totals.cacheWriteTokens || void 0
954
- };
955
- },
956
- toV3Usage() {
957
- return toV3Usage(totals);
958
- },
959
- toLanguageModelUsage() {
960
- return toLanguageModelUsage(toV3Usage(totals));
961
- }
962
- };
754
+ const totals = {
755
+ inputTokens: 0,
756
+ outputTokens: 0,
757
+ cacheReadTokens: 0,
758
+ cacheWriteTokens: 0
759
+ };
760
+ return {
761
+ record(update) {
762
+ if (update.type !== "turn-ended" || !update.usage) return;
763
+ totals.inputTokens += update.usage.inputTokens;
764
+ totals.outputTokens += update.usage.outputTokens;
765
+ totals.cacheReadTokens += update.usage.cacheReadTokens;
766
+ totals.cacheWriteTokens += update.usage.cacheWriteTokens;
767
+ },
768
+ totals() {
769
+ return {
770
+ inputTokens: totals.inputTokens || void 0,
771
+ outputTokens: totals.outputTokens || void 0,
772
+ cacheReadTokens: totals.cacheReadTokens || void 0,
773
+ cacheWriteTokens: totals.cacheWriteTokens || void 0
774
+ };
775
+ },
776
+ toV3Usage() {
777
+ return toV3Usage(totals);
778
+ },
779
+ toLanguageModelUsage() {
780
+ return toLanguageModelUsage(toV3Usage(totals));
781
+ }
782
+ };
963
783
  }
964
784
  function toV3Usage(usage) {
965
- const noCache = usage.inputTokens;
966
- const cacheRead = usage.cacheReadTokens;
967
- const cacheWrite = usage.cacheWriteTokens;
968
- const totalInputTokens = sumDefined(noCache, cacheRead, cacheWrite);
969
- const outputTokens = usage.outputTokens;
970
- return {
971
- inputTokens: {
972
- total: totalInputTokens,
973
- noCache,
974
- cacheRead,
975
- cacheWrite
976
- },
977
- outputTokens: {
978
- total: outputTokens,
979
- text: outputTokens
980
- }
981
- };
785
+ const noCache = usage.inputTokens;
786
+ const cacheRead = usage.cacheReadTokens;
787
+ const cacheWrite = usage.cacheWriteTokens;
788
+ const totalInputTokens = sumDefined(noCache, cacheRead, cacheWrite);
789
+ const outputTokens = usage.outputTokens;
790
+ return {
791
+ inputTokens: {
792
+ total: totalInputTokens,
793
+ noCache,
794
+ cacheRead,
795
+ cacheWrite
796
+ },
797
+ outputTokens: {
798
+ total: outputTokens,
799
+ text: outputTokens
800
+ }
801
+ };
982
802
  }
983
803
  function getRequestedModel(options) {
984
- return options.sdkOptions?.model;
804
+ return options.sdkOptions?.model;
985
805
  }
986
806
  function getModelId(model) {
987
- if (!model) {
988
- return MODEL_ID;
989
- }
990
- return typeof model === "string" ? model : model.id;
807
+ if (!model) return MODEL_ID;
808
+ return typeof model === "string" ? model : model.id;
991
809
  }
992
810
  function getCursorModelId(options, agent) {
993
- return getModelId(getRequestedModel(options) ?? agent.model);
811
+ return getModelId(getRequestedModel(options) ?? agent.model);
994
812
  }
995
813
  function getCursorProviderMetadata(options, agentId, runId, status, durationMs, usage, requestedModel) {
996
- return createProviderMetadata("cursor", {
997
- agentId,
998
- runId,
999
- status,
1000
- requestedModel: requestedModel ?? getModelId(getRequestedModel(options)),
1001
- durationMs,
1002
- mcpServerNames: getMcpServerNames(options),
1003
- usage
1004
- });
814
+ return createProviderMetadata("cursor", {
815
+ agentId,
816
+ runId,
817
+ status,
818
+ requestedModel: requestedModel ?? getModelId(getRequestedModel(options)),
819
+ durationMs,
820
+ mcpServerNames: getMcpServerNames(options),
821
+ usage
822
+ });
1005
823
  }
1006
824
  function getMcpServerNames(options) {
1007
- const servers = options.sdkOptions?.mcpServers;
1008
- return servers ? Object.keys(servers) : void 0;
825
+ const servers = options.sdkOptions?.mcpServers;
826
+ return servers ? Object.keys(servers) : void 0;
1009
827
  }
1010
828
  function getTextFromCursorMessage(message) {
1011
- if (message.type === "assistant") {
1012
- return message.message.content.map((block) => {
1013
- if (block.type === "text") {
1014
- return block.text;
1015
- }
1016
- return "";
1017
- }).filter(Boolean).join("");
1018
- }
1019
- if (message.type === "task") {
1020
- return message.text ?? "";
1021
- }
1022
- return "";
829
+ if (message.type === "assistant") return message.message.content.map((block) => {
830
+ if (block.type === "text") return block.text;
831
+ return "";
832
+ }).filter(Boolean).join("");
833
+ if (message.type === "task") return message.text ?? "";
834
+ return "";
1023
835
  }
1024
836
  function recordCursorToolTelemetry(update, telemetry) {
1025
- const updateRecord = toRecord(update);
1026
- if (!updateRecord) {
1027
- return;
1028
- }
1029
- const updateType = typeof updateRecord?.type === "string" ? updateRecord.type : void 0;
1030
- if (updateType !== "tool-call-started" && updateType !== "partial-tool-call" && updateType !== "tool-call-completed") {
1031
- return;
1032
- }
1033
- const toolCall = getCursorToolCall(updateRecord);
1034
- if (!toolCall) {
1035
- return;
1036
- }
1037
- if (updateType === "tool-call-started" || updateType === "partial-tool-call") {
1038
- telemetry.startToolCall({
1039
- toolCallId: toolCall.toolCallId,
1040
- toolName: toolCall.toolName,
1041
- input: toolCall.input
1042
- });
1043
- return;
1044
- }
1045
- telemetry.startToolCall({
1046
- toolCallId: toolCall.toolCallId,
1047
- toolName: toolCall.toolName,
1048
- input: toolCall.input
1049
- });
1050
- telemetry.endToolCall({
1051
- toolCallId: toolCall.toolCallId,
1052
- output: toolCall.output,
1053
- isError: toolCall.isError
1054
- });
837
+ const updateRecord = toRecord(update);
838
+ if (!updateRecord) return;
839
+ const updateType = typeof updateRecord?.type === "string" ? updateRecord.type : void 0;
840
+ if (updateType !== "tool-call-started" && updateType !== "partial-tool-call" && updateType !== "tool-call-completed") return;
841
+ const toolCall = getCursorToolCall(updateRecord);
842
+ if (!toolCall) return;
843
+ if (updateType === "tool-call-started" || updateType === "partial-tool-call") {
844
+ telemetry.startToolCall({
845
+ toolCallId: toolCall.toolCallId,
846
+ toolName: toolCall.toolName,
847
+ input: toolCall.input
848
+ });
849
+ return;
850
+ }
851
+ telemetry.startToolCall({
852
+ toolCallId: toolCall.toolCallId,
853
+ toolName: toolCall.toolName,
854
+ input: toolCall.input
855
+ });
856
+ telemetry.endToolCall({
857
+ toolCallId: toolCall.toolCallId,
858
+ output: toolCall.output,
859
+ isError: toolCall.isError
860
+ });
1055
861
  }
1056
862
  function getCursorToolCall(update) {
1057
- const toolCallId = typeof update.callId === "string" ? update.callId : void 0;
1058
- const toolCall = toRecord(update.toolCall);
1059
- if (!toolCallId || !toolCall) {
1060
- return void 0;
1061
- }
1062
- if (toolCall.type === "mcp") {
1063
- const args = toRecord(toolCall.args);
1064
- if (!args) {
1065
- return void 0;
1066
- }
1067
- const providerIdentifier = typeof args?.providerIdentifier === "string" ? args.providerIdentifier : void 0;
1068
- const toolName2 = typeof args?.toolName === "string" ? args.toolName : void 0;
1069
- if (!providerIdentifier || !toolName2) {
1070
- return void 0;
1071
- }
1072
- const result = toRecord(toolCall.result);
1073
- return {
1074
- toolCallId,
1075
- toolName: `mcp__${providerIdentifier}__${toolName2}`,
1076
- input: args.args,
1077
- output: result?.value ?? toolCall.result,
1078
- isError: result?.status === "error" || result?.status === "failed"
1079
- };
1080
- }
1081
- const toolName = typeof toolCall.name === "string" ? toolCall.name : typeof toolCall.type === "string" ? toolCall.type : void 0;
1082
- if (!toolName) {
1083
- return void 0;
1084
- }
1085
- return {
1086
- toolCallId,
1087
- toolName,
1088
- input: "args" in toolCall ? toolCall.args : void 0,
1089
- output: "result" in toolCall ? toolCall.result : void 0,
1090
- isError: toolCall.status === "error"
1091
- };
863
+ const toolCallId = typeof update.callId === "string" ? update.callId : void 0;
864
+ const toolCall = toRecord(update.toolCall);
865
+ if (!toolCallId || !toolCall) return;
866
+ if (toolCall.type === "mcp") {
867
+ const args = toRecord(toolCall.args);
868
+ if (!args) return;
869
+ const providerIdentifier = typeof args?.providerIdentifier === "string" ? args.providerIdentifier : void 0;
870
+ const toolName = typeof args?.toolName === "string" ? args.toolName : void 0;
871
+ if (!providerIdentifier || !toolName) return;
872
+ const result = toRecord(toolCall.result);
873
+ return {
874
+ toolCallId,
875
+ toolName: `mcp__${providerIdentifier}__${toolName}`,
876
+ input: args.args,
877
+ output: result?.value ?? toolCall.result,
878
+ isError: result?.status === "error" || result?.status === "failed"
879
+ };
880
+ }
881
+ const toolName = typeof toolCall.name === "string" ? toolCall.name : typeof toolCall.type === "string" ? toolCall.type : void 0;
882
+ if (!toolName) return;
883
+ return {
884
+ toolCallId,
885
+ toolName,
886
+ input: "args" in toolCall ? toolCall.args : void 0,
887
+ output: "result" in toolCall ? toolCall.result : void 0,
888
+ isError: toolCall.status === "error"
889
+ };
1092
890
  }
1093
891
  function toRecord(value) {
1094
- return value !== null && typeof value === "object" ? value : void 0;
892
+ return value !== null && typeof value === "object" ? value : void 0;
1095
893
  }
1096
-
894
+ //#endregion
1097
895
  exports.CursorSDKAgent = CursorSDKAgent;
1098
- //# sourceMappingURL=index.cjs.map
896
+
1099
897
  //# sourceMappingURL=index.cjs.map