@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
@@ -13452,7 +13452,8 @@ var OAuthTokensSchema = object({
13452
13452
  token_type: string2(),
13453
13453
  expires_in: exports_coerce.number().optional(),
13454
13454
  scope: string2().optional(),
13455
- refresh_token: string2().optional()
13455
+ refresh_token: string2().optional(),
13456
+ issuer: string2().optional().catch(undefined)
13456
13457
  }).strip();
13457
13458
  var OAuthErrorResponseSchema = object({
13458
13459
  error: string2(),
@@ -13484,7 +13485,8 @@ var OAuthClientInformationSchema = object({
13484
13485
  client_id: string2(),
13485
13486
  client_secret: string2().optional(),
13486
13487
  client_id_issued_at: number2().optional(),
13487
- client_secret_expires_at: number2().optional()
13488
+ client_secret_expires_at: number2().optional(),
13489
+ issuer: string2().optional().catch(undefined)
13488
13490
  }).strip();
13489
13491
  var OAuthClientInformationFullSchema = OAuthClientMetadataSchema.merge(OAuthClientInformationSchema);
13490
13492
  var OAuthClientRegistrationErrorSchema = object({
@@ -13625,6 +13627,94 @@ var OAUTH_ERRORS = {
13625
13627
  [InvalidTargetError.errorCode]: InvalidTargetError
13626
13628
  };
13627
13629
 
13630
+ // node_modules/@modelcontextprotocol/sdk/dist/esm/shared/transport.js
13631
+ function normalizeHeaders(headers) {
13632
+ if (!headers)
13633
+ return {};
13634
+ if (headers instanceof Headers) {
13635
+ return Object.fromEntries(headers.entries());
13636
+ }
13637
+ if (Array.isArray(headers)) {
13638
+ return Object.fromEntries(headers);
13639
+ }
13640
+ return { ...headers };
13641
+ }
13642
+ function createFetchWithInit(baseFetch = fetch, baseInit) {
13643
+ if (!baseInit) {
13644
+ return baseFetch;
13645
+ }
13646
+ return async (url2, init) => {
13647
+ const mergedInit = {
13648
+ ...baseInit,
13649
+ ...init,
13650
+ headers: init?.headers ? { ...normalizeHeaders(baseInit.headers), ...normalizeHeaders(init.headers) } : baseInit.headers
13651
+ };
13652
+ return baseFetch(url2, mergedInit);
13653
+ };
13654
+ }
13655
+ var MAX_REDIRECTS = 5;
13656
+ var REDIRECT_STATUSES = [301, 302, 303, 307, 308];
13657
+ function isWithinOrigin(from, to) {
13658
+ if (from.protocol === to.protocol && from.hostname === to.hostname && from.port === to.port) {
13659
+ return true;
13660
+ }
13661
+ return from.hostname === to.hostname && from.protocol === "http:" && from.port === "" && to.protocol === "https:" && to.port === "";
13662
+ }
13663
+ function redirectTarget(response, requestUrl) {
13664
+ const location = REDIRECT_STATUSES.includes(response.status) ? response.headers.get("location") : null;
13665
+ try {
13666
+ return location ? new URL(location, requestUrl) : undefined;
13667
+ } catch {
13668
+ return;
13669
+ }
13670
+ }
13671
+ function followWithinOrigin(baseFetch, url2, init, response, followed = 0) {
13672
+ const target = redirectTarget(response, url2);
13673
+ const keepsMethod = response.status === 307 || response.status === 308 || (init?.method ?? "GET").toUpperCase() === "GET";
13674
+ if (!target || followed === MAX_REDIRECTS || !keepsMethod) {
13675
+ return;
13676
+ }
13677
+ const from = new URL(url2);
13678
+ const addsUserinfo = (target.username || target.password) && (target.username !== from.username || target.password !== from.password);
13679
+ if (addsUserinfo || !isWithinOrigin(from, target)) {
13680
+ return;
13681
+ }
13682
+ return Promise.resolve(response.body?.cancel()).then(() => baseFetch(target, { ...init, redirect: "manual" })).then((next) => followWithinOrigin(baseFetch, target, init, next, followed + 1) ?? next);
13683
+ }
13684
+ var followingFetches = new WeakSet;
13685
+ function fetchLeavingRedirects(baseFetch) {
13686
+ const following = (url2, init) => (baseFetch ?? fetch)(url2, init);
13687
+ followingFetches.add(following);
13688
+ return following;
13689
+ }
13690
+ function fetchWithinOrigin(baseFetch = fetch) {
13691
+ if (followingFetches.has(baseFetch)) {
13692
+ return baseFetch;
13693
+ }
13694
+ return (url2, init) => {
13695
+ if (init?.redirect === "error" || init?.redirect === "manual") {
13696
+ return baseFetch(url2, init);
13697
+ }
13698
+ return Promise.resolve(baseFetch(url2, { ...init, redirect: "manual" })).then((response) => followWithinOrigin(baseFetch, url2, init, response) ?? response);
13699
+ };
13700
+ }
13701
+ function unfollowedRedirect(response, requestUrl) {
13702
+ if (response.type === "opaqueredirect") {
13703
+ return "Redirect not followed: this runtime does not expose the redirect target";
13704
+ }
13705
+ const from = response.url || requestUrl;
13706
+ const target = redirectTarget(response, from);
13707
+ if (!target) {
13708
+ return;
13709
+ }
13710
+ target.username = target.password = target.search = target.hash = "";
13711
+ if (target.protocol === "http:" && new URL(from).protocol === "https:") {
13712
+ target.protocol = "https:";
13713
+ return `Redirect to plain http not followed; try ${target.href} instead`;
13714
+ }
13715
+ return `Redirect to ${target.href} not followed`;
13716
+ }
13717
+
13628
13718
  // node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth.js
13629
13719
  class UnauthorizedError extends Error {
13630
13720
  constructor(message) {
@@ -13696,10 +13786,30 @@ async function parseErrorResponse(input) {
13696
13786
  const errorClass = OAUTH_ERRORS[error2] || ServerError;
13697
13787
  return new errorClass(error_description || "", error_uri);
13698
13788
  } catch (error2) {
13699
- const errorMessage = `${statusCode ? `HTTP ${statusCode}: ` : ""}Invalid OAuth error response: ${error2}. Raw body: ${body}`;
13789
+ const redirect = input instanceof Response ? unfollowedRedirect(input, input.url) : undefined;
13790
+ const errorMessage = `${statusCode ? `HTTP ${statusCode}: ` : ""}${redirect ?? `Invalid OAuth error response: ${error2}. Raw body: ${body}`}`;
13700
13791
  return new ServerError(errorMessage);
13701
13792
  }
13702
13793
  }
13794
+ function issuersMatch(a, b) {
13795
+ let [x, y] = [a, b];
13796
+ try {
13797
+ [x, y] = [new URL(a).href, new URL(b).href];
13798
+ } catch {}
13799
+ return x === y || x.endsWith("/") && x.slice(0, -1) === y || y.endsWith("/") && y.slice(0, -1) === x;
13800
+ }
13801
+ function discardIfIssuerMismatch(stored, issuer) {
13802
+ if (!stored)
13803
+ return;
13804
+ if (typeof stored.issuer !== "string")
13805
+ return stored.issuer == null ? stored : { ...stored, issuer: undefined };
13806
+ return issuersMatch(stored.issuer, issuer) ? stored : undefined;
13807
+ }
13808
+ var TokenResponseSchema = OAuthTokensSchema.omit({ issuer: true });
13809
+ var RegistrationResponseSchema = OAuthClientInformationFullSchema.omit({ issuer: true });
13810
+ function boundElsewhereError(stored, issuer) {
13811
+ 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.");
13812
+ }
13703
13813
  async function auth(provider, options) {
13704
13814
  try {
13705
13815
  return await authInternal(provider, options);
@@ -13752,9 +13862,23 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
13752
13862
  authorizationServerMetadata: metadata
13753
13863
  });
13754
13864
  }
13755
- const resource = await selectResourceURL(serverUrl, provider, resourceMetadata);
13865
+ const issuer = String(authorizationServerUrl);
13866
+ const selectedResource = await selectResourceURL(serverUrl, provider, resourceMetadata);
13867
+ const resource = selectedResource && resourceMetadata && !provider.validateResourceURL ? resourceMetadata.resource : selectedResource;
13756
13868
  const resolvedScope = scope || resourceMetadata?.scopes_supported?.join(" ") || provider.clientMetadata.scope;
13757
- let clientInformation = await Promise.resolve(provider.clientInformation());
13869
+ const storedClientInformation = await Promise.resolve(provider.clientInformation());
13870
+ let clientInformation = discardIfIssuerMismatch(storedClientInformation, issuer);
13871
+ const canRegisterAgain = provider.saveClientInformation !== undefined && !!provider.redirectUrl;
13872
+ if (storedClientInformation && !clientInformation && !canRegisterAgain) {
13873
+ throw boundElsewhereError(storedClientInformation, issuer);
13874
+ }
13875
+ const unstampedClientInformation = clientInformation?.issuer == null ? clientInformation : undefined;
13876
+ const bindClientInformation = async () => {
13877
+ try {
13878
+ if (unstampedClientInformation)
13879
+ await provider.saveClientInformation?.({ ...unstampedClientInformation, issuer });
13880
+ } catch {}
13881
+ };
13758
13882
  if (!clientInformation) {
13759
13883
  if (authorizationCode !== undefined) {
13760
13884
  throw new Error("Existing OAuth client information is required when exchanging an authorization code");
@@ -13766,9 +13890,7 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
13766
13890
  }
13767
13891
  const shouldUseUrlBasedClientId = supportsUrlBasedClientId && clientMetadataUrl;
13768
13892
  if (shouldUseUrlBasedClientId) {
13769
- clientInformation = {
13770
- client_id: clientMetadataUrl
13771
- };
13893
+ clientInformation = { client_id: clientMetadataUrl, issuer };
13772
13894
  await provider.saveClientInformation?.(clientInformation);
13773
13895
  } else {
13774
13896
  if (!provider.saveClientInformation) {
@@ -13780,8 +13902,8 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
13780
13902
  scope: resolvedScope,
13781
13903
  fetchFn
13782
13904
  });
13783
- await provider.saveClientInformation(fullInformation);
13784
- clientInformation = fullInformation;
13905
+ clientInformation = { ...fullInformation, issuer };
13906
+ await provider.saveClientInformation(clientInformation);
13785
13907
  }
13786
13908
  }
13787
13909
  const nonInteractiveFlow = !provider.redirectUrl;
@@ -13792,10 +13914,14 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
13792
13914
  authorizationCode,
13793
13915
  fetchFn
13794
13916
  });
13795
- await provider.saveTokens(tokens2);
13917
+ await bindClientInformation();
13918
+ await provider.saveTokens({ ...tokens2, issuer });
13796
13919
  return "AUTHORIZED";
13797
13920
  }
