effect-cursor-sdk 0.2.0 → 0.3.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/DEPRECATIONS.md +88 -0
- package/README.md +22 -6
- package/dist/index.d.ts +229 -20
- package/dist/index.js +314 -14
- package/dist/index.js.map +1 -1
- package/docs/MIGRATION_NEXT_MAJOR.md +22 -0
- package/docs/RECIPES.md +256 -0
- package/docs/RELEASE_CHECKLIST.md +46 -0
- package/docs/SDK_COVERAGE.md +72 -0
- package/package.json +10 -5
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Config, ConfigProvider, Context, Data, Effect, Layer, ManagedRuntime, Match, Metric, Option, Redacted, Schema, Stream } from "effect";
|
|
1
|
+
import { Config, ConfigProvider, Context, Data, Effect, Layer, ManagedRuntime, Match, Metric, Option, Redacted, Schedule, Schema, Stream } from "effect";
|
|
2
2
|
import { Agent, AuthenticationError, AuthenticationError as AuthenticationError$1, ConfigurationError, ConfigurationError as ConfigurationError$1, Cursor, CursorAgentError, CursorAgentError as CursorAgentError$1, CursorAgentPlatform, IntegrationNotConnectedError, IntegrationNotConnectedError as IntegrationNotConnectedError$1, NetworkError, NetworkError as NetworkError$1, RateLimitError, RateLimitError as RateLimitError$1, UnknownAgentError, UnknownAgentError as UnknownAgentError$1, UnsupportedRunOperationError, UnsupportedRunOperationError as UnsupportedRunOperationError$1, createAgentPlatform, createInMemoryRunEventNotifier, createLocalRunEventNotifier, createSdkMessageRunStreamEvent, decodeLocalRunStreamEvent, decodeSdkMessageRunStreamEvent, getTurnType, isTerminalLocalRunStreamEvent, localRunStreamEventToSdkMessage, startLocalRunEventNotifierServer } from "@cursor/sdk";
|
|
3
3
|
//#region src/cursor-error.ts
|
|
4
4
|
/**
|
|
@@ -237,6 +237,14 @@ const agentOptionsFromConfig = (config, overrides = {}) => {
|
|
|
237
237
|
* It uses ConfigProvider to load the environment variables
|
|
238
238
|
* with their default names (`CURSOR_API_KEY`, `CURSOR_MODEL`, `CURSOR_LOCAL_CWD`)
|
|
239
239
|
* from {@link cursorConfig}.
|
|
240
|
+
* Omitting `CURSOR_API_KEY` only means no default API-key-based auth will be
|
|
241
|
+
* set; callers can still provide credentials via {@link agentOptionsFromConfig}
|
|
242
|
+
* overrides or the `*FromConfig` service helpers.
|
|
243
|
+
*
|
|
244
|
+
* If the API key is not set, it will log a warning message.
|
|
245
|
+
*
|
|
246
|
+
* **NOTE**: omitting the API key will cause an unauthenticated error
|
|
247
|
+
* in subsequent calls to the Cursor SDK API.
|
|
240
248
|
*
|
|
241
249
|
* @example
|
|
242
250
|
* ```ts
|
|
@@ -278,6 +286,7 @@ const loadCursorConfig = Effect.gen(function* () {
|
|
|
278
286
|
const provider = yield* ConfigProvider.ConfigProvider;
|
|
279
287
|
const raw = yield* cursorConfig.parse(provider);
|
|
280
288
|
const apiKey = Option.getOrUndefined(raw.apiKey);
|
|
289
|
+
if (apiKey === void 0 || apiKey === null) yield* Effect.logWarning("CURSOR_API_KEY is not set — this will cause an unauthenticated error in subsequent calls to the Cursor SDK API.");
|
|
281
290
|
const modelId = Option.getOrUndefined(raw.modelId);
|
|
282
291
|
const cwd = Option.getOrUndefined(raw.cwd);
|
|
283
292
|
return new CursorConfig({
|
|
@@ -493,7 +502,7 @@ const redact = (value) => {
|
|
|
493
502
|
return redactInner(value, /* @__PURE__ */ new Set(), 0);
|
|
494
503
|
};
|
|
495
504
|
/**
|
|
496
|
-
* Wraps an SDK-backed {@link Effect
|
|
505
|
+
* Wraps an SDK-backed {@link Effect} with consistent
|
|
497
506
|
* observability: increments {@link cursorOperationsStarted} at execution start,
|
|
498
507
|
* increments {@link cursorOperationsFailed} on the error channel, and attaches
|
|
499
508
|
* a span named `cursor.<operation>` (for example `cursor.agent.list`).
|
|
@@ -566,6 +575,8 @@ const instrument = (operation, effect) => {
|
|
|
566
575
|
* Prefer {@link CursorAgentServiceShape.createFromConfig} and related methods
|
|
567
576
|
* with {@link loadCursorConfig}; raw {@link AgentOptions} on
|
|
568
577
|
* {@link CursorAgentServiceShape.create} and siblings are deprecated.
|
|
578
|
+
* See `DEPRECATIONS.md` at the package root for migration and planned next-major renames
|
|
579
|
+
* (`createFromConfig` → `create`, etc.).
|
|
569
580
|
*
|
|
570
581
|
* @category services
|
|
571
582
|
*/
|
|
@@ -869,9 +880,10 @@ var MockCursorRun = class {
|
|
|
869
880
|
createdAt = Date.now();
|
|
870
881
|
#status;
|
|
871
882
|
#listeners = /* @__PURE__ */ new Set();
|
|
872
|
-
constructor(streamEvents, waitResult) {
|
|
883
|
+
constructor(streamEvents, waitResult, behavior) {
|
|
873
884
|
this.streamEvents = streamEvents;
|
|
874
885
|
this.waitResult = waitResult;
|
|
886
|
+
this.behavior = behavior;
|
|
875
887
|
this.id = waitResult.id;
|
|
876
888
|
this.agentId = streamEvents[0]?.agent_id ?? "mock-agent";
|
|
877
889
|
this.#status = waitResult.status;
|
|
@@ -891,10 +903,14 @@ var MockCursorRun = class {
|
|
|
891
903
|
get git() {
|
|
892
904
|
return this.waitResult.git;
|
|
893
905
|
}
|
|
894
|
-
supports(
|
|
895
|
-
|
|
906
|
+
supports(operation) {
|
|
907
|
+
const override = this.behavior?.supports?.[operation];
|
|
908
|
+
return override !== void 0 ? override : true;
|
|
909
|
+
}
|
|
910
|
+
unsupportedReason(operation) {
|
|
911
|
+
if (this.supports(operation)) return void 0;
|
|
912
|
+
return this.behavior?.unsupportedReason?.[operation] ?? "unsupported in mock";
|
|
896
913
|
}
|
|
897
|
-
unsupportedReason(_operation) {}
|
|
898
914
|
async *stream() {
|
|
899
915
|
yield* this.streamEvents;
|
|
900
916
|
}
|
|
@@ -934,6 +950,7 @@ var MockCursorAgent = class {
|
|
|
934
950
|
agentId;
|
|
935
951
|
runs = [];
|
|
936
952
|
closed = false;
|
|
953
|
+
#sendIndex = 0;
|
|
937
954
|
constructor(fixtures = {}) {
|
|
938
955
|
this.fixtures = fixtures;
|
|
939
956
|
this.agentId = fixtures.agentId ?? "mock-agent";
|
|
@@ -942,7 +959,14 @@ var MockCursorAgent = class {
|
|
|
942
959
|
return this.fixtures.result?.model;
|
|
943
960
|
}
|
|
944
961
|
async send(_message, _options) {
|
|
945
|
-
const
|
|
962
|
+
const seq = this.fixtures.sendSequence;
|
|
963
|
+
const piece = seq === void 0 ? void 0 : seq[Math.min(this.#sendIndex, Math.max(seq.length - 1, 0))];
|
|
964
|
+
const merged = piece !== void 0 ? {
|
|
965
|
+
...this.fixtures,
|
|
966
|
+
...piece
|
|
967
|
+
} : this.fixtures;
|
|
968
|
+
if (seq !== void 0) this.#sendIndex++;
|
|
969
|
+
const run = makeMockRun(merged);
|
|
946
970
|
this.runs.push(run);
|
|
947
971
|
return run;
|
|
948
972
|
}
|
|
@@ -974,6 +998,9 @@ const makeMockRun = (fixtures = {}) => {
|
|
|
974
998
|
id: runId,
|
|
975
999
|
status: "finished",
|
|
976
1000
|
result: ""
|
|
1001
|
+
}, {
|
|
1002
|
+
supports: fixtures.runSupports,
|
|
1003
|
+
unsupportedReason: fixtures.runUnsupportedReason
|
|
977
1004
|
});
|
|
978
1005
|
};
|
|
979
1006
|
/**
|
|
@@ -988,6 +1015,29 @@ const makeMockAgent = (fixtures = {}) => {
|
|
|
988
1015
|
return new MockCursorAgent(fixtures);
|
|
989
1016
|
};
|
|
990
1017
|
/**
|
|
1018
|
+
* Minimal assistant {@link SDKMessage} for streaming tests.
|
|
1019
|
+
*
|
|
1020
|
+
* @category testing
|
|
1021
|
+
*/
|
|
1022
|
+
const makeMockAssistantSdkMessage = (text, ids = {}) => {
|
|
1023
|
+
return {
|
|
1024
|
+
type: "assistant",
|
|
1025
|
+
agent_id: ids.agentId ?? "mock-agent",
|
|
1026
|
+
run_id: ids.runId ?? "mock-run",
|
|
1027
|
+
message: {
|
|
1028
|
+
role: "assistant",
|
|
1029
|
+
content: [{
|
|
1030
|
+
type: "text",
|
|
1031
|
+
text
|
|
1032
|
+
}]
|
|
1033
|
+
}
|
|
1034
|
+
};
|
|
1035
|
+
};
|
|
1036
|
+
const rejectFactory = (fixtures, method) => {
|
|
1037
|
+
const err = fixtures.factoryErrors?.[method];
|
|
1038
|
+
if (err !== void 0) return Promise.reject(err);
|
|
1039
|
+
};
|
|
1040
|
+
/**
|
|
991
1041
|
* Layer replacing the SDK factory with deterministic mock behavior.
|
|
992
1042
|
*
|
|
993
1043
|
* This is the lowest-level mock entry point. Prefer {@link mockLayer} when you
|
|
@@ -1009,12 +1059,14 @@ const makeMockAgent = (fixtures = {}) => {
|
|
|
1009
1059
|
const makeMockSdkFactoryLayer = (fixtures = {}) => {
|
|
1010
1060
|
return Layer.succeed(CursorSdkFactory, CursorSdkFactory.of({
|
|
1011
1061
|
create: (_options) => {
|
|
1012
|
-
return Promise.resolve(makeMockAgent(fixtures));
|
|
1062
|
+
return rejectFactory(fixtures, "create") ?? Promise.resolve(makeMockAgent(fixtures));
|
|
1013
1063
|
},
|
|
1014
1064
|
resume: (_agentId, _options) => {
|
|
1015
|
-
return Promise.resolve(makeMockAgent(fixtures));
|
|
1065
|
+
return rejectFactory(fixtures, "resume") ?? Promise.resolve(makeMockAgent(fixtures));
|
|
1016
1066
|
},
|
|
1017
1067
|
prompt: async (_message, _options) => {
|
|
1068
|
+
const early = rejectFactory(fixtures, "prompt");
|
|
1069
|
+
if (early) return early;
|
|
1018
1070
|
return fixtures.result ?? {
|
|
1019
1071
|
id: fixtures.runId ?? "mock-run",
|
|
1020
1072
|
status: "finished",
|
|
@@ -1022,15 +1074,23 @@ const makeMockSdkFactoryLayer = (fixtures = {}) => {
|
|
|
1022
1074
|
};
|
|
1023
1075
|
},
|
|
1024
1076
|
listAgents: async (_options) => {
|
|
1077
|
+
const early = rejectFactory(fixtures, "listAgents");
|
|
1078
|
+
if (early) return early;
|
|
1025
1079
|
return { items: [...fixtures.agents ?? []] };
|
|
1026
1080
|
},
|
|
1027
1081
|
listRuns: async (_agentId, _options) => {
|
|
1082
|
+
const early = rejectFactory(fixtures, "listRuns");
|
|
1083
|
+
if (early) return early;
|
|
1028
1084
|
return { items: [makeMockRun(fixtures)] };
|
|
1029
1085
|
},
|
|
1030
1086
|
getRun: async (_runId, _options) => {
|
|
1087
|
+
const early = rejectFactory(fixtures, "getRun");
|
|
1088
|
+
if (early) return early;
|
|
1031
1089
|
return makeMockRun(fixtures);
|
|
1032
1090
|
},
|
|
1033
1091
|
getAgent: async (_agentId, _options) => {
|
|
1092
|
+
const early = rejectFactory(fixtures, "getAgent");
|
|
1093
|
+
if (early) return early;
|
|
1034
1094
|
return fixtures.agents?.[0] ?? {
|
|
1035
1095
|
agentId: fixtures.agentId ?? "mock-agent",
|
|
1036
1096
|
name: "Mock Agent",
|
|
@@ -1038,35 +1098,250 @@ const makeMockSdkFactoryLayer = (fixtures = {}) => {
|
|
|
1038
1098
|
lastModified: 0
|
|
1039
1099
|
};
|
|
1040
1100
|
},
|
|
1041
|
-
archiveAgent: async (_agentId, _options) => {
|
|
1042
|
-
|
|
1043
|
-
|
|
1101
|
+
archiveAgent: async (_agentId, _options) => {
|
|
1102
|
+
const early = rejectFactory(fixtures, "archiveAgent");
|
|
1103
|
+
if (early) return early;
|
|
1104
|
+
},
|
|
1105
|
+
unarchiveAgent: async (_agentId, _options) => {
|
|
1106
|
+
const early = rejectFactory(fixtures, "unarchiveAgent");
|
|
1107
|
+
if (early) return early;
|
|
1108
|
+
},
|
|
1109
|
+
deleteAgent: async (_agentId, _options) => {
|
|
1110
|
+
const early = rejectFactory(fixtures, "deleteAgent");
|
|
1111
|
+
if (early) return early;
|
|
1112
|
+
},
|
|
1044
1113
|
listMessages: async (_agentId, _options) => {
|
|
1114
|
+
const early = rejectFactory(fixtures, "listMessages");
|
|
1115
|
+
if (early) return early;
|
|
1045
1116
|
return [...fixtures.messages ?? []];
|
|
1046
1117
|
},
|
|
1047
1118
|
me: async (_options) => {
|
|
1119
|
+
const early = rejectFactory(fixtures, "me");
|
|
1120
|
+
if (early) return early;
|
|
1048
1121
|
return fixtures.user ?? {
|
|
1049
1122
|
apiKeyName: "mock",
|
|
1050
1123
|
createdAt: "1970-01-01T00:00:00.000Z"
|
|
1051
1124
|
};
|
|
1052
1125
|
},
|
|
1053
1126
|
listModels: async (_options) => {
|
|
1127
|
+
const early = rejectFactory(fixtures, "listModels");
|
|
1128
|
+
if (early) return early;
|
|
1054
1129
|
return [...fixtures.models ?? []];
|
|
1055
1130
|
},
|
|
1056
1131
|
listRepositories: async (_options) => {
|
|
1132
|
+
const early = rejectFactory(fixtures, "listRepositories");
|
|
1133
|
+
if (early) return early;
|
|
1057
1134
|
return [...fixtures.repositories ?? []];
|
|
1058
1135
|
}
|
|
1059
1136
|
}));
|
|
1060
1137
|
};
|
|
1061
1138
|
//#endregion
|
|
1139
|
+
//#region src/cursor-observability.ts
|
|
1140
|
+
/**
|
|
1141
|
+
* Reusable observability helpers: stream metrics, retry schedules, and safe summaries.
|
|
1142
|
+
*
|
|
1143
|
+
* @example
|
|
1144
|
+
* ```ts
|
|
1145
|
+
* import {
|
|
1146
|
+
* cursorCatalogLoadTimeout,
|
|
1147
|
+
* cursorCatalogRetrySchedule,
|
|
1148
|
+
* CursorInspectionService,
|
|
1149
|
+
* liveLayer,
|
|
1150
|
+
* } from "effect-cursor-sdk";
|
|
1151
|
+
* import { Effect } from "effect";
|
|
1152
|
+
*
|
|
1153
|
+
* const catalog = Effect.gen(function* () {
|
|
1154
|
+
* const inspection = yield* CursorInspectionService;
|
|
1155
|
+
* return yield* Effect.all(
|
|
1156
|
+
* { agents: inspection.listAgents({ runtime: "cloud" }), models: inspection.listModels() },
|
|
1157
|
+
* { concurrency: "unbounded" },
|
|
1158
|
+
* ).pipe(Effect.retry(cursorCatalogRetrySchedule), Effect.timeout(cursorCatalogLoadTimeout));
|
|
1159
|
+
* }).pipe(Effect.provide(liveLayer));
|
|
1160
|
+
* ```
|
|
1161
|
+
*
|
|
1162
|
+
* @module
|
|
1163
|
+
*/
|
|
1164
|
+
/**
|
|
1165
|
+
* Default exponential retry for Cursor catalog-style calls (list agents, models, repos).
|
|
1166
|
+
*
|
|
1167
|
+
* Matches the pattern used in the advanced ops dashboard example: 150ms base, 3 attempts.
|
|
1168
|
+
*
|
|
1169
|
+
* @example
|
|
1170
|
+
* ```ts
|
|
1171
|
+
* import { CursorInspectionService, cursorCatalogRetrySchedule, liveLayer } from "effect-cursor-sdk";
|
|
1172
|
+
* import { Effect } from "effect";
|
|
1173
|
+
*
|
|
1174
|
+
* const program = Effect.gen(function* () {
|
|
1175
|
+
* const inspection = yield* CursorInspectionService;
|
|
1176
|
+
* return yield* inspection.listModels().pipe(Effect.retry(cursorCatalogRetrySchedule));
|
|
1177
|
+
* }).pipe(Effect.provide(liveLayer));
|
|
1178
|
+
* ```
|
|
1179
|
+
*
|
|
1180
|
+
* @category observability
|
|
1181
|
+
*/
|
|
1182
|
+
const cursorCatalogRetrySchedule = Schedule.exponential("150 millis").pipe(Schedule.both(Schedule.recurs(3)));
|
|
1183
|
+
/**
|
|
1184
|
+
* Default timeout for parallel catalog loads.
|
|
1185
|
+
*
|
|
1186
|
+
* @example
|
|
1187
|
+
* ```ts
|
|
1188
|
+
* import { CursorInspectionService, cursorCatalogLoadTimeout, liveLayer } from "effect-cursor-sdk";
|
|
1189
|
+
* import { Effect } from "effect";
|
|
1190
|
+
*
|
|
1191
|
+
* const program = Effect.gen(function* () {
|
|
1192
|
+
* const inspection = yield* CursorInspectionService;
|
|
1193
|
+
* return yield* Effect.all(
|
|
1194
|
+
* { user: inspection.me(), models: inspection.listModels() },
|
|
1195
|
+
* { concurrency: "unbounded" },
|
|
1196
|
+
* ).pipe(Effect.timeout(cursorCatalogLoadTimeout));
|
|
1197
|
+
* }).pipe(Effect.provide(liveLayer));
|
|
1198
|
+
* ```
|
|
1199
|
+
*
|
|
1200
|
+
* @category observability
|
|
1201
|
+
*/
|
|
1202
|
+
const cursorCatalogLoadTimeout = "45 seconds";
|
|
1203
|
+
/**
|
|
1204
|
+
* Append assistant-visible text from a streamed {@link SDKMessage} (same rules as {@link CursorRunService.collectText}).
|
|
1205
|
+
*
|
|
1206
|
+
* @example
|
|
1207
|
+
* ```ts
|
|
1208
|
+
* import { appendAssistantSdkMessageText } from "effect-cursor-sdk";
|
|
1209
|
+
* import type { SDKMessage } from "effect-cursor-sdk";
|
|
1210
|
+
*
|
|
1211
|
+
* const events: SDKMessage[] = []; // from run.stream()
|
|
1212
|
+
* const text = events.reduce(appendAssistantSdkMessageText, "");
|
|
1213
|
+
* ```
|
|
1214
|
+
*
|
|
1215
|
+
* @category observability
|
|
1216
|
+
*/
|
|
1217
|
+
const appendAssistantSdkMessageText = (text, event) => {
|
|
1218
|
+
if (event.type !== "assistant") return text;
|
|
1219
|
+
return text + event.message.content.filter((block) => {
|
|
1220
|
+
return block.type === "text";
|
|
1221
|
+
}).map((block) => {
|
|
1222
|
+
return block.text;
|
|
1223
|
+
}).join("");
|
|
1224
|
+
};
|
|
1225
|
+
/**
|
|
1226
|
+
* Wraps a run event stream and increments {@link cursorStreamEvents} per emitted event.
|
|
1227
|
+
*
|
|
1228
|
+
* @example
|
|
1229
|
+
* ```ts
|
|
1230
|
+
* import { CursorRunService, streamEventsTracked, liveLayer } from "effect-cursor-sdk";
|
|
1231
|
+
* import { Effect, Stream } from "effect";
|
|
1232
|
+
* import type { Run } from "effect-cursor-sdk";
|
|
1233
|
+
*
|
|
1234
|
+
* declare const run: Run;
|
|
1235
|
+
*
|
|
1236
|
+
* const program = Effect.gen(function* () {
|
|
1237
|
+
* const runs = yield* CursorRunService;
|
|
1238
|
+
* yield* streamEventsTracked(runs.streamEvents(run)).pipe(Stream.runDrain);
|
|
1239
|
+
* }).pipe(Effect.provide(liveLayer));
|
|
1240
|
+
* ```
|
|
1241
|
+
*
|
|
1242
|
+
* @category observability
|
|
1243
|
+
*/
|
|
1244
|
+
const streamEventsTracked = (stream) => {
|
|
1245
|
+
return stream.pipe(Stream.tap(() => Effect.void.pipe(Effect.trackSuccesses(cursorStreamEvents.pipe(Metric.withConstantInput(1))))));
|
|
1246
|
+
};
|
|
1247
|
+
/**
|
|
1248
|
+
* Like {@link CursorRunService.collectText}, but increments {@link cursorStreamEvents} per stream chunk.
|
|
1249
|
+
*
|
|
1250
|
+
* @param run - SDK run handle.
|
|
1251
|
+
* @param streamEvents - Typically `runs.streamEvents` from {@link CursorRunService}.
|
|
1252
|
+
*
|
|
1253
|
+
* @example
|
|
1254
|
+
* ```ts
|
|
1255
|
+
* import { collectTextTracked, CursorRunService, liveLayer } from "effect-cursor-sdk";
|
|
1256
|
+
* import { Effect } from "effect";
|
|
1257
|
+
* import type { Run } from "effect-cursor-sdk";
|
|
1258
|
+
*
|
|
1259
|
+
* declare const run: Run;
|
|
1260
|
+
*
|
|
1261
|
+
* const text = Effect.gen(function* () {
|
|
1262
|
+
* const runs = yield* CursorRunService;
|
|
1263
|
+
* return yield* collectTextTracked(run, (r) => runs.streamEvents(r));
|
|
1264
|
+
* }).pipe(Effect.provide(liveLayer));
|
|
1265
|
+
* ```
|
|
1266
|
+
*
|
|
1267
|
+
* @category observability
|
|
1268
|
+
*/
|
|
1269
|
+
const collectTextTracked = (run, streamEvents) => {
|
|
1270
|
+
return streamEventsTracked(streamEvents(run)).pipe(Stream.runFold(() => "", appendAssistantSdkMessageText));
|
|
1271
|
+
};
|
|
1272
|
+
/**
|
|
1273
|
+
* Build a redacted, log-safe summary of {@link AgentOptions} **without** an API key value.
|
|
1274
|
+
*
|
|
1275
|
+
* @remarks
|
|
1276
|
+
* Nested structures are passed through {@link redact}. Never log raw `apiKey`.
|
|
1277
|
+
*
|
|
1278
|
+
* @example
|
|
1279
|
+
* ```ts
|
|
1280
|
+
* import { summarizeAgentOptionsForLog } from "effect-cursor-sdk";
|
|
1281
|
+
* import { Effect } from "effect";
|
|
1282
|
+
*
|
|
1283
|
+
* const program = Effect.gen(function* () {
|
|
1284
|
+
* const options = { model: { id: "composer-2" }, apiKey: "secret" };
|
|
1285
|
+
* yield* Effect.logInfo("cursor run", summarizeAgentOptionsForLog(options));
|
|
1286
|
+
* });
|
|
1287
|
+
* ```
|
|
1288
|
+
*
|
|
1289
|
+
* @category observability
|
|
1290
|
+
*/
|
|
1291
|
+
const summarizeAgentOptionsForLog = (options) => {
|
|
1292
|
+
const mcpKeys = options.mcpServers ? Object.keys(options.mcpServers) : void 0;
|
|
1293
|
+
return redact({
|
|
1294
|
+
model: options.model,
|
|
1295
|
+
name: options.name,
|
|
1296
|
+
agentId: options.agentId,
|
|
1297
|
+
local: options.local,
|
|
1298
|
+
cloud: options.cloud ? {
|
|
1299
|
+
reposCount: options.cloud.repos?.length,
|
|
1300
|
+
autoCreatePR: options.cloud.autoCreatePR,
|
|
1301
|
+
workOnCurrentBranch: options.cloud.workOnCurrentBranch,
|
|
1302
|
+
envType: options.cloud.env?.type
|
|
1303
|
+
} : void 0,
|
|
1304
|
+
mcpServerNames: mcpKeys,
|
|
1305
|
+
agentsCount: options.agents ? Object.keys(options.agents).length : void 0
|
|
1306
|
+
});
|
|
1307
|
+
};
|
|
1308
|
+
/**
|
|
1309
|
+
* Attach minimal run identifiers for structured logs or span attributes.
|
|
1310
|
+
*
|
|
1311
|
+
* @example
|
|
1312
|
+
* ```ts
|
|
1313
|
+
* import { summarizeRunForLog } from "effect-cursor-sdk";
|
|
1314
|
+
* import { Effect } from "effect";
|
|
1315
|
+
*
|
|
1316
|
+
* const program = Effect.gen(function* () {
|
|
1317
|
+
* const run = { id: "run_1", agentId: "agt_1", status: "finished" as const };
|
|
1318
|
+
* yield* Effect.logDebug("run done", summarizeRunForLog(run));
|
|
1319
|
+
* });
|
|
1320
|
+
* ```
|
|
1321
|
+
*
|
|
1322
|
+
* @category observability
|
|
1323
|
+
*/
|
|
1324
|
+
const summarizeRunForLog = (run) => {
|
|
1325
|
+
return {
|
|
1326
|
+
runId: run.id,
|
|
1327
|
+
agentId: run.agentId,
|
|
1328
|
+
status: run.status
|
|
1329
|
+
};
|
|
1330
|
+
};
|
|
1331
|
+
//#endregion
|
|
1062
1332
|
//#region src/cursor-run.ts
|
|
1063
1333
|
/**
|
|
1064
1334
|
* Effect-native helpers for SDK run handles.
|
|
1065
1335
|
*
|
|
1066
1336
|
* @example
|
|
1067
1337
|
* ```ts
|
|
1338
|
+
* const runService = yield* CursorRunService;
|
|
1339
|
+
*
|
|
1340
|
+
* // Create a run with the agent service
|
|
1068
1341
|
* const run = yield* agents.send(agent, "Refactor auth")
|
|
1069
|
-
*
|
|
1342
|
+
*
|
|
1343
|
+
* // Use the run service with the created run
|
|
1344
|
+
* const conversation = yield* runService.conversation(run);
|
|
1070
1345
|
* ```
|
|
1071
1346
|
*
|
|
1072
1347
|
* @see {@link CursorAgentService} for creating and sending runs.
|
|
@@ -1130,6 +1405,31 @@ var CursorRunService = class CursorRunService extends Context.Service()("effect-
|
|
|
1130
1405
|
onDidChangeStatus: (run, listener) => {
|
|
1131
1406
|
return Effect.sync(() => run.onDidChangeStatus(listener));
|
|
1132
1407
|
},
|
|
1408
|
+
streamStatusChanges: (run) => {
|
|
1409
|
+
return Stream.fromAsyncIterable((async function* () {
|
|
1410
|
+
const pending = [];
|
|
1411
|
+
let notify;
|
|
1412
|
+
const unsub = run.onDidChangeStatus((status) => {
|
|
1413
|
+
pending.push(status);
|
|
1414
|
+
const resume = notify;
|
|
1415
|
+
notify = void 0;
|
|
1416
|
+
resume?.();
|
|
1417
|
+
});
|
|
1418
|
+
try {
|
|
1419
|
+
while (true) {
|
|
1420
|
+
if (pending.length > 0) {
|
|
1421
|
+
yield pending.shift();
|
|
1422
|
+
continue;
|
|
1423
|
+
}
|
|
1424
|
+
await new Promise((resolve) => {
|
|
1425
|
+
notify = resolve;
|
|
1426
|
+
});
|
|
1427
|
+
}
|
|
1428
|
+
} finally {
|
|
1429
|
+
unsub();
|
|
1430
|
+
}
|
|
1431
|
+
})(), () => void 0);
|
|
1432
|
+
},
|
|
1133
1433
|
collectText: (run) => {
|
|
1134
1434
|
return Stream.fromAsyncIterable(run.stream(), (cause) => {
|
|
1135
1435
|
return mapCursorError(cause, {
|
|
@@ -1232,6 +1532,6 @@ const makeMockRuntime = (fixtures = {}) => {
|
|
|
1232
1532
|
*/
|
|
1233
1533
|
const packageName = "effect-cursor-sdk";
|
|
1234
1534
|
//#endregion
|
|
1235
|
-
export { AuthenticationError, ConfigurationError, CursorAgentError, CursorAgentPlatform, CursorAgentService, CursorApiKey, CursorArtifactService, CursorAuthenticationError, CursorConfig, CursorConfigurationError, CursorInspectionService, CursorIntegrationNotConnectedError, CursorLocalCwd, CursorModelId, CursorNetworkError, CursorRateLimitError, CursorRunFailedError, CursorRunService, CursorSdkFactory, CursorStreamError, CursorUnknownError, CursorUnsupportedOperationError, IntegrationNotConnectedError, MockCursorAgent, MockCursorRun, NetworkError, RateLimitError, UnknownAgentError, UnsupportedRunOperationError, agentOptionsFromConfig, createAgentPlatform, createInMemoryRunEventNotifier, createLocalRunEventNotifier, createSdkMessageRunStreamEvent, cursorConfig, cursorOperationsFailed, cursorOperationsStarted, cursorStreamEvents, decodeLocalRunStreamEvent, decodeSdkMessageRunStreamEvent, getTurnType, instrument, isTerminalLocalRunStreamEvent, liveLayer, liveRuntime, loadCursorConfig, localRunStreamEventToSdkMessage, makeMockAgent, makeMockRun, makeMockRuntime, makeMockSdkFactoryLayer, mapCursorError, mockLayer, packageName, redact, startLocalRunEventNotifierServer };
|
|
1535
|
+
export { AuthenticationError, ConfigurationError, CursorAgentError, CursorAgentPlatform, CursorAgentService, CursorApiKey, CursorArtifactService, CursorAuthenticationError, CursorConfig, CursorConfigurationError, CursorInspectionService, CursorIntegrationNotConnectedError, CursorLocalCwd, CursorModelId, CursorNetworkError, CursorRateLimitError, CursorRunFailedError, CursorRunService, CursorSdkFactory, CursorStreamError, CursorUnknownError, CursorUnsupportedOperationError, IntegrationNotConnectedError, MockCursorAgent, MockCursorRun, NetworkError, RateLimitError, UnknownAgentError, UnsupportedRunOperationError, agentOptionsFromConfig, appendAssistantSdkMessageText, collectTextTracked, createAgentPlatform, createInMemoryRunEventNotifier, createLocalRunEventNotifier, createSdkMessageRunStreamEvent, cursorCatalogLoadTimeout, cursorCatalogRetrySchedule, cursorConfig, cursorOperationsFailed, cursorOperationsStarted, cursorStreamEvents, decodeLocalRunStreamEvent, decodeSdkMessageRunStreamEvent, getTurnType, instrument, isTerminalLocalRunStreamEvent, liveLayer, liveRuntime, loadCursorConfig, localRunStreamEventToSdkMessage, makeMockAgent, makeMockAssistantSdkMessage, makeMockRun, makeMockRuntime, makeMockSdkFactoryLayer, mapCursorError, mockLayer, packageName, redact, startLocalRunEventNotifierServer, streamEventsTracked, summarizeAgentOptionsForLog, summarizeRunForLog };
|
|
1236
1536
|
|
|
1237
1537
|
//# sourceMappingURL=index.js.map
|