@letta-ai/letta-code 0.34.25 → 0.34.26

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 (76) hide show
  1. package/cursor-worker.js +167 -0
  2. package/dist/agent-presets.js +1 -64
  3. package/dist/agent-presets.js.map +2 -2
  4. package/dist/channels-slack.js +30 -24
  5. package/dist/channels-slack.js.map +3 -3
  6. package/dist/mcp-client.js +233 -75
  7. package/dist/mcp-client.js.map +9 -9
  8. package/dist/mcp-oauth.js +233 -75
  9. package/dist/mcp-oauth.js.map +9 -9
  10. package/dist/types/agent/subagents/index.d.ts +4 -0
  11. package/dist/types/agent/subagents/index.d.ts.map +1 -1
  12. package/dist/types/agent/subagents/manager.d.ts.map +1 -1
  13. package/dist/types/agent/subagents/memory-worker.d.ts +2 -8
  14. package/dist/types/agent/subagents/memory-worker.d.ts.map +1 -1
  15. package/dist/types/backend/api/providers.d.ts +8 -2
  16. package/dist/types/backend/api/providers.d.ts.map +1 -1
  17. package/dist/types/backend/backend.d.ts +5 -2
  18. package/dist/types/backend/backend.d.ts.map +1 -1
  19. package/dist/types/backend/dev/fake-headless-backend.d.ts +2 -1
  20. package/dist/types/backend/dev/fake-headless-backend.d.ts.map +1 -1
  21. package/dist/types/backend/dev/pi-model-factory.d.ts.map +1 -1
  22. package/dist/types/backend/local/local-provider-auth-store.d.ts +2 -0
  23. package/dist/types/backend/local/local-provider-auth-store.d.ts.map +1 -1
  24. package/dist/types/backend/local/local-transcript-history.d.ts +10 -0
  25. package/dist/types/backend/local/local-transcript-history.d.ts.map +1 -0
  26. package/dist/types/backend/local/local-transcript.d.ts +6 -0
  27. package/dist/types/backend/local/local-transcript.d.ts.map +1 -1
  28. package/dist/types/channels/slack/attachment-primitives.d.ts +2 -1
  29. package/dist/types/channels/slack/attachment-primitives.d.ts.map +1 -1
  30. package/dist/types/cli/subcommands/mcp.d.ts +2 -2
  31. package/dist/types/cli/subcommands/mcp.d.ts.map +1 -1
  32. package/dist/types/cron/process-identity.d.ts.map +1 -1
  33. package/dist/types/cron/run-log.d.ts +1 -0
  34. package/dist/types/cron/run-log.d.ts.map +1 -1
  35. package/dist/types/headless-environment-response.d.ts +27 -0
  36. package/dist/types/headless-environment-response.d.ts.map +1 -1
  37. package/dist/types/providers/byok-providers.d.ts +14 -0
  38. package/dist/types/providers/byok-providers.d.ts.map +1 -1
  39. package/dist/types/tools/impl/claude-stream-session.d.ts.map +1 -1
  40. package/dist/types/tools/impl/codex-app-server.d.ts.map +1 -1
  41. package/dist/types/tools/impl/cursor-session.d.ts +26 -0
  42. package/dist/types/tools/impl/cursor-session.d.ts.map +1 -0
  43. package/dist/types/tools/impl/cursor-worker.d.ts +32 -0
  44. package/dist/types/tools/impl/cursor-worker.d.ts.map +1 -0
  45. package/dist/types/tools/impl/external-coding-agent-task.d.ts.map +1 -1
  46. package/dist/types/tools/impl/external-coding-agent.d.ts +1 -1
  47. package/dist/types/tools/impl/external-coding-agent.d.ts.map +1 -1
  48. package/dist/types/tools/impl/memory-task-lifecycle.d.ts +2 -2
  49. package/dist/types/tools/impl/memory-task-lifecycle.d.ts.map +1 -1
  50. package/dist/types/tools/impl/remote-external-coding-agent.d.ts.map +1 -1
  51. package/dist/types/tools/impl/send-agent-message.d.ts.map +1 -1
  52. package/dist/types/tools/impl/task.d.ts.map +1 -1
  53. package/dist/types/tools/workflow/sdk-spawner.d.ts.map +1 -1
  54. package/dist/types/utils/native-cli-env.d.ts +3 -0
  55. package/dist/types/utils/native-cli-env.d.ts.map +1 -0
  56. package/dist/types/utils/process-liveness.d.ts +9 -0
  57. package/dist/types/utils/process-liveness.d.ts.map +1 -1
  58. package/letta.js +3512 -2894
  59. package/npm-shrinkwrap.json +275 -101
  60. package/package.json +5 -3
  61. package/scripts/agent-watch/verify-pr-identity.test.ts +148 -0
  62. package/scripts/agent-watch/verify-pr-identity.ts +72 -14
  63. package/scripts/claude-watch/agent-watch.ts +8 -2
  64. package/scripts/claude-watch/release-source.test.ts +120 -0
  65. package/scripts/claude-watch/release-source.ts +79 -9
  66. package/scripts/codex-watch/agent-watch.ts +2 -2
  67. package/scripts/codex-watch/release-analysis.test.ts +112 -6
  68. package/scripts/codex-watch/release-analysis.ts +63 -6
  69. package/scripts/source-file-size-baseline.json +5 -4
  70. package/skills/initializing-memory/SKILL.md +1 -1
  71. package/skills/managing-agent-webhooks/SKILL.md +23 -3
  72. package/skills/managing-agent-webhooks/scripts/manage-agent-webhooks.mjs +40 -11
  73. package/skills/self-configuration/SKILL.md +1 -1
  74. package/skills/syncing-memory-filesystem/SKILL.md +2 -10
  75. package/dist/types/agent/memory-worktree.d.ts +0 -83
  76. package/dist/types/agent/memory-worktree.d.ts.map +0 -1