13798
- const tokens = await provider.tokens();
13921
+ const tokens = discardIfIssuerMismatch(await provider.tokens(), issuer);
13922
+ if (tokens?.refresh_token && tokens.issuer == null) {
13923
+ 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.");
13924
+ }
13799
13925
  if (tokens?.refresh_token) {
13800
13926
  try {
13801
13927
  const newTokens = await refreshAuthorization(authorizationServerUrl, {
@@ -13806,7 +13932,8 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
13806
13932
  addClientAuthentication: provider.addClientAuthentication,
13807
13933
  fetchFn
13808
13934
  });
13809
- await provider.saveTokens(newTokens);
13935
+ await bindClientInformation();
13936
+ await provider.saveTokens({ ...newTokens, issuer });
13810
13937
  return "AUTHORIZED";
13811
13938
  } catch (error2) {
13812
13939
  if (!(error2 instanceof OAuthError) || error2 instanceof ServerError) {} else {
@@ -13903,7 +14030,7 @@ async function discoverOAuthProtectedResourceMetadata(serverUrl, opts, fetchFn =
13903
14030
  }
13904
14031
  async function fetchWithCorsRetry(url2, headers, fetchFn = fetch) {
13905
14032
  try {
13906
- return await fetchFn(url2, { headers });
14033
+ return await fetchWithinOrigin(fetchFn)(url2, { headers });
13907
14034
  } catch (error2) {
13908
14035
  if (error2 instanceof TypeError) {
13909
14036
  if (headers) {
@@ -13928,7 +14055,7 @@ async function tryMetadataDiscovery(url2, protocolVersion, fetchFn = fetch) {
13928
14055
  return await fetchWithCorsRetry(url2, headers, fetchFn);
13929
14056
  }
13930
14057
  function shouldAttemptFallback(response, pathname) {
13931
- return !response || response.status >= 400 && response.status < 500 && pathname !== "/";
14058
+ return !response || !response.ok && response.status < 500 && pathname !== "/";
13932
14059
  }
13933
14060
  async function discoverMetadataWithFallback(serverUrl, wellKnownType, fetchFn, opts) {
13934
14061
  const issuer = new URL(serverUrl);
@@ -13994,7 +14121,7 @@ async function discoverAuthorizationServerMetadata(authorizationServerUrl, { fet
13994
14121
  }
13995
14122
  if (!response.ok) {
13996
14123
  await response.body?.cancel();
13997
- if (response.status >= 400 && response.status < 500) {
14124
+ if (response.status < 500) {
13998
14125
  continue;
13999
14126
  }
14000
14127
  throw new Error(`HTTP ${response.status} trying to load ${type === "oauth" ? "OAuth" : "OpenID provider"} metadata from ${endpointUrl}`);
@@ -14026,6 +14153,9 @@ async function discoverOAuthServerInfo(serverUrl, opts) {
14026
14153
  resourceMetadata
14027
14154
  };
14028
14155
  }
14156
+ function resourceIndicatorToString(resource) {
14157
+ return typeof resource === "string" ? resource : resource.href;
14158
+ }
14029
14159
  async function startAuthorization(authorizationServerUrl, { metadata, clientInformation, redirectUrl, scope, state, resource }) {
14030
14160
  let authorizationUrl;
14031
14161
  if (metadata) {
@@ -14057,7 +14187,7 @@ async function startAuthorization(authorizationServerUrl, { metadata, clientInfo
14057
14187
  authorizationUrl.searchParams.append("prompt", "consent");
14058
14188
  }
14059
14189
  if (resource) {
14060
- authorizationUrl.searchParams.set("resource", resource.href);
14190
+ authorizationUrl.searchParams.set("resource", resourceIndicatorToString(resource));
14061
14191
  }
14062
14192
  return { authorizationUrl, codeVerifier };
14063
14193
  }
@@ -14076,7 +14206,7 @@ async function executeTokenRequest(authorizationServerUrl, { metadata, tokenRequ
14076
14206
  Accept: "application/json"
14077
14207
  });
14078
14208
  if (resource) {
14079
- tokenRequestParams.set("resource", resource.href);
14209
+ tokenRequestParams.set("resource", resourceIndicatorToString(resource));
14080
14210
  }
14081
14211
  if (addClientAuthentication) {
14082
14212
  await addClientAuthentication(headers, tokenRequestParams, tokenUrl, metadata);
@@ -14085,7 +14215,7 @@ async function executeTokenRequest(authorizationServerUrl, { metadata, tokenRequ
14085
14215
  const authMethod = selectClientAuthMethod(clientInformation, supportedMethods);
14086
14216
  applyClientAuthentication(authMethod, clientInformation, headers, tokenRequestParams);
14087
14217
  }
14088
- const response = await (fetchFn ?? fetch)(tokenUrl, {
14218
+ const response = await fetchWithinOrigin(fetchFn ?? fetch)(tokenUrl, {
14089
14219
  method: "POST",
14090
14220
  headers,
14091
14221
  body: tokenRequestParams
@@ -14093,7 +14223,7 @@ async function executeTokenRequest(authorizationServerUrl, { metadata, tokenRequ
14093
14223
  if (!response.ok) {
14094
14224
  throw await parseErrorResponse(response);
14095
14225
  }
14096
- return OAuthTokensSchema.parse(await response.json());
14226
+ return TokenResponseSchema.parse(await response.json());
14097
14227
  }
14098
14228
  async function refreshAuthorization(authorizationServerUrl, { metadata, clientInformation, refreshToken, resource, addClientAuthentication, fetchFn }) {
14099
14229
  const tokenRequestParams = new URLSearchParams({
@@ -14111,6 +14241,15 @@ async function refreshAuthorization(authorizationServerUrl, { metadata, clientIn
14111
14241
  return { refresh_token: refreshToken, ...tokens };
14112
14242
  }
14113
14243
  async function fetchToken(provider, authorizationServerUrl, { metadata, resource, authorizationCode, fetchFn } = {}) {
14244
+ const readClientInformation = async () => {
14245
+ const storedClientInformation = await provider.clientInformation();
14246
+ const checked = discardIfIssuerMismatch(storedClientInformation, String(authorizationServerUrl));
14247
+ if (storedClientInformation && !checked) {
14248
+ throw boundElsewhereError(storedClientInformation, String(authorizationServerUrl));
14249
+ }
14250
+ return checked;
14251
+ };
14252
+ let clientInformation = await readClientInformation();
14114
14253
  const scope = provider.clientMetadata.scope;
14115
14254
  let tokenRequestParams;
14116
14255
  if (provider.prepareTokenRequest) {
@@ -14126,11 +14265,11 @@ async function fetchToken(provider, authorizationServerUrl, { metadata, resource
14126
14265
  const codeVerifier = await provider.codeVerifier();
14127
14266
  tokenRequestParams = prepareAuthorizationCodeRequest(authorizationCode, codeVerifier, provider.redirectUrl);
14128
14267
  }
14129
- const clientInformation = await provider.clientInformation();
14268
+ clientInformation ?? (clientInformation = await readClientInformation());
14130
14269
  return executeTokenRequest(authorizationServerUrl, {
14131
14270
  metadata,
14132
14271
  tokenRequestParams,
14133
- clientInformation: clientInformation ?? undefined,
14272
+ clientInformation,
14134
14273
  addClientAuthentication: provider.addClientAuthentication,
14135
14274
  resource,
14136
14275
  fetchFn
@@ -14146,7 +14285,7 @@ async function registerClient(authorizationServerUrl, { metadata, clientMetadata
14146
14285
  } else {
14147
14286
  registrationUrl = new URL("/register", authorizationServerUrl);
14148
14287
  }
14149
- const response = await (fetchFn ?? fetch)(registrationUrl, {
14288
+ const response = await fetchWithinOrigin(fetchFn ?? fetch)(registrationUrl, {
14150
14289
  method: "POST",
14151
14290
  headers: {
14152
14291
  "Content-Type": "application/json"
@@ -14159,7 +14298,7 @@ async function registerClient(authorizationServerUrl, { metadata, clientMetadata
14159
14298
  if (!response.ok) {
14160
14299
  throw await parseErrorResponse(response);
14161
14300
  }
14162
- return OAuthClientInformationFullSchema.parse(await response.json());
14301
+ return RegistrationResponseSchema.parse(await response.json());
14163
14302
  }
14164
14303
  // node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js
14165
14304
  function isZ4Schema(s) {
@@ -14292,6 +14431,9 @@ class Protocol {
14292
14431
  this.setRequestHandler(GetTaskPayloadRequestSchema, async (request, extra) => {
14293
14432
  const handleTaskResult = async () => {
14294
14433
  const taskId = request.params.taskId;
14434
+ if (!await this._taskStore.getTask(taskId, extra.sessionId)) {
14435
+ throw new McpError(ErrorCode.InvalidParams, `Task not found: ${taskId}`);
14436
+ }
14295
14437
  if (this._taskMessageQueue) {
14296
14438
  let queuedMessage;
14297
14439
  while (queuedMessage = await this._taskMessageQueue.dequeue(taskId, extra.sessionId)) {
@@ -14322,12 +14464,12 @@ class Protocol {
14322
14464
  throw new McpError(ErrorCode.InvalidParams, `Task not found: ${taskId}`);
14323
14465
  }
14324
14466
  if (!isTerminal(task.status)) {
14325
- await this._waitForTaskUpdate(taskId, extra.signal);
14467
+ await this._waitForTaskUpdate(taskId, extra.signal, extra.sessionId);
14326
14468
  return await handleTaskResult();
14327
14469
  }
14328
14470
  if (isTerminal(task.status)) {
14329
14471
  const result = await this._taskStore.getTaskResult(taskId, extra.sessionId);
14330
- this._clearTaskQueue(taskId);
14472
+ this._clearTaskQueue(taskId, extra.sessionId);
14331
14473
  return {
14332
14474
  ...result,
14333
14475
  _meta: {
@@ -14364,7 +14506,7 @@ class Protocol {
14364
14506
  throw new McpError(ErrorCode.InvalidParams, `Cannot cancel task in terminal status: ${task.status}`);
14365
14507
  }
14366
14508
  await this._taskStore.updateTaskStatus(request.params.taskId, "cancelled", "Client cancelled task execution.", extra.sessionId);
14367
- this._clearTaskQueue(request.params.taskId);
14509
+ this._clearTaskQueue(request.params.taskId, extra.sessionId);
14368
14510
  const cancelledTask = await this._taskStore.getTask(request.params.taskId, extra.sessionId);
14369
14511
  if (!cancelledTask) {
14370
14512
  throw new McpError(ErrorCode.InvalidParams, `Task not found after cancellation: ${request.params.taskId}`);
@@ -14487,6 +14629,19 @@ class Protocol {
14487
14629
  const handler = this._requestHandlers.get(request.method) ?? this.fallbackRequestHandler;
14488
14630
  const capturedTransport = this._transport;
14489
14631
  const relatedTaskId = request.params?._meta?.[RELATED_TASK_META_KEY]?.taskId;
14632
+ const sessionId = capturedTransport?.sessionId;
14633
+ const store = this._taskStore;
14634
+ let relatedTaskFound = true;
14635
+ let relatedTaskLookup;
14636
+ if (relatedTaskId && store && this._taskMessageQueue && sessionId !== undefined) {
14637
+ relatedTaskFound = false;
14638
+ relatedTaskLookup = (async () => {
14639
+ if (!await store.getTask(relatedTaskId, sessionId)) {
14640
+ throw new McpError(ErrorCode.InvalidParams, `Task not found: ${relatedTaskId}`);
14641
+ }
14642
+ relatedTaskFound = true;
14643
+ })();
14644
+ }
14490
14645
  if (handler === undefined) {
14491
14646
  const errorResponse = {
14492
14647
  jsonrpc: "2.0",
@@ -14496,7 +14651,10 @@ class Protocol {
14496
14651
  message: "Method not found"
14497
14652
  }
14498
14653
  };
14499
- if (relatedTaskId && this._taskMessageQueue) {
14654
+ if (relatedTaskId && relatedTaskLookup) {
14655
+ const queuedError = { type: "error", message: errorResponse, timestamp: Date.now() };
14656
+ relatedTaskLookup.then(() => this._enqueueTaskMessage(relatedTaskId, queuedError, sessionId), () => capturedTransport?.send(errorResponse)).catch((error2) => this._onerror(new Error(`Failed to send an error response: ${error2}`)));
14657
+ } else if (relatedTaskId && this._taskMessageQueue) {
14500
14658
  this._enqueueTaskMessage(relatedTaskId, {
14501
14659
  type: "error",
14502
14660
  message: errorResponse,
@@ -14547,7 +14705,10 @@ class Protocol {
14547
14705
  closeSSEStream: extra?.closeSSEStream,
14548
14706
  closeStandaloneSSEStream: extra?.closeStandaloneSSEStream
14549
14707
  };
14550
- Promise.resolve().then(() => {
14708
+ (relatedTaskLookup ?? Promise.resolve()).then(() => {
14709
+ if (relatedTaskLookup && abortController.signal.aborted) {
14710
+ throw new McpError(ErrorCode.ConnectionClosed, "Request was cancelled");
14711
+ }
14551
14712
  if (taskCreationParams) {
14552
14713
  this.assertTaskHandlerCapability(request.method);
14553
14714
  }
@@ -14582,7 +14743,7 @@ class Protocol {
14582
14743
  ...error2["data"] !== undefined && { data: error2["data"] }
14583
14744
  }
14584
14745
  };
14585
- if (relatedTaskId && this._taskMessageQueue) {
14746
+ if (relatedTaskId && this._taskMessageQueue && relatedTaskFound) {
14586
14747
  await this._enqueueTaskMessage(relatedTaskId, {
14587
14748
  type: "error",
14588
14749
  message: errorResponse,
@@ -14970,7 +15131,7 @@ class Protocol {
14970
15131
  throw new Error("Cannot enqueue task message: taskStore and taskMessageQueue are not configured");
14971
15132
  }
14972
15133
  const maxQueueSize = this._options?.maxTaskQueueSize;
14973
- await this._taskMessageQueue.enqueue(taskId, message, sessionId, maxQueueSize);
15134
+ await this._taskMessageQueue.enqueue(taskId, message, sessionId ?? this._transport?.sessionId, maxQueueSize);
14974
15135
  }
14975
15136
  async _clearTaskQueue(taskId, sessionId) {
14976
15137
  if (this._taskMessageQueue) {
@@ -14989,10 +15150,10 @@ class Protocol {
14989
15150
  }
14990
15151
  }
14991
15152
  }
14992
- async _waitForTaskUpdate(taskId, signal) {
15153
+ async _waitForTaskUpdate(taskId, signal, sessionId) {
14993
15154
  let interval = this._options?.defaultTaskPollInterval ?? 1000;
14994
15155
  try {
14995
- const task = await this._taskStore?.getTask(taskId);
15156
+ const task = await this._taskStore?.getTask(taskId, sessionId);
14996
15157
  if (task?.pollInterval) {
14997
15158
  interval = task.pollInterval;
14998
15159
  }
@@ -16048,32 +16209,6 @@ function getBaseURL() {
16048
16209
  return doc2 && typeof doc2 == "object" && "baseURI" in doc2 && typeof doc2.baseURI == "string" ? doc2.baseURI : undefined;
16049
16210
  }
16050
16211
 
16051
- // node_modules/@modelcontextprotocol/sdk/dist/esm/shared/transport.js
16052
- function normalizeHeaders(headers) {
16053
- if (!headers)
16054
- return {};
16055
- if (headers instanceof Headers) {
16056
- return Object.fromEntries(headers.entries());
16057
- }
16058
- if (Array.isArray(headers)) {
16059
- return Object.fromEntries(headers);
16060
- }
16061
- return { ...headers };
16062
- }
16063
- function createFetchWithInit(baseFetch = fetch, baseInit) {
16064
- if (!baseInit) {
16065
- return baseFetch;
16066
- }
16067
- return async (url2, init) => {
16068
- const mergedInit = {
16069
- ...baseInit,
16070
- ...init,
16071
- headers: init?.headers ? { ...normalizeHeaders(baseInit.headers), ...normalizeHeaders(init.headers) } : baseInit.headers
16072
- };
16073
- return baseFetch(url2, mergedInit);
16074
- };
16075
- }
16076
-
16077
16212
  // node_modules/@modelcontextprotocol/sdk/dist/esm/client/sse.js
16078
16213
  class SseError extends Error {
16079
16214
  constructor(code, message, event) {
@@ -16093,6 +16228,15 @@ class SSEClientTransport {
16093
16228
  this._authProvider = opts?.authProvider;
16094
16229
  this._fetch = opts?.fetch;
16095
16230
  this._fetchWithInit = createFetchWithInit(opts?.fetch, opts?.requestInit);
16231
+ this._followRedirects = opts?.redirectPolicy === "follow";
16232
+ if (this._followRedirects) {
16233
+ this._fetch = fetchLeavingRedirects(this._fetch);
16234
+ this._fetchWithInit = fetchLeavingRedirects(this._fetchWithInit);
16235
+ }
16236
+ }
16237
+ _unfollowedRedirect(response, url2) {
16238
+ const text = unfollowedRedirect(response, url2);
16239
+ return text && !this._followRedirects ? `${text} (redirectPolicy: 'same-origin')` : text;
16096
16240
  }
16097
16241
  async _authThenStart() {
16098
16242
  if (!this._authProvider) {
@@ -16133,7 +16277,9 @@ class SSEClientTransport {
16133
16277
  });
16134
16278
  }
16135
16279
  _startOrAuth() {
16136
- const fetchImpl = this?._eventSourceInit?.fetch ?? this._fetch ?? fetch;
16280
+ const baseFetch = this?._eventSourceInit?.fetch ?? this._fetch ?? fetch;
16281
+ const fetchImpl = this._followRedirects ? baseFetch : fetchWithinOrigin(baseFetch);
16282
+ let redirect;
16137
16283
  return new Promise((resolve, reject) => {
16138
16284
  this._eventSource = new EventSource(this._url.href, {
16139
16285
  ...this._eventSourceInit,
@@ -16144,6 +16290,7 @@ class SSEClientTransport {
16144
16290
  ...init,
16145
16291
  headers
16146
16292
  });
16293
+ redirect = this._unfollowedRedirect(response, url2);
16147
16294
  if (response.status === 401 && response.headers.has("www-authenticate")) {
16148
16295
  const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);
16149
16296
  this._resourceMetadataUrl = resourceMetadataUrl;
@@ -16158,7 +16305,7 @@ class SSEClientTransport {
16158
16305
  this._authThenStart().then(resolve, reject);
16159
16306
  return;
16160
16307
  }
16161
- const error2 = new SseError(event.code, event.message, event);
16308
+ const error2 = new SseError(event.code, redirect ?? event.message, event);
16162
16309
  reject(error2);
16163
16310
  this.onerror?.(error2);
16164
16311
  };
@@ -16231,7 +16378,7 @@ class SSEClientTransport {
16231
16378
  body: JSON.stringify(message),
16232
16379
  signal: this._abortController?.signal
16233
16380
  };
16234
- const response = await (this._fetch ?? fetch)(this._endpoint, init);
16381
+ const response = await fetchWithinOrigin(this._fetch ?? fetch)(this._endpoint, init);
16235
16382
  if (!response.ok) {
16236
16383
  const text = await response.text().catch(() => null);
16237
16384
  if (response.status === 401 && this._authProvider) {
@@ -16249,7 +16396,7 @@ class SSEClientTransport {
16249
16396
  }
16250
16397
  return this.send(message);
16251
16398
  }
16252
- throw new Error(`Error POSTing to endpoint (HTTP ${response.status}): ${text}`);
16399
+ throw new Error(`Error POSTing to endpoint (HTTP ${response.status}): ${this._unfollowedRedirect(response, this._endpoint) ?? text}`);
16253
16400
  }
16254
16401
  await response.body?.cancel();
16255
16402
  } catch (error2) {
@@ -16523,9 +16670,18 @@ class StreamableHTTPClientTransport {
16523
16670
  this._authProvider = opts?.authProvider;
16524
16671
  this._fetch = opts?.fetch;
16525
16672
  this._fetchWithInit = createFetchWithInit(opts?.fetch, opts?.requestInit);
16673
+ this._followRedirects = opts?.redirectPolicy === "follow";
16674
+ if (this._followRedirects) {
16675
+ this._fetch = fetchLeavingRedirects(this._fetch);
16676
+ this._fetchWithInit = fetchLeavingRedirects(this._fetchWithInit);
16677
+ }
16526
16678
  this._sessionId = opts?.sessionId;
16527
16679
  this._reconnectionOptions = opts?.reconnectionOptions ?? DEFAULT_STREAMABLE_HTTP_RECONNECTION_OPTIONS;
16528
16680
  }
16681
+ _unfollowedRedirect(response, url2) {
16682
+ const text = unfollowedRedirect(response, url2);
16683
+ return text && !this._followRedirects ? `${text} (redirectPolicy: 'same-origin')` : text;
16684
+ }
16529
16685
  async _authThenStart() {
16530
16686
  if (!this._authProvider) {
16531
16687
  throw new UnauthorizedError("No auth provider");
@@ -16575,11 +16731,13 @@ class StreamableHTTPClientTransport {
16575
16731
  if (resumptionToken) {
16576
16732
  headers.set("last-event-id", resumptionToken);
16577
16733
  }
16578
- const response = await (this._fetch ?? fetch)(this._url, {
16579
- method: "GET",
16580
- headers,
16581
- signal: this._abortController?.signal
16582
- });
16734
+ const fetchFn = this._fetch ?? fetch;
16735
+ const init = { method: "GET", headers, signal: this._abortController?.signal };
16736
+ let response = await fetchFn(this._url, this._followRedirects ? init : { ...init, redirect: "manual" });
16737
+ const followed = this._followRedirects ? undefined : followWithinOrigin(fetchFn, this._url, init, response);
16738
+ if (followed) {
16739
+ response = await followed;
16740
+ }
16583
16741
  if (!response.ok) {
16584
16742
  await response.body?.cancel();
16585
16743
  if (response.status === 401 && this._authProvider) {
@@ -16588,7 +16746,7 @@ class StreamableHTTPClientTransport {
16588
16746
  if (response.status === 405) {
16589
16747
  return;
16590
16748
  }
16591
- throw new StreamableHTTPError(response.status, `Failed to open SSE stream: ${response.statusText}`);
16749
+ throw new StreamableHTTPError(response.status, `Failed to open SSE stream: ${this._unfollowedRedirect(response, this._url) ?? response.statusText}`);
16592
16750
  }
16593
16751
  this._handleSseStream(response.body, options, true);
16594
16752
  } catch (error2) {
@@ -16736,7 +16894,7 @@ class StreamableHTTPClientTransport {
16736
16894
  body: JSON.stringify(message),
16737
16895
  signal: this._abortController?.signal
16738
16896
  };
16739
- const response = await (this._fetch ?? fetch)(this._url, init);
16897
+ const response = await fetchWithinOrigin(this._fetch ?? fetch)(this._url, init);
16740
16898
  const sessionId = response.headers.get("mcp-session-id");
16741
16899
  if (sessionId) {
16742
16900
  this._sessionId = sessionId;
@@ -16788,7 +16946,7 @@ class StreamableHTTPClientTransport {
16788
16946
  return this.send(message);
16789
16947
  }
16790
16948
  }
16791
- throw new StreamableHTTPError(response.status, `Error POSTing to endpoint: ${text}`);
16949
+ throw new StreamableHTTPError(response.status, `Error POSTing to endpoint: ${this._unfollowedRedirect(response, this._url) ?? text}`);
16792
16950
  }
16793
16951
  this._hasCompletedAuthFlow = false;
16794
16952
  this._lastUpscopingHeader = undefined;
@@ -16839,10 +16997,10 @@ class StreamableHTTPClientTransport {
16839
16997
  headers,
16840
16998
  signal: this._abortController?.signal
16841
16999
  };
16842
- const response = await (this._fetch ?? fetch)(this._url, init);
17000
+ const response = await fetchWithinOrigin(this._fetch ?? fetch)(this._url, init);
16843
17001
  await response.body?.cancel();
16844
17002
  if (!response.ok && response.status !== 405) {
16845
- throw new StreamableHTTPError(response.status, `Failed to terminate session: ${response.statusText}`);
17003
+ throw new StreamableHTTPError(response.status, `Failed to terminate session: ${this._unfollowedRedirect(response, this._url) ?? response.statusText}`);
16846
17004
  }
16847
17005
  this._sessionId = undefined;
16848
17006
  } catch (error2) {
@@ -16867,7 +17025,7 @@ class StreamableHTTPClientTransport {
16867
17025
  // src/mcp-client.ts
16868
17026
  var DEFAULT_CLIENT_INFO = {
16869
17027
  name: "letta-code",
16870
- version: "0.34.25"
17028
+ version: "0.34.26"
16871
17029
  };
16872
17030
  async function connectMcpServer(config2, options = {}) {
16873
17031
  let client = new Client(options.clientInfo ?? DEFAULT_CLIENT_INFO);
@@ -17034,4 +17192,4 @@ export {
17034
17192
  connectMcpServer
17035
17193
  };
17036
17194
 
17037
- //# debugId=B93FC1D311E7902A64756E2164756E21
17195
+ //# debugId=9D4E900F8A359AA164756E2164756E21