package/dist/mcp-oauth.js CHANGED
@@ -13977,7 +13977,8 @@ var OAuthTokensSchema = object({
13977
13977
  token_type: string2(),
13978
13978
  expires_in: exports_coerce.number().optional(),
13979
13979
  scope: string2().optional(),
13980
- refresh_token: string2().optional()
13980
+ refresh_token: string2().optional(),
13981
+ issuer: string2().optional().catch(undefined)
13981
13982
  }).strip();
13982
13983
  var OAuthErrorResponseSchema = object({
13983
13984
  error: string2(),
@@ -14009,7 +14010,8 @@ var OAuthClientInformationSchema = object({
14009
14010
  client_id: string2(),
14010
14011
  client_secret: string2().optional(),
14011
14012
  client_id_issued_at: number2().optional(),
14012
- client_secret_expires_at: number2().optional()
14013
+ client_secret_expires_at: number2().optional(),
14014
+ issuer: string2().optional().catch(undefined)
14013
14015
  }).strip();
14014
14016
  var OAuthClientInformationFullSchema = OAuthClientMetadataSchema.merge(OAuthClientInformationSchema);
14015
14017
  var OAuthClientRegistrationErrorSchema = object({
@@ -14150,6 +14152,94 @@ var OAUTH_ERRORS = {
14150
14152
  [InvalidTargetError.errorCode]: InvalidTargetError
14151
14153
  };
14152
14154
 
14155
+ // node_modules/@modelcontextprotocol/sdk/dist/esm/shared/transport.js
14156
+ function normalizeHeaders(headers) {
14157
+ if (!headers)
14158
+ return {};
14159
+ if (headers instanceof Headers) {
14160
+ return Object.fromEntries(headers.entries());
14161
+ }
14162
+ if (Array.isArray(headers)) {
14163
+ return Object.fromEntries(headers);
14164
+ }
14165
+ return { ...headers };
14166
+ }
14167
+ function createFetchWithInit(baseFetch = fetch, baseInit) {
14168
+ if (!baseInit) {
14169
+ return baseFetch;
14170
+ }
14171
+ return async (url2, init) => {
14172
+ const mergedInit = {
14173
+ ...baseInit,
14174
+ ...init,
14175
+ headers: init?.headers ? { ...normalizeHeaders(baseInit.headers), ...normalizeHeaders(init.headers) } : baseInit.headers
14176
+ };
14177
+ return baseFetch(url2, mergedInit);
14178
+ };
14179
+ }
14180
+ var MAX_REDIRECTS = 5;
14181
+ var REDIRECT_STATUSES = [301, 302, 303, 307, 308];
14182
+ function isWithinOrigin(from, to) {
14183
+ if (from.protocol === to.protocol && from.hostname === to.hostname && from.port === to.port) {
14184
+ return true;
14185
+ }
14186
+ return from.hostname === to.hostname && from.protocol === "http:" && from.port === "" && to.protocol === "https:" && to.port === "";
14187
+ }
14188
+ function redirectTarget(response, requestUrl) {
14189
+ const location = REDIRECT_STATUSES.includes(response.status) ? response.headers.get("location") : null;
14190
+ try {
14191
+ return location ? new URL(location, requestUrl) : undefined;
14192
+ } catch {
14193
+ return;
14194
+ }
14195
+ }
14196
+ function followWithinOrigin(baseFetch, url2, init, response, followed = 0) {
14197
+ const target = redirectTarget(response, url2);
14198
+ const keepsMethod = response.status === 307 || response.status === 308 || (init?.method ?? "GET").toUpperCase() === "GET";
14199
+ if (!target || followed === MAX_REDIRECTS || !keepsMethod) {
14200
+ return;
14201
+ }
14202
+ const from = new URL(url2);
14203
+ const addsUserinfo = (target.username || target.password) && (target.username !== from.username || target.password !== from.password);
14204
+ if (addsUserinfo || !isWithinOrigin(from, target)) {
14205
+ return;
14206
+ }
14207
+ return Promise.resolve(response.body?.cancel()).then(() => baseFetch(target, { ...init, redirect: "manual" })).then((next) => followWithinOrigin(baseFetch, target, init, next, followed + 1) ?? next);
14208
+ }
14209
+ var followingFetches = new WeakSet;
14210
+ function fetchLeavingRedirects(baseFetch) {
14211
+ const following = (url2, init) => (baseFetch ?? fetch)(url2, init);
14212
+ followingFetches.add(following);
14213
+ return following;
14214
+ }
14215
+ function fetchWithinOrigin(baseFetch = fetch) {
14216
+ if (followingFetches.has(baseFetch)) {
14217
+ return baseFetch;
14218
+ }
14219
+ return (url2, init) => {
14220
+ if (init?.redirect === "error" || init?.redirect === "manual") {
14221
+ return baseFetch(url2, init);
14222
+ }
14223
+ return Promise.resolve(baseFetch(url2, { ...init, redirect: "manual" })).then((response) => followWithinOrigin(baseFetch, url2, init, response) ?? response);
14224
+ };
14225
+ }
14226
+ function unfollowedRedirect(response, requestUrl) {
14227
+ if (response.type === "opaqueredirect") {
14228
+ return "Redirect not followed: this runtime does not expose the redirect target";
14229
+ }
14230
+ const from = response.url || requestUrl;
14231
+ const target = redirectTarget(response, from);
14232
+ if (!target) {
14233
+ return;
14234
+ }
14235
+ target.username = target.password = target.search = target.hash = "";
14236
+ if (target.protocol === "http:" && new URL(from).protocol === "https:") {
14237
+ target.protocol = "https:";
14238
+ return `Redirect to plain http not followed; try ${target.href} instead`;
14239
+ }
14240
+ return `Redirect to ${target.href} not followed`;
14241
+ }
14242
+
14153
14243
  // node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth.js
14154
14244
  class UnauthorizedError extends Error {
14155
14245
  constructor(message) {
@@ -14221,10 +14311,30 @@ async function parseErrorResponse(input) {
14221
14311
  const errorClass = OAUTH_ERRORS[error2] || ServerError;
14222
14312
  return new errorClass(error_description || "", error_uri);
14223
14313
  } catch (error2) {
14224
- const errorMessage = `${statusCode ? `HTTP ${statusCode}: ` : ""}Invalid OAuth error response: ${error2}. Raw body: ${body}`;
14314
+ const redirect = input instanceof Response ? unfollowedRedirect(input, input.url) : undefined;
14315
+ const errorMessage = `${statusCode ? `HTTP ${statusCode}: ` : ""}${redirect ?? `Invalid OAuth error response: ${error2}. Raw body: ${body}`}`;
14225
14316
  return new ServerError(errorMessage);
14226
14317
  }
14227
14318
  }
14319
+ function issuersMatch(a, b) {
14320
+ let [x, y] = [a, b];
14321
+ try {
14322
+ [x, y] = [new URL(a).href, new URL(b).href];
14323
+ } catch {}
14324
+ return x === y || x.endsWith("/") && x.slice(0, -1) === y || y.endsWith("/") && y.slice(0, -1) === x;
14325
+ }
14326
+ function discardIfIssuerMismatch(stored, issuer) {
14327
+ if (!stored)
14328
+ return;
14329
+ if (typeof stored.issuer !== "string")
14330
+ return stored.issuer == null ? stored : { ...stored, issuer: undefined };
14331
+ return issuersMatch(stored.issuer, issuer) ? stored : undefined;
14332
+ }
14333
+ var TokenResponseSchema = OAuthTokensSchema.omit({ issuer: true });
14334
+ var RegistrationResponseSchema = OAuthClientInformationFullSchema.omit({ issuer: true });
14335
+ function boundElsewhereError(stored, issuer) {
14336
+ return new Error(`OAuth client information is bound to authorization server ${stored.issuer} and is not presented to ${issuer}. ` + "Clear the stored client information, or correct `expectedIssuer`, if the authorization server has moved.");
14337
+ }
14228
14338
  async function auth(provider, options) {
14229
14339
  try {
14230
14340
  return await authInternal(provider, options);
@@ -14277,9 +14387,23 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
14277
14387
  authorizationServerMetadata: metadata
14278
14388
  });
14279
14389
  }
14280
- const resource = await selectResourceURL(serverUrl, provider, resourceMetadata);
14390
+ const issuer = String(authorizationServerUrl);
14391
+ const selectedResource = await selectResourceURL(serverUrl, provider, resourceMetadata);
14392
+ const resource = selectedResource && resourceMetadata && !provider.validateResourceURL ? resourceMetadata.resource : selectedResource;
14281
14393
  const resolvedScope = scope || resourceMetadata?.scopes_supported?.join(" ") || provider.clientMetadata.scope;
14282
- let clientInformation = await Promise.resolve(provider.clientInformation());
14394
+ const storedClientInformation = await Promise.resolve(provider.clientInformation());
14395
+ let clientInformation = discardIfIssuerMismatch(storedClientInformation, issuer);
14396
+ const canRegisterAgain = provider.saveClientInformation !== undefined && !!provider.redirectUrl;
14397
+ if (storedClientInformation && !clientInformation && !canRegisterAgain) {
14398
+ throw boundElsewhereError(storedClientInformation, issuer);
14399
+ }
14400
+ const unstampedClientInformation = clientInformation?.issuer == null ? clientInformation : undefined;
14401
+ const bindClientInformation = async () => {
14402
+ try {
14403
+ if (unstampedClientInformation)
14404
+ await provider.saveClientInformation?.({ ...unstampedClientInformation, issuer });
14405
+ } catch {}
14406
+ };
14283
14407
  if (!clientInformation) {
14284
14408
  if (authorizationCode !== undefined) {
14285
14409
  throw new Error("Existing OAuth client information is required when exchanging an authorization code");
@@ -14291,9 +14415,7 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
14291
14415
  }
14292
14416
  const shouldUseUrlBasedClientId = supportsUrlBasedClientId && clientMetadataUrl;
14293
14417
  if (shouldUseUrlBasedClientId) {
14294
- clientInformation = {
14295
- client_id: clientMetadataUrl
14296
- };
14418
+ clientInformation = { client_id: clientMetadataUrl, issuer };
14297
14419
  await provider.saveClientInformation?.(clientInformation);
14298
14420
  } else {
14299
14421
  if (!provider.saveClientInformation) {
@@ -14305,8 +14427,8 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
14305
14427
  scope: resolvedScope,
14306
14428
  fetchFn
14307
14429
  });
14308
- await provider.saveClientInformation(fullInformation);
14309
- clientInformation = fullInformation;
14430
+ clientInformation = { ...fullInformation, issuer };
14431
+ await provider.saveClientInformation(clientInformation);
14310
14432
  }
14311
14433
  }
14312
14434
  const nonInteractiveFlow = !provider.redirectUrl;
@@ -14317,10 +14439,14 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
14317
14439
  authorizationCode,
14318
14440
  fetchFn
14319
14441
  });
14320
- await provider.saveTokens(tokens2);
14442
+ await bindClientInformation();
14443
+ await provider.saveTokens({ ...tokens2, issuer });
14321
14444
  return "AUTHORIZED";
14322
14445
  }
14323
- const tokens = await provider.tokens();
14446
+ const tokens = discardIfIssuerMismatch(await provider.tokens(), issuer);
14447
+ if (tokens?.refresh_token && tokens.issuer == null) {
14448
+ console.warn("[mcp-sdk] stored OAuth tokens have no 'issuer' property (saved by an earlier version, or by a provider that " + "does not keep it) and are used as-is; make sure your OAuthClientProvider stores what saveTokens() and " + "saveClientInformation() receive unchanged.");
14449
+ }
14324
14450
  if (tokens?.refresh_token) {
14325
14451
  try {
14326
14452
  const newTokens = await refreshAuthorization(authorizationServerUrl, {
@@ -14331,7 +14457,8 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
14331
14457
  addClientAuthentication: provider.addClientAuthentication,
14332
14458
  fetchFn
14333
14459
  });
14334
- await provider.saveTokens(newTokens);
14460
+ await bindClientInformation();
14461
+ await provider.saveTokens({ ...newTokens, issuer });
14335
14462
  return "AUTHORIZED";
14336
14463
  } catch (error2) {
14337
14464
  if (!(error2 instanceof OAuthError) || error2 instanceof ServerError) {} else {
@@ -14428,7 +14555,7 @@ async function discoverOAuthProtectedResourceMetadata(serverUrl, opts, fetchFn =
14428
14555
  }
14429
14556
  async function fetchWithCorsRetry(url2, headers, fetchFn = fetch) {
14430
14557
  try {
14431
- return await fetchFn(url2, { headers });
14558
+ return await fetchWithinOrigin(fetchFn)(url2, { headers });
14432
14559
  } catch (error2) {
14433
14560
  if (error2 instanceof TypeError) {
14434
14561
  if (headers) {
@@ -14453,7 +14580,7 @@ async function tryMetadataDiscovery(url2, protocolVersion, fetchFn = fetch) {
14453
14580
  return await fetchWithCorsRetry(url2, headers, fetchFn);
14454
14581
  }
14455
14582
  function shouldAttemptFallback(response, pathname) {
14456
- return !response || response.status >= 400 && response.status < 500 && pathname !== "/";
14583
+ return !response || !response.ok && response.status < 500 && pathname !== "/";
14457
14584
  }
14458
14585
  async function discoverMetadataWithFallback(serverUrl, wellKnownType, fetchFn, opts) {
14459
14586
  const issuer = new URL(serverUrl);
@@ -14519,7 +14646,7 @@ async function discoverAuthorizationServerMetadata(authorizationServerUrl, { fet
14519
14646
  }
14520
14647
  if (!response.ok) {
14521
14648
  await response.body?.cancel();
14522
- if (response.status >= 400 && response.status < 500) {
14649
+ if (response.status < 500) {
14523
14650
  continue;
14524
14651
  }
14525
14652
  throw new Error(`HTTP ${response.status} trying to load ${type === "oauth" ? "OAuth" : "OpenID provider"} metadata from ${endpointUrl}`);
@@ -14551,6 +14678,9 @@ async function discoverOAuthServerInfo(serverUrl, opts) {
14551
14678
  resourceMetadata
14552
14679
  };
14553
14680
  }
14681
+ function resourceIndicatorToString(resource) {
14682
+ return typeof resource === "string" ? resource : resource.href;
14683
+ }
14554
14684
  async function startAuthorization(authorizationServerUrl, { metadata, clientInformation, redirectUrl, scope, state, resource }) {
14555
14685
  let authorizationUrl;
14556
14686
  if (metadata) {
@@ -14582,7 +14712,7 @@ async function startAuthorization(authorizationServerUrl, { metadata, clientInfo
14582
14712
  authorizationUrl.searchParams.append("prompt", "consent");
14583
14713
  }
14584
14714
  if (resource) {
14585
- authorizationUrl.searchParams.set("resource", resource.href);
14715
+ authorizationUrl.searchParams.set("resource", resourceIndicatorToString(resource));
14586
14716
  }
14587
14717
  return { authorizationUrl, codeVerifier };
14588
14718
  }
@@ -14601,7 +14731,7 @@ async function executeTokenRequest(authorizationServerUrl, { metadata, tokenRequ
14601
14731
  Accept: "application/json"
14602
14732
  });
14603
14733
  if (resource) {
14604
- tokenRequestParams.set("resource", resource.href);
14734
+ tokenRequestParams.set("resource", resourceIndicatorToString(resource));
14605
14735
  }
14606
14736
  if (addClientAuthentication) {
14607
14737
  await addClientAuthentication(headers, tokenRequestParams, tokenUrl, metadata);
@@ -14610,7 +14740,7 @@ async function executeTokenRequest(authorizationServerUrl, { metadata, tokenRequ
14610
14740
  const authMethod = selectClientAuthMethod(clientInformation, supportedMethods);
14611
14741
  applyClientAuthentication(authMethod, clientInformation, headers, tokenRequestParams);
14612
14742
  }
14613
- const response = await (fetchFn ?? fetch)(tokenUrl, {
14743
+ const response = await fetchWithinOrigin(fetchFn ?? fetch)(tokenUrl, {
14614
14744
  method: "POST",
14615
14745
  headers,
14616
14746
  body: tokenRequestParams
@@ -14618,7 +14748,7 @@ async function executeTokenRequest(authorizationServerUrl, { metadata, tokenRequ
14618
14748
  if (!response.ok) {
14619
14749
  throw await parseErrorResponse(response);
14620
14750
  }
14621
- return OAuthTokensSchema.parse(await response.json());
14751
+ return TokenResponseSchema.parse(await response.json());
14622
14752
  }
14623
14753
  async function refreshAuthorization(authorizationServerUrl, { metadata, clientInformation, refreshToken, resource, addClientAuthentication, fetchFn }) {
14624
14754
  const tokenRequestParams = new URLSearchParams({
@@ -14636,6 +14766,15 @@ async function refreshAuthorization(authorizationServerUrl, { metadata, clientIn
14636
14766
  return { refresh_token: refreshToken, ...tokens };
14637
14767
  }
14638
14768
  async function fetchToken(provider, authorizationServerUrl, { metadata, resource, authorizationCode, fetchFn } = {}) {
14769
+ const readClientInformation = async () => {
14770
+ const storedClientInformation = await provider.clientInformation();
14771
+ const checked = discardIfIssuerMismatch(storedClientInformation, String(authorizationServerUrl));
14772
+ if (storedClientInformation && !checked) {
14773
+ throw boundElsewhereError(storedClientInformation, String(authorizationServerUrl));
14774
+ }
14775
+ return checked;
14776
+ };
14777
+ let clientInformation = await readClientInformation();
14639
14778
  const scope = provider.clientMetadata.scope;
14640
14779
  let tokenRequestParams;
14641
14780
  if (provider.prepareTokenRequest) {
@@ -14651,11 +14790,11 @@ async function fetchToken(provider, authorizationServerUrl, { metadata, resource
14651
14790
  const codeVerifier = await provider.codeVerifier();
14652
14791
  tokenRequestParams = prepareAuthorizationCodeRequest(authorizationCode, codeVerifier, provider.redirectUrl);
14653
14792
  }
14654
- const clientInformation = await provider.clientInformation();
14793
+ clientInformation ?? (clientInformation = await readClientInformation());
14655
14794
  return executeTokenRequest(authorizationServerUrl, {
14656
14795
  metadata,
14657
14796
  tokenRequestParams,
14658
- clientInformation: clientInformation ?? undefined,
14797
+ clientInformation,
14659
14798
  addClientAuthentication: provider.addClientAuthentication,
14660
14799
  resource,
14661
14800
  fetchFn
@@ -14671,7 +14810,7 @@ async function registerClient(authorizationServerUrl, { metadata, clientMetadata
14671
14810
  } else {
14672
14811
  registrationUrl = new URL("/register", authorizationServerUrl);
14673
14812
  }
14674
- const response = await (fetchFn ?? fetch)(registrationUrl, {
14813
+ const response = await fetchWithinOrigin(fetchFn ?? fetch)(registrationUrl, {
14675
14814
  method: "POST",
14676
14815
  headers: {
14677
14816
  "Content-Type": "application/json"
@@ -14684,7 +14823,7 @@ async function registerClient(authorizationServerUrl, { metadata, clientMetadata
14684
14823
  if (!response.ok) {
14685
14824
  throw await parseErrorResponse(response);
14686
14825
  }
14687
- return OAuthClientInformationFullSchema.parse(await response.json());
14826
+ return RegistrationResponseSchema.parse(await response.json());
14688
14827
  }
14689
14828
  // node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js
14690
14829
  function isZ4Schema(s) {
@@ -14817,6 +14956,9 @@ class Protocol {
14817
14956
  this.setRequestHandler(GetTaskPayloadRequestSchema, async (request, extra) => {
14818
14957
  const handleTaskResult = async () => {
14819
14958
  const taskId = request.params.taskId;
14959
+ if (!await this._taskStore.getTask(taskId, extra.sessionId)) {
14960
+ throw new McpError(ErrorCode.InvalidParams, `Task not found: ${taskId}`);
14961
+ }
14820
14962
  if (this._taskMessageQueue) {
14821
14963
  let queuedMessage;
14822
14964
  while (queuedMessage = await this._taskMessageQueue.dequeue(taskId, extra.sessionId)) {
@@ -14847,12 +14989,12 @@ class Protocol {
14847
14989
  throw new McpError(ErrorCode.InvalidParams, `Task not found: ${taskId}`);
14848
14990
  }
14849
14991
  if (!isTerminal(task.status)) {
14850
- await this._waitForTaskUpdate(taskId, extra.signal);
14992
+ await this._waitForTaskUpdate(taskId, extra.signal, extra.sessionId);
14851
14993
  return await handleTaskResult();
14852
14994
  }
14853
14995
  if (isTerminal(task.status)) {
14854
14996
  const result = await this._taskStore.getTaskResult(taskId, extra.sessionId);
14855
- this._clearTaskQueue(taskId);
14997
+ this._clearTaskQueue(taskId, extra.sessionId);
14856
14998
  return {
14857
14999
  ...result,
14858
15000
  _meta: {
@@ -14889,7 +15031,7 @@ class Protocol {
14889
15031
  throw new McpError(ErrorCode.InvalidParams, `Cannot cancel task in terminal status: ${task.status}`);
14890
15032
  }
14891
15033
  await this._taskStore.updateTaskStatus(request.params.taskId, "cancelled", "Client cancelled task execution.", extra.sessionId);
14892
- this._clearTaskQueue(request.params.taskId);
15034
+ this._clearTaskQueue(request.params.taskId, extra.sessionId);
14893
15035
  const cancelledTask = await this._taskStore.getTask(request.params.taskId, extra.sessionId);
14894
15036
  if (!cancelledTask) {
14895
15037
  throw new McpError(ErrorCode.InvalidParams, `Task not found after cancellation: ${request.params.taskId}`);
@@ -15012,6 +15154,19 @@ class Protocol {
15012
15154
  const handler = this._requestHandlers.get(request.method) ?? this.fallbackRequestHandler;
15013
15155
  const capturedTransport = this._transport;
15014
15156
  const relatedTaskId = request.params?._meta?.[RELATED_TASK_META_KEY]?.taskId;
15157
+ const sessionId = capturedTransport?.sessionId;
15158
+ const store = this._taskStore;
15159
+ let relatedTaskFound = true;
15160
+ let relatedTaskLookup;
15161
+ if (relatedTaskId && store && this._taskMessageQueue && sessionId !== undefined) {
15162
+ relatedTaskFound = false;
15163
+ relatedTaskLookup = (async () => {
15164
+ if (!await store.getTask(relatedTaskId, sessionId)) {
15165
+ throw new McpError(ErrorCode.InvalidParams, `Task not found: ${relatedTaskId}`);
15166
+ }
15167
+ relatedTaskFound = true;
15168
+ })();
15169
+ }
15015
15170
  if (handler === undefined) {
15016
15171
  const errorResponse = {
15017
15172
  jsonrpc: "2.0",
@@ -15021,7 +15176,10 @@ class Protocol {
15021
15176
  message: "Method not found"
15022
15177
  }
15023
15178
  };
15024
- if (relatedTaskId && this._taskMessageQueue) {
15179
+ if (relatedTaskId && relatedTaskLookup) {
15180
+ const queuedError = { type: "error", message: errorResponse, timestamp: Date.now() };
15181
+ relatedTaskLookup.then(() => this._enqueueTaskMessage(relatedTaskId, queuedError, sessionId), () => capturedTransport?.send(errorResponse)).catch((error2) => this._onerror(new Error(`Failed to send an error response: ${error2}`)));
15182
+ } else if (relatedTaskId && this._taskMessageQueue) {
15025
15183
  this._enqueueTaskMessage(relatedTaskId, {
15026
15184
  type: "error",
15027
15185
  message: errorResponse,
@@ -15072,7 +15230,10 @@ class Protocol {
15072
15230
  closeSSEStream: extra?.closeSSEStream,
15073
15231
  closeStandaloneSSEStream: extra?.closeStandaloneSSEStream
15074
15232
  };
15075
- Promise.resolve().then(() => {
15233
+ (relatedTaskLookup ?? Promise.resolve()).then(() => {
15234
+ if (relatedTaskLookup && abortController.signal.aborted) {
15235
+ throw new McpError(ErrorCode.ConnectionClosed, "Request was cancelled");
15236
+ }
15076
15237
  if (taskCreationParams) {
15077
15238
  this.assertTaskHandlerCapability(request.method);
15078
15239
  }
@@ -15107,7 +15268,7 @@ class Protocol {
15107
15268
  ...error2["data"] !== undefined && { data: error2["data"] }
15108
15269
  }
15109
15270
  };
15110
- if (relatedTaskId && this._taskMessageQueue) {
15271
+ if (relatedTaskId && this._taskMessageQueue && relatedTaskFound) {
15111
15272
  await this._enqueueTaskMessage(relatedTaskId, {
15112
15273
  type: "error",
15113
15274
  message: errorResponse,
@@ -15495,7 +15656,7 @@ class Protocol {
15495
15656
  throw new Error("Cannot enqueue task message: taskStore and taskMessageQueue are not configured");
15496
15657
  }
15497
15658
  const maxQueueSize = this._options?.maxTaskQueueSize;
15498
- await this._taskMessageQueue.enqueue(taskId, message, sessionId, maxQueueSize);
15659
+ await this._taskMessageQueue.enqueue(taskId, message, sessionId ?? this._transport?.sessionId, maxQueueSize);
15499
15660
  }
15500
15661
  async _clearTaskQueue(taskId, sessionId) {
15501
15662
  if (this._taskMessageQueue) {
@@ -15514,10 +15675,10 @@ class Protocol {
15514
15675
  }
15515
15676
  }
15516
15677
  }
15517
- async _waitForTaskUpdate(taskId, signal) {
15678
+ async _waitForTaskUpdate(taskId, signal, sessionId) {
15518
15679
  let interval = this._options?.defaultTaskPollInterval ?? 1000;
15519
15680
  try {
15520
- const task = await this._taskStore?.getTask(taskId);
15681
+ const task = await this._taskStore?.getTask(taskId, sessionId);
15521
15682
  if (task?.pollInterval) {
15522
15683
  interval = task.pollInterval;
15523
15684
  }
@@ -16573,32 +16734,6 @@ function getBaseURL() {
16573
16734
  return doc2 && typeof doc2 == "object" && "baseURI" in doc2 && typeof doc2.baseURI == "string" ? doc2.baseURI : undefined;
16574
16735
  }
16575
16736
 
16576
- // node_modules/@modelcontextprotocol/sdk/dist/esm/shared/transport.js
16577
- function normalizeHeaders(headers) {
16578
- if (!headers)
16579
- return {};
16580
- if (headers instanceof Headers) {
16581
- return Object.fromEntries(headers.entries());
16582
- }
16583
- if (Array.isArray(headers)) {
16584
- return Object.fromEntries(headers);
16585
- }
16586
- return { ...headers };
16587
- }
16588
- function createFetchWithInit(baseFetch = fetch, baseInit) {
16589
- if (!baseInit) {
16590
- return baseFetch;
16591
- }
16592
- return async (url2, init) => {
16593
- const mergedInit = {
16594
- ...baseInit,
16595
- ...init,
16596
- headers: init?.headers ? { ...normalizeHeaders(baseInit.headers), ...normalizeHeaders(init.headers) } : baseInit.headers
16597
- };
16598
- return baseFetch(url2, mergedInit);
16599
- };
16600
- }
16601
-
16602
16737
  // node_modules/@modelcontextprotocol/sdk/dist/esm/client/sse.js
16603
16738
  class SseError extends Error {
16604
16739
  constructor(code, message, event) {
@@ -16618,6 +16753,15 @@ class SSEClientTransport {
16618
16753
  this._authProvider = opts?.authProvider;
16619
16754
  this._fetch = opts?.fetch;
16620
16755
  this._fetchWithInit = createFetchWithInit(opts?.fetch, opts?.requestInit);
16756
+ this._followRedirects = opts?.redirectPolicy === "follow";
16757
+ if (this._followRedirects) {
16758
+ this._fetch = fetchLeavingRedirects(this._fetch);
16759
+ this._fetchWithInit = fetchLeavingRedirects(this._fetchWithInit);
16760
+ }
16761
+ }
16762
+ _unfollowedRedirect(response, url2) {
16763
+ const text = unfollowedRedirect(response, url2);
16764
+ return text && !this._followRedirects ? `${text} (redirectPolicy: 'same-origin')` : text;
16621
16765
  }
16622
16766
  async _authThenStart() {
16623
16767
  if (!this._authProvider) {
@@ -16658,7 +16802,9 @@ class SSEClientTransport {
16658
16802
  });
16659
16803
  }
16660
16804
  _startOrAuth() {
16661
- const fetchImpl = this?._eventSourceInit?.fetch ?? this._fetch ?? fetch;
16805
+ const baseFetch = this?._eventSourceInit?.fetch ?? this._fetch ?? fetch;
16806
+ const fetchImpl = this._followRedirects ? baseFetch : fetchWithinOrigin(baseFetch);
16807
+ let redirect;
16662
16808
  return new Promise((resolve, reject) => {
16663
16809
  this._eventSource = new EventSource(this._url.href, {
16664
16810
  ...this._eventSourceInit,
@@ -16669,6 +16815,7 @@ class SSEClientTransport {
16669
16815
  ...init,
16670
16816
  headers
16671
16817
  });
16818
+ redirect = this._unfollowedRedirect(response, url2);
16672
16819
  if (response.status === 401 && response.headers.has("www-authenticate")) {
16673
16820
  const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);
16674
16821
  this._resourceMetadataUrl = resourceMetadataUrl;
@@ -16683,7 +16830,7 @@ class SSEClientTransport {
16683
16830
  this._authThenStart().then(resolve, reject);
16684
16831
  return;
16685
16832
  }
16686
- const error2 = new SseError(event.code, event.message, event);
16833
+ const error2 = new SseError(event.code, redirect ?? event.message, event);
16687
16834
  reject(error2);
16688
16835
  this.onerror?.(error2);
16689
16836
  };
@@ -16756,7 +16903,7 @@ class SSEClientTransport {
16756
16903
  body: JSON.stringify(message),
16757
16904
  signal: this._abortController?.signal
16758
16905
  };
16759
- const response = await (this._fetch ?? fetch)(this._endpoint, init);
16906
+ const response = await fetchWithinOrigin(this._fetch ?? fetch)(this._endpoint, init);
16760
16907
  if (!response.ok) {
16761
16908
  const text = await response.text().catch(() => null);
16762
16909
  if (response.status === 401 && this._authProvider) {
@@ -16774,7 +16921,7 @@ class SSEClientTransport {
16774
16921
  }
16775
16922
  return this.send(message);
16776
16923
  }
16777
- throw new Error(`Error POSTing to endpoint (HTTP ${response.status}): ${text}`);
16924
+ throw new Error(`Error POSTing to endpoint (HTTP ${response.status}): ${this._unfollowedRedirect(response, this._endpoint) ?? text}`);
16778
16925
  }
16779
16926
  await response.body?.cancel();
16780
16927
  } catch (error2) {
@@ -17048,9 +17195,18 @@ class StreamableHTTPClientTransport {
17048
17195
  this._authProvider = opts?.authProvider;
17049
17196
  this._fetch = opts?.fetch;
17050
17197
  this._fetchWithInit = createFetchWithInit(opts?.fetch, opts?.requestInit);
17198
+ this._followRedirects = opts?.redirectPolicy === "follow";
17199
+ if (this._followRedirects) {
17200
+ this._fetch = fetchLeavingRedirects(this._fetch);
17201
+ this._fetchWithInit = fetchLeavingRedirects(this._fetchWithInit);
17202
+ }
17051
17203
  this._sessionId = opts?.sessionId;
17052
17204
  this._reconnectionOptions = opts?.reconnectionOptions ?? DEFAULT_STREAMABLE_HTTP_RECONNECTION_OPTIONS;
17053
17205
  }
17206
+ _unfollowedRedirect(response, url2) {
17207
+ const text = unfollowedRedirect(response, url2);
17208
+ return text && !this._followRedirects ? `${text} (redirectPolicy: 'same-origin')` : text;
17209
+ }
17054
17210
  async _authThenStart() {
17055
17211
  if (!this._authProvider) {
17056
17212
  throw new UnauthorizedError("No auth provider");
@@ -17100,11 +17256,13 @@ class StreamableHTTPClientTransport {
17100
17256
  if (resumptionToken) {
17101
17257
  headers.set("last-event-id", resumptionToken);
17102
17258
  }
17103
- const response = await (this._fetch ?? fetch)(this._url, {
17104
- method: "GET",
17105
- headers,
17106
- signal: this._abortController?.signal
17107
- });
17259
+ const fetchFn = this._fetch ?? fetch;
17260
+ const init = { method: "GET", headers, signal: this._abortController?.signal };
17261
+ let response = await fetchFn(this._url, this._followRedirects ? init : { ...init, redirect: "manual" });
17262
+ const followed = this._followRedirects ? undefined : followWithinOrigin(fetchFn, this._url, init, response);
17263
+ if (followed) {
17264
+ response = await followed;
17265
+ }
17108
17266
  if (!response.ok) {
17109
17267
  await response.body?.cancel();
17110
17268
  if (response.status === 401 && this._authProvider) {
@@ -17113,7 +17271,7 @@ class StreamableHTTPClientTransport {
17113
17271
  if (response.status === 405) {
17114
17272
  return;
17115
17273
  }
17116
- throw new StreamableHTTPError(response.status, `Failed to open SSE stream: ${response.statusText}`);
17274
+ throw new StreamableHTTPError(response.status, `Failed to open SSE stream: ${this._unfollowedRedirect(response, this._url) ?? response.statusText}`);
17117
17275
  }
17118
17276
  this._handleSseStream(response.body, options, true);
17119
17277
  } catch (error2) {
@@ -17261,7 +17419,7 @@ class StreamableHTTPClientTransport {
17261
17419
  body: JSON.stringify(message),
17262
17420
  signal: this._abortController?.signal
17263
17421
  };
17264
- const response = await (this._fetch ?? fetch)(this._url, init);
17422
+ const response = await fetchWithinOrigin(this._fetch ?? fetch)(this._url, init);
17265
17423
  const sessionId = response.headers.get("mcp-session-id");
17266
17424
  if (sessionId) {
17267
17425
  this._sessionId = sessionId;
@@ -17313,7 +17471,7 @@ class StreamableHTTPClientTransport {
17313
17471
  return this.send(message);
17314
17472
  }
17315
17473
  }
17316
- throw new StreamableHTTPError(response.status, `Error POSTing to endpoint: ${text}`);
17474
+ throw new StreamableHTTPError(response.status, `Error POSTing to endpoint: ${this._unfollowedRedirect(response, this._url) ?? text}`);
17317
17475
  }
17318
17476
  this._hasCompletedAuthFlow = false;
17319
17477
  this._lastUpscopingHeader = undefined;
@@ -17364,10 +17522,10 @@ class StreamableHTTPClientTransport {
17364
17522
  headers,
17365
17523
  signal: this._abortController?.signal
17366
17524
  };
17367
- const response = await (this._fetch ?? fetch)(this._url, init);
17525
+ const response = await fetchWithinOrigin(this._fetch ?? fetch)(this._url, init);
17368
17526
  await response.body?.cancel();
17369
17527
  if (!response.ok && response.status !== 405) {
17370
- throw new StreamableHTTPError(response.status, `Failed to terminate session: ${response.statusText}`);
17528
+ throw new StreamableHTTPError(response.status, `Failed to terminate session: ${this._unfollowedRedirect(response, this._url) ?? response.statusText}`);
17371
17529
  }
17372
17530
  this._sessionId = undefined;
17373
17531
  } catch (error2) {
@@ -17392,7 +17550,7 @@ class StreamableHTTPClientTransport {
17392
17550
  // src/mcp-client.ts
17393
17551
  var DEFAULT_CLIENT_INFO = {
17394
17552
  name: "letta-code",
17395
- version: "0.34.25"
17553
+ version: "0.34.26"
17396
17554
  };
17397
17555
  async function connectMcpServer(config2, options = {}) {
17398
17556
  let client = new Client(options.clientInfo ?? DEFAULT_CLIENT_INFO);
@@ -18608,4 +18766,4 @@ export {
18608
18766
  authorizeMcpServerWithStorage
18609
18767
  };
18610
18768
 
18611
- //# debugId=8A4B00AF1E8A20D764756E2164756E21
18769
+ //# debugId=34827806B038DB6564756E2164756E21