@letta-ai/letta-agent-sdk 0.8.53 → 0.8.55
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client-entry.js +1 -64
- package/dist/client-entry.js.map +3 -3
- package/dist/index.js +231 -136
- package/dist/index.js.map +4 -4
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -10310,27 +10310,6 @@ The MemFS is a git-backed projection of your memory. Changes affect your future
|
|
|
10310
10310
|
|
|
10311
10311
|
**Editing memory does NOT change your behavior in the current turn.** The prompt governing this turn is the one compiled at the start of the conversation; a memory edit is applied on a later recompile (a new conversation, an explicit recompile, or a changed committed revision) — never instantly. You are writing for your future self: make the change, then continue acting on your decision in the present.
|
|
10312
10312
|
|
|
10313
|
-
You can always read and search memory directly. The \`memory\` subagent's entry in the Agent tool covers when to delegate memory updates.
|
|
10314
|
-
|
|
10315
|
-
### Editing memory directly
|
|
10316
|
-
|
|
10317
|
-
When memory is the main task, inspect Git status and read the current files before editing. Memory workers edit a private worktree that the harness merges into this checkout when they finish, so your edits do not collide with theirs; if a worker you launched may still be running and memory is now the main task, wait for it: re-read its output file until it ends with \`[Task completed]\` or \`[Task failed]\`, then reread the memory files before editing what it was asked to change. Automatic conflict repair and reflection integration may also commit to this checkout while you work, so stage only the files you changed by explicit path (never \`git add -A\` or \`git add .\`) and commit them in the same shell call.
|
|
10318
|
-
|
|
10319
|
-
Memory Markdown files must start with YAML frontmatter containing a non-empty \`description:\` field. Preserve existing frontmatter and discovery links. The MemFS pre-commit hook validates frontmatter and prevents changes to protected \`read_only\` files. Skill \`SKILL.md\` files use their own skill frontmatter format.
|
|
10320
|
-
|
|
10321
|
-
Review the diff, stage only the intended files, and commit only those paths, so anything else already staged in the checkout stays out of your commit. Preserve unrelated changes and protected read-only files. Use a non-empty author name fallback if \`$AGENT_NAME\` is unavailable:
|
|
10322
|
-
|
|
10323
|
-
\`\`\`bash
|
|
10324
|
-
cd "$MEMORY_DIR"
|
|
10325
|
-
git status
|
|
10326
|
-
git diff
|
|
10327
|
-
git add <specific files>
|
|
10328
|
-
author_name="\${AGENT_NAME:-$AGENT_ID}"
|
|
10329
|
-
git commit --author="$author_name <$AGENT_ID@letta.com>" -m "<type>: <what changed>" -- <specific files>
|
|
10330
|
-
\`\`\`
|
|
10331
|
-
|
|
10332
|
-
Verify the committed changes before claiming they are saved. Use \`git -C "$MEMORY_DIR" log --oneline\` to inspect memory history. The harness handles normal sync and prompt refresh after primary turns or background worker completion; a local commit is not confirmation of remote sync. Reflection continues independently.
|
|
10333
|
-
|
|
10334
10313
|
## Learning from mistakes
|
|
10335
10314
|
|
|
10336
10315
|
You are a long-lived stateful agent expected to operate over a long (potentially infinite) time horizon. Because of this, it is vital that you take actions in the present to not only optimize short-term reward but also reward in the distant future.
|
|
@@ -10510,27 +10489,6 @@ The MemFS is a git-backed projection of your memory. Changes affect your future
|
|
|
10510
10489
|
|
|
10511
10490
|
**Editing memory does NOT change your behavior in the current turn.** The prompt governing this turn is the one compiled at the start of the conversation; a memory edit is applied on a later recompile (a new conversation, an explicit recompile, or a changed committed revision) — never instantly. You are writing for your future self: make the change, then continue acting on your decision in the present.
|
|
10512
10491
|
|
|
10513
|
-
You can always read and search memory directly. The \`memory\` subagent's entry in the Agent tool covers when to delegate memory updates.
|
|
10514
|
-
|
|
10515
|
-
### Editing memory directly
|
|
10516
|
-
|
|
10517
|
-
When memory is the main task, inspect Git status and read the current files before editing. Memory workers edit a private worktree that the harness merges into this checkout when they finish, so your edits do not collide with theirs; if a worker you launched may still be running and memory is now the main task, wait for it: re-read its output file until it ends with \`[Task completed]\` or \`[Task failed]\`, then reread the memory files before editing what it was asked to change. Automatic conflict repair and reflection integration may also commit to this checkout while you work, so stage only the files you changed by explicit path (never \`git add -A\` or \`git add .\`) and commit them in the same shell call.
|
|
10518
|
-
|
|
10519
|
-
Memory Markdown files must start with YAML frontmatter containing a non-empty \`description:\` field. Preserve existing frontmatter and discovery links. The MemFS pre-commit hook validates frontmatter and prevents changes to protected \`read_only\` files. Skill \`SKILL.md\` files use their own skill frontmatter format.
|
|
10520
|
-
|
|
10521
|
-
Review the diff, stage only the intended files, and commit only those paths, so anything else already staged in the checkout stays out of your commit. Preserve unrelated changes and protected read-only files. Use a non-empty author name fallback if \`$AGENT_NAME\` is unavailable:
|
|
10522
|
-
|
|
10523
|
-
\`\`\`bash
|
|
10524
|
-
cd "$MEMORY_DIR"
|
|
10525
|
-
git status
|
|
10526
|
-
git diff
|
|
10527
|
-
git add <specific files>
|
|
10528
|
-
author_name="\${AGENT_NAME:-$AGENT_ID}"
|
|
10529
|
-
git commit --author="$author_name <$AGENT_ID@letta.com>" -m "<type>: <what changed>" -- <specific files>
|
|
10530
|
-
\`\`\`
|
|
10531
|
-
|
|
10532
|
-
Verify the committed changes before claiming they are saved. Use \`git -C "$MEMORY_DIR" log --oneline\` to inspect memory history. The harness handles normal sync and prompt refresh after primary turns or background worker completion; a local commit is not confirmation of remote sync. Reflection continues independently.
|
|
10533
|
-
|
|
10534
10492
|
## Learning from mistakes
|
|
10535
10493
|
|
|
10536
10494
|
You are a long-lived stateful agent expected to operate over a long (potentially infinite) time horizon. Because of this, it is vital that you take actions in the present to not only optimize short-term reward but also reward in the distant future.
|
|
@@ -10860,27 +10818,6 @@ The MemFS is a git-backed projection of your memory. Changes affect your future
|
|
|
10860
10818
|
|
|
10861
10819
|
**Editing memory does NOT change your behavior in the current turn.** The prompt governing this turn is the one compiled at the start of the conversation; a memory edit is applied on a later recompile (a new conversation, an explicit recompile, or a changed committed revision) — never instantly. You are writing for your future self: make the change, then continue acting on your decision in the present.
|
|
10862
10820
|
|
|
10863
|
-
You can always read and search memory directly. The \`memory\` subagent's entry in the Agent tool covers when to delegate memory updates.
|
|
10864
|
-
|
|
10865
|
-
### Editing memory directly
|
|
10866
|
-
|
|
10867
|
-
When memory is the main task, inspect Git status and read the current files before editing. Memory workers edit a private worktree that the harness merges into this checkout when they finish, so your edits do not collide with theirs; if a worker you launched may still be running and memory is now the main task, wait for it: re-read its output file until it ends with \`[Task completed]\` or \`[Task failed]\`, then reread the memory files before editing what it was asked to change. Automatic conflict repair and reflection integration may also commit to this checkout while you work, so stage only the files you changed by explicit path (never \`git add -A\` or \`git add .\`) and commit them in the same shell call.
|
|
10868
|
-
|
|
10869
|
-
Preserve the root layout: root and child \`MEMORY.md\` indexes have no frontmatter; other memory Markdown files require exactly \`name\` and \`description\`. Keep discovery links up to date. Skill \`SKILL.md\` files use their own skill frontmatter format. Obey the repository's validation hooks.
|
|
10870
|
-
|
|
10871
|
-
Review the diff, stage only the intended files, and commit only those paths, so anything else already staged in the checkout stays out of your commit. Preserve unrelated changes and protected read-only files. Use a non-empty author name fallback if \`$AGENT_NAME\` is unavailable:
|
|
10872
|
-
|
|
10873
|
-
\`\`\`bash
|
|
10874
|
-
cd "$MEMORY_DIR"
|
|
10875
|
-
git status
|
|
10876
|
-
git diff
|
|
10877
|
-
git add <specific files>
|
|
10878
|
-
author_name="\${AGENT_NAME:-$AGENT_ID}"
|
|
10879
|
-
git commit --author="$author_name <$AGENT_ID@letta.com>" -m "<type>: <what changed>" -- <specific files>
|
|
10880
|
-
\`\`\`
|
|
10881
|
-
|
|
10882
|
-
Verify the committed changes before claiming they are saved. Use \`git -C "$MEMORY_DIR" log --oneline\` to inspect memory history. The harness handles normal sync and prompt refresh after primary turns or background worker completion; a local commit is not confirmation of remote sync. Reflection continues independently.
|
|
10883
|
-
|
|
10884
10821
|
## Learning from mistakes
|
|
10885
10822
|
|
|
10886
10823
|
You are a long-lived stateful agent expected to operate over a long (potentially infinite) time horizon. Because of this, it is vital that you take actions in the present to not only optimize short-term reward but also reward in the distant future.
|
|
@@ -31426,7 +31363,8 @@ var OAuthTokensSchema = object({
|
|
|
31426
31363
|
token_type: string2(),
|
|
31427
31364
|
expires_in: exports_coerce.number().optional(),
|
|
31428
31365
|
scope: string2().optional(),
|
|
31429
|
-
refresh_token: string2().optional()
|
|
31366
|
+
refresh_token: string2().optional(),
|
|
31367
|
+
issuer: string2().optional().catch(undefined)
|
|
31430
31368
|
}).strip();
|
|
31431
31369
|
var OAuthErrorResponseSchema = object({
|
|
31432
31370
|
error: string2(),
|
|
@@ -31458,7 +31396,8 @@ var OAuthClientInformationSchema = object({
|
|
|
31458
31396
|
client_id: string2(),
|
|
31459
31397
|
client_secret: string2().optional(),
|
|
31460
31398
|
client_id_issued_at: number2().optional(),
|
|
31461
|
-
client_secret_expires_at: number2().optional()
|
|
31399
|
+
client_secret_expires_at: number2().optional(),
|
|
31400
|
+
issuer: string2().optional().catch(undefined)
|
|
31462
31401
|
}).strip();
|
|
31463
31402
|
var OAuthClientInformationFullSchema = OAuthClientMetadataSchema.merge(OAuthClientInformationSchema);
|
|
31464
31403
|
var OAuthClientRegistrationErrorSchema = object({
|
|
@@ -31595,6 +31534,92 @@ var OAUTH_ERRORS = {
|
|
|
31595
31534
|
[InsufficientScopeError.errorCode]: InsufficientScopeError,
|
|
31596
31535
|
[InvalidTargetError.errorCode]: InvalidTargetError
|
|
31597
31536
|
};
|
|
31537
|
+
function normalizeHeaders(headers) {
|
|
31538
|
+
if (!headers)
|
|
31539
|
+
return {};
|
|
31540
|
+
if (headers instanceof Headers) {
|
|
31541
|
+
return Object.fromEntries(headers.entries());
|
|
31542
|
+
}
|
|
31543
|
+
if (Array.isArray(headers)) {
|
|
31544
|
+
return Object.fromEntries(headers);
|
|
31545
|
+
}
|
|
31546
|
+
return { ...headers };
|
|
31547
|
+
}
|
|
31548
|
+
function createFetchWithInit(baseFetch = fetch, baseInit) {
|
|
31549
|
+
if (!baseInit) {
|
|
31550
|
+
return baseFetch;
|
|
31551
|
+
}
|
|
31552
|
+
return async (url2, init) => {
|
|
31553
|
+
const mergedInit = {
|
|
31554
|
+
...baseInit,
|
|
31555
|
+
...init,
|
|
31556
|
+
headers: init?.headers ? { ...normalizeHeaders(baseInit.headers), ...normalizeHeaders(init.headers) } : baseInit.headers
|
|
31557
|
+
};
|
|
31558
|
+
return baseFetch(url2, mergedInit);
|
|
31559
|
+
};
|
|
31560
|
+
}
|
|
31561
|
+
var MAX_REDIRECTS = 5;
|
|
31562
|
+
var REDIRECT_STATUSES = [301, 302, 303, 307, 308];
|
|
31563
|
+
function isWithinOrigin(from, to) {
|
|
31564
|
+
if (from.protocol === to.protocol && from.hostname === to.hostname && from.port === to.port) {
|
|
31565
|
+
return true;
|
|
31566
|
+
}
|
|
31567
|
+
return from.hostname === to.hostname && from.protocol === "http:" && from.port === "" && to.protocol === "https:" && to.port === "";
|
|
31568
|
+
}
|
|
31569
|
+
function redirectTarget(response, requestUrl) {
|
|
31570
|
+
const location = REDIRECT_STATUSES.includes(response.status) ? response.headers.get("location") : null;
|
|
31571
|
+
try {
|
|
31572
|
+
return location ? new URL(location, requestUrl) : undefined;
|
|
31573
|
+
} catch {
|
|
31574
|
+
return;
|
|
31575
|
+
}
|
|
31576
|
+
}
|
|
31577
|
+
function followWithinOrigin(baseFetch, url2, init, response, followed = 0) {
|
|
31578
|
+
const target = redirectTarget(response, url2);
|
|
31579
|
+
const keepsMethod = response.status === 307 || response.status === 308 || (init?.method ?? "GET").toUpperCase() === "GET";
|
|
31580
|
+
if (!target || followed === MAX_REDIRECTS || !keepsMethod) {
|
|
31581
|
+
return;
|
|
31582
|
+
}
|
|
31583
|
+
const from = new URL(url2);
|
|
31584
|
+
const addsUserinfo = (target.username || target.password) && (target.username !== from.username || target.password !== from.password);
|
|
31585
|
+
if (addsUserinfo || !isWithinOrigin(from, target)) {
|
|
31586
|
+
return;
|
|
31587
|
+
}
|
|
31588
|
+
return Promise.resolve(response.body?.cancel()).then(() => baseFetch(target, { ...init, redirect: "manual" })).then((next) => followWithinOrigin(baseFetch, target, init, next, followed + 1) ?? next);
|
|
31589
|
+
}
|
|
31590
|
+
var followingFetches = new WeakSet;
|
|
31591
|
+
function fetchLeavingRedirects(baseFetch) {
|
|
31592
|
+
const following = (url2, init) => (baseFetch ?? fetch)(url2, init);
|
|
31593
|
+
followingFetches.add(following);
|
|
31594
|
+
return following;
|
|
31595
|
+
}
|
|
31596
|
+
function fetchWithinOrigin(baseFetch = fetch) {
|
|
31597
|
+
if (followingFetches.has(baseFetch)) {
|
|
31598
|
+
return baseFetch;
|
|
31599
|
+
}
|
|
31600
|
+
return (url2, init) => {
|
|
31601
|
+
if (init?.redirect === "error" || init?.redirect === "manual") {
|
|
31602
|
+
return baseFetch(url2, init);
|
|
31603
|
+
}
|
|
31604
|
+
return Promise.resolve(baseFetch(url2, { ...init, redirect: "manual" })).then((response) => followWithinOrigin(baseFetch, url2, init, response) ?? response);
|
|
31605
|
+
};
|
|
31606
|
+
}
|
|
31607
|
+
function unfollowedRedirect(response, requestUrl) {
|
|
31608
|
+
if (response.type === "opaqueredirect") {
|
|
31609
|
+
return "Redirect not followed: this runtime does not expose the redirect target";
|
|
31610
|
+
}
|
|
31611
|
+
const from = response.url || requestUrl;
|
|
31612
|
+
const target = redirectTarget(response, from);
|
|
31613
|
+
if (!target) {
|
|
31614
|
+
return;
|
|
31615
|
+
}
|
|
31616
|
+
target.username = target.password = target.search = target.hash = "";
|
|
31617
|
+
if (target.protocol === "http:" && new URL(from).protocol === "https:") {
|
|
31618
|
+
target.protocol = "https:";
|
|
31619
|
+
return `Redirect to plain http not followed; try ${target.href} instead`;
|
|
31620
|
+
}
|
|
31621
|
+
return `Redirect to ${target.href} not followed`;
|
|
31622
|
+
}
|
|
31598
31623
|
|
|
31599
31624
|
class UnauthorizedError extends Error {
|
|
31600
31625
|
constructor(message) {
|
|
@@ -31666,10 +31691,30 @@ async function parseErrorResponse(input) {
|
|
|
31666
31691
|
const errorClass = OAUTH_ERRORS[error2] || ServerError;
|
|
31667
31692
|
return new errorClass(error_description || "", error_uri);
|
|
31668
31693
|
} catch (error2) {
|
|
31669
|
-
const
|
|
31694
|
+
const redirect = input instanceof Response ? unfollowedRedirect(input, input.url) : undefined;
|
|
31695
|
+
const errorMessage = `${statusCode ? `HTTP ${statusCode}: ` : ""}${redirect ?? `Invalid OAuth error response: ${error2}. Raw body: ${body}`}`;
|
|
31670
31696
|
return new ServerError(errorMessage);
|
|
31671
31697
|
}
|
|
31672
31698
|
}
|
|
31699
|
+
function issuersMatch(a, b) {
|
|
31700
|
+
let [x, y] = [a, b];
|
|
31701
|
+
try {
|
|
31702
|
+
[x, y] = [new URL(a).href, new URL(b).href];
|
|
31703
|
+
} catch {}
|
|
31704
|
+
return x === y || x.endsWith("/") && x.slice(0, -1) === y || y.endsWith("/") && y.slice(0, -1) === x;
|
|
31705
|
+
}
|
|
31706
|
+
function discardIfIssuerMismatch(stored, issuer) {
|
|
31707
|
+
if (!stored)
|
|
31708
|
+
return;
|
|
31709
|
+
if (typeof stored.issuer !== "string")
|
|
31710
|
+
return stored.issuer == null ? stored : { ...stored, issuer: undefined };
|
|
31711
|
+
return issuersMatch(stored.issuer, issuer) ? stored : undefined;
|
|
31712
|
+
}
|
|
31713
|
+
var TokenResponseSchema = OAuthTokensSchema.omit({ issuer: true });
|
|
31714
|
+
var RegistrationResponseSchema = OAuthClientInformationFullSchema.omit({ issuer: true });
|
|
31715
|
+
function boundElsewhereError(stored, issuer) {
|
|
31716
|
+
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.`);
|
|
31717
|
+
}
|
|
31673
31718
|
async function auth(provider, options) {
|
|
31674
31719
|
try {
|
|
31675
31720
|
return await authInternal(provider, options);
|
|
@@ -31722,9 +31767,23 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
|
|
|
31722
31767
|
authorizationServerMetadata: metadata
|
|
31723
31768
|
});
|
|
31724
31769
|
}
|
|
31725
|
-
const
|
|
31770
|
+
const issuer = String(authorizationServerUrl);
|
|
31771
|
+
const selectedResource = await selectResourceURL(serverUrl, provider, resourceMetadata);
|
|
31772
|
+
const resource = selectedResource && resourceMetadata && !provider.validateResourceURL ? resourceMetadata.resource : selectedResource;
|
|
31726
31773
|
const resolvedScope = scope || resourceMetadata?.scopes_supported?.join(" ") || provider.clientMetadata.scope;
|
|
31727
|
-
|
|
31774
|
+
const storedClientInformation = await Promise.resolve(provider.clientInformation());
|
|
31775
|
+
let clientInformation = discardIfIssuerMismatch(storedClientInformation, issuer);
|
|
31776
|
+
const canRegisterAgain = provider.saveClientInformation !== undefined && !!provider.redirectUrl;
|
|
31777
|
+
if (storedClientInformation && !clientInformation && !canRegisterAgain) {
|
|
31778
|
+
throw boundElsewhereError(storedClientInformation, issuer);
|
|
31779
|
+
}
|
|
31780
|
+
const unstampedClientInformation = clientInformation?.issuer == null ? clientInformation : undefined;
|
|
31781
|
+
const bindClientInformation = async () => {
|
|
31782
|
+
try {
|
|
31783
|
+
if (unstampedClientInformation)
|
|
31784
|
+
await provider.saveClientInformation?.({ ...unstampedClientInformation, issuer });
|
|
31785
|
+
} catch {}
|
|
31786
|
+
};
|
|
31728
31787
|
if (!clientInformation) {
|
|
31729
31788
|
if (authorizationCode !== undefined) {
|
|
31730
31789
|
throw new Error("Existing OAuth client information is required when exchanging an authorization code");
|
|
@@ -31736,9 +31795,7 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
|
|
|
31736
31795
|
}
|
|
31737
31796
|
const shouldUseUrlBasedClientId = supportsUrlBasedClientId && clientMetadataUrl;
|
|
31738
31797
|
if (shouldUseUrlBasedClientId) {
|
|
31739
|
-
clientInformation = {
|
|
31740
|
-
client_id: clientMetadataUrl
|
|
31741
|
-
};
|
|
31798
|
+
clientInformation = { client_id: clientMetadataUrl, issuer };
|
|
31742
31799
|
await provider.saveClientInformation?.(clientInformation);
|
|
31743
31800
|
} else {
|
|
31744
31801
|
if (!provider.saveClientInformation) {
|
|
@@ -31750,8 +31807,8 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
|
|
|
31750
31807
|
scope: resolvedScope,
|
|
31751
31808
|
fetchFn
|
|
31752
31809
|
});
|
|
31753
|
-
|
|
31754
|
-
clientInformation
|
|
31810
|
+
clientInformation = { ...fullInformation, issuer };
|
|
31811
|
+
await provider.saveClientInformation(clientInformation);
|
|
31755
31812
|
}
|
|
31756
31813
|
}
|
|
31757
31814
|
const nonInteractiveFlow = !provider.redirectUrl;
|
|
@@ -31762,10 +31819,14 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
|
|
|
31762
31819
|
authorizationCode,
|
|
31763
31820
|
fetchFn
|
|
31764
31821
|
});
|
|
31765
|
-
await
|
|
31822
|
+
await bindClientInformation();
|
|
31823
|
+
await provider.saveTokens({ ...tokens2, issuer });
|
|
31766
31824
|
return "AUTHORIZED";
|
|
31767
31825
|
}
|
|
31768
|
-
const tokens = await provider.tokens();
|
|
31826
|
+
const tokens = discardIfIssuerMismatch(await provider.tokens(), issuer);
|
|
31827
|
+
if (tokens?.refresh_token && tokens.issuer == null) {
|
|
31828
|
+
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.");
|
|
31829
|
+
}
|
|
31769
31830
|
if (tokens?.refresh_token) {
|
|
31770
31831
|
try {
|
|
31771
31832
|
const newTokens = await refreshAuthorization(authorizationServerUrl, {
|
|
@@ -31776,7 +31837,8 @@ async function authInternal(provider, { serverUrl, authorizationCode, scope, res
|
|
|
31776
31837
|
addClientAuthentication: provider.addClientAuthentication,
|
|
31777
31838
|
fetchFn
|
|
31778
31839
|
});
|
|
31779
|
-
await
|
|
31840
|
+
await bindClientInformation();
|
|
31841
|
+
await provider.saveTokens({ ...newTokens, issuer });
|
|
31780
31842
|
return "AUTHORIZED";
|
|
31781
31843
|
} catch (error2) {
|
|
31782
31844
|
if (!(error2 instanceof OAuthError) || error2 instanceof ServerError) {} else {
|
|
@@ -31873,7 +31935,7 @@ async function discoverOAuthProtectedResourceMetadata(serverUrl, opts, fetchFn =
|
|
|
31873
31935
|
}
|
|
31874
31936
|
async function fetchWithCorsRetry(url2, headers, fetchFn = fetch) {
|
|
31875
31937
|
try {
|
|
31876
|
-
return await fetchFn(url2, { headers });
|
|
31938
|
+
return await fetchWithinOrigin(fetchFn)(url2, { headers });
|
|
31877
31939
|
} catch (error2) {
|
|
31878
31940
|
if (error2 instanceof TypeError) {
|
|
31879
31941
|
if (headers) {
|
|
@@ -31898,7 +31960,7 @@ async function tryMetadataDiscovery(url2, protocolVersion, fetchFn = fetch) {
|
|
|
31898
31960
|
return await fetchWithCorsRetry(url2, headers, fetchFn);
|
|
31899
31961
|
}
|
|
31900
31962
|
function shouldAttemptFallback(response, pathname) {
|
|
31901
|
-
return !response || response.
|
|
31963
|
+
return !response || !response.ok && response.status < 500 && pathname !== "/";
|
|
31902
31964
|
}
|
|
31903
31965
|
async function discoverMetadataWithFallback(serverUrl, wellKnownType, fetchFn, opts) {
|
|
31904
31966
|
const issuer = new URL(serverUrl);
|
|
@@ -31964,7 +32026,7 @@ async function discoverAuthorizationServerMetadata(authorizationServerUrl, { fet
|
|
|
31964
32026
|
}
|
|
31965
32027
|
if (!response.ok) {
|
|
31966
32028
|
await response.body?.cancel();
|
|
31967
|
-
if (response.status
|
|
32029
|
+
if (response.status < 500) {
|
|
31968
32030
|
continue;
|
|
31969
32031
|
}
|
|
31970
32032
|
throw new Error(`HTTP ${response.status} trying to load ${type === "oauth" ? "OAuth" : "OpenID provider"} metadata from ${endpointUrl}`);
|
|
@@ -31996,6 +32058,9 @@ async function discoverOAuthServerInfo(serverUrl, opts) {
|
|
|
31996
32058
|
resourceMetadata
|
|
31997
32059
|
};
|
|
31998
32060
|
}
|
|
32061
|
+
function resourceIndicatorToString(resource) {
|
|
32062
|
+
return typeof resource === "string" ? resource : resource.href;
|
|
32063
|
+
}
|
|
31999
32064
|
async function startAuthorization(authorizationServerUrl, { metadata, clientInformation, redirectUrl, scope, state, resource }) {
|
|
32000
32065
|
let authorizationUrl;
|
|
32001
32066
|
if (metadata) {
|
|
@@ -32027,7 +32092,7 @@ async function startAuthorization(authorizationServerUrl, { metadata, clientInfo
|
|
|
32027
32092
|
authorizationUrl.searchParams.append("prompt", "consent");
|
|
32028
32093
|
}
|
|
32029
32094
|
if (resource) {
|
|
32030
|
-
authorizationUrl.searchParams.set("resource", resource
|
|
32095
|
+
authorizationUrl.searchParams.set("resource", resourceIndicatorToString(resource));
|
|
32031
32096
|
}
|
|
32032
32097
|
return { authorizationUrl, codeVerifier };
|
|
32033
32098
|
}
|
|
@@ -32046,7 +32111,7 @@ async function executeTokenRequest(authorizationServerUrl, { metadata, tokenRequ
|
|
|
32046
32111
|
Accept: "application/json"
|
|
32047
32112
|
});
|
|
32048
32113
|
if (resource) {
|
|
32049
|
-
tokenRequestParams.set("resource", resource
|
|
32114
|
+
tokenRequestParams.set("resource", resourceIndicatorToString(resource));
|
|
32050
32115
|
}
|
|
32051
32116
|
if (addClientAuthentication) {
|
|
32052
32117
|
await addClientAuthentication(headers, tokenRequestParams, tokenUrl, metadata);
|
|
@@ -32055,7 +32120,7 @@ async function executeTokenRequest(authorizationServerUrl, { metadata, tokenRequ
|
|
|
32055
32120
|
const authMethod = selectClientAuthMethod(clientInformation, supportedMethods);
|
|
32056
32121
|
applyClientAuthentication(authMethod, clientInformation, headers, tokenRequestParams);
|
|
32057
32122
|
}
|
|
32058
|
-
const response = await (fetchFn ?? fetch)(tokenUrl, {
|
|
32123
|
+
const response = await fetchWithinOrigin(fetchFn ?? fetch)(tokenUrl, {
|
|
32059
32124
|
method: "POST",
|
|
32060
32125
|
headers,
|
|
32061
32126
|
body: tokenRequestParams
|
|
@@ -32063,7 +32128,7 @@ async function executeTokenRequest(authorizationServerUrl, { metadata, tokenRequ
|
|
|
32063
32128
|
if (!response.ok) {
|
|
32064
32129
|
throw await parseErrorResponse(response);
|
|
32065
32130
|
}
|
|
32066
|
-
return
|
|
32131
|
+
return TokenResponseSchema.parse(await response.json());
|
|
32067
32132
|
}
|
|
32068
32133
|
async function refreshAuthorization(authorizationServerUrl, { metadata, clientInformation, refreshToken, resource, addClientAuthentication, fetchFn }) {
|
|
32069
32134
|
const tokenRequestParams = new URLSearchParams({
|
|
@@ -32081,6 +32146,15 @@ async function refreshAuthorization(authorizationServerUrl, { metadata, clientIn
|
|
|
32081
32146
|
return { refresh_token: refreshToken, ...tokens };
|
|
32082
32147
|
}
|
|
32083
32148
|
async function fetchToken(provider, authorizationServerUrl, { metadata, resource, authorizationCode, fetchFn } = {}) {
|
|
32149
|
+
const readClientInformation = async () => {
|
|
32150
|
+
const storedClientInformation = await provider.clientInformation();
|
|
32151
|
+
const checked = discardIfIssuerMismatch(storedClientInformation, String(authorizationServerUrl));
|
|
32152
|
+
if (storedClientInformation && !checked) {
|
|
32153
|
+
throw boundElsewhereError(storedClientInformation, String(authorizationServerUrl));
|
|
32154
|
+
}
|
|
32155
|
+
return checked;
|
|
32156
|
+
};
|
|
32157
|
+
let clientInformation = await readClientInformation();
|
|
32084
32158
|
const scope = provider.clientMetadata.scope;
|
|
32085
32159
|
let tokenRequestParams;
|
|
32086
32160
|
if (provider.prepareTokenRequest) {
|
|
@@ -32096,11 +32170,11 @@ async function fetchToken(provider, authorizationServerUrl, { metadata, resource
|
|
|
32096
32170
|
const codeVerifier = await provider.codeVerifier();
|
|
32097
32171
|
tokenRequestParams = prepareAuthorizationCodeRequest(authorizationCode, codeVerifier, provider.redirectUrl);
|
|
32098
32172
|
}
|
|
32099
|
-
|
|
32173
|
+
clientInformation ?? (clientInformation = await readClientInformation());
|
|
32100
32174
|
return executeTokenRequest(authorizationServerUrl, {
|
|
32101
32175
|
metadata,
|
|
32102
32176
|
tokenRequestParams,
|
|
32103
|
-
clientInformation
|
|
32177
|
+
clientInformation,
|
|
32104
32178
|
addClientAuthentication: provider.addClientAuthentication,
|
|
32105
32179
|
resource,
|
|
32106
32180
|
fetchFn
|
|
@@ -32116,7 +32190,7 @@ async function registerClient(authorizationServerUrl, { metadata, clientMetadata
|
|
|
32116
32190
|
} else {
|
|
32117
32191
|
registrationUrl = new URL("/register", authorizationServerUrl);
|
|
32118
32192
|
}
|
|
32119
|
-
const response = await (fetchFn ?? fetch)(registrationUrl, {
|
|
32193
|
+
const response = await fetchWithinOrigin(fetchFn ?? fetch)(registrationUrl, {
|
|
32120
32194
|
method: "POST",
|
|
32121
32195
|
headers: {
|
|
32122
32196
|
"Content-Type": "application/json"
|
|
@@ -32129,7 +32203,7 @@ async function registerClient(authorizationServerUrl, { metadata, clientMetadata
|
|
|
32129
32203
|
if (!response.ok) {
|
|
32130
32204
|
throw await parseErrorResponse(response);
|
|
32131
32205
|
}
|
|
32132
|
-
return
|
|
32206
|
+
return RegistrationResponseSchema.parse(await response.json());
|
|
32133
32207
|
}
|
|
32134
32208
|
function isZ4Schema(s) {
|
|
32135
32209
|
const schema = s;
|
|
@@ -32253,6 +32327,9 @@ class Protocol {
|
|
|
32253
32327
|
this.setRequestHandler(GetTaskPayloadRequestSchema, async (request, extra) => {
|
|
32254
32328
|
const handleTaskResult = async () => {
|
|
32255
32329
|
const taskId = request.params.taskId;
|
|
32330
|
+
if (!await this._taskStore.getTask(taskId, extra.sessionId)) {
|
|
32331
|
+
throw new McpError(ErrorCode.InvalidParams, `Task not found: ${taskId}`);
|
|
32332
|
+
}
|
|
32256
32333
|
if (this._taskMessageQueue) {
|
|
32257
32334
|
let queuedMessage;
|
|
32258
32335
|
while (queuedMessage = await this._taskMessageQueue.dequeue(taskId, extra.sessionId)) {
|
|
@@ -32283,12 +32360,12 @@ class Protocol {
|
|
|
32283
32360
|
throw new McpError(ErrorCode.InvalidParams, `Task not found: ${taskId}`);
|
|
32284
32361
|
}
|
|
32285
32362
|
if (!isTerminal(task.status)) {
|
|
32286
|
-
await this._waitForTaskUpdate(taskId, extra.signal);
|
|
32363
|
+
await this._waitForTaskUpdate(taskId, extra.signal, extra.sessionId);
|
|
32287
32364
|
return await handleTaskResult();
|
|
32288
32365
|
}
|
|
32289
32366
|
if (isTerminal(task.status)) {
|
|
32290
32367
|
const result = await this._taskStore.getTaskResult(taskId, extra.sessionId);
|
|
32291
|
-
this._clearTaskQueue(taskId);
|
|
32368
|
+
this._clearTaskQueue(taskId, extra.sessionId);
|
|
32292
32369
|
return {
|
|
32293
32370
|
...result,
|
|
32294
32371
|
_meta: {
|
|
@@ -32325,7 +32402,7 @@ class Protocol {
|
|
|
32325
32402
|
throw new McpError(ErrorCode.InvalidParams, `Cannot cancel task in terminal status: ${task.status}`);
|
|
32326
32403
|
}
|
|
32327
32404
|
await this._taskStore.updateTaskStatus(request.params.taskId, "cancelled", "Client cancelled task execution.", extra.sessionId);
|
|
32328
|
-
this._clearTaskQueue(request.params.taskId);
|
|
32405
|
+
this._clearTaskQueue(request.params.taskId, extra.sessionId);
|
|
32329
32406
|
const cancelledTask = await this._taskStore.getTask(request.params.taskId, extra.sessionId);
|
|
32330
32407
|
if (!cancelledTask) {
|
|
32331
32408
|
throw new McpError(ErrorCode.InvalidParams, `Task not found after cancellation: ${request.params.taskId}`);
|
|
@@ -32448,6 +32525,19 @@ class Protocol {
|
|
|
32448
32525
|
const handler = this._requestHandlers.get(request.method) ?? this.fallbackRequestHandler;
|
|
32449
32526
|
const capturedTransport = this._transport;
|
|
32450
32527
|
const relatedTaskId = request.params?._meta?.[RELATED_TASK_META_KEY]?.taskId;
|
|
32528
|
+
const sessionId = capturedTransport?.sessionId;
|
|
32529
|
+
const store = this._taskStore;
|
|
32530
|
+
let relatedTaskFound = true;
|
|
32531
|
+
let relatedTaskLookup;
|
|
32532
|
+
if (relatedTaskId && store && this._taskMessageQueue && sessionId !== undefined) {
|
|
32533
|
+
relatedTaskFound = false;
|
|
32534
|
+
relatedTaskLookup = (async () => {
|
|
32535
|
+
if (!await store.getTask(relatedTaskId, sessionId)) {
|
|
32536
|
+
throw new McpError(ErrorCode.InvalidParams, `Task not found: ${relatedTaskId}`);
|
|
32537
|
+
}
|
|
32538
|
+
relatedTaskFound = true;
|
|
32539
|
+
})();
|
|
32540
|
+
}
|
|
32451
32541
|
if (handler === undefined) {
|
|
32452
32542
|
const errorResponse = {
|
|
32453
32543
|
jsonrpc: "2.0",
|
|
@@ -32457,7 +32547,10 @@ class Protocol {
|
|
|
32457
32547
|
message: "Method not found"
|
|
32458
32548
|
}
|
|
32459
32549
|
};
|
|
32460
|
-
if (relatedTaskId &&
|
|
32550
|
+
if (relatedTaskId && relatedTaskLookup) {
|
|
32551
|
+
const queuedError = { type: "error", message: errorResponse, timestamp: Date.now() };
|
|
32552
|
+
relatedTaskLookup.then(() => this._enqueueTaskMessage(relatedTaskId, queuedError, sessionId), () => capturedTransport?.send(errorResponse)).catch((error2) => this._onerror(new Error(`Failed to send an error response: ${error2}`)));
|
|
32553
|
+
} else if (relatedTaskId && this._taskMessageQueue) {
|
|
32461
32554
|
this._enqueueTaskMessage(relatedTaskId, {
|
|
32462
32555
|
type: "error",
|
|
32463
32556
|
message: errorResponse,
|
|
@@ -32508,7 +32601,10 @@ class Protocol {
|
|
|
32508
32601
|
closeSSEStream: extra?.closeSSEStream,
|
|
32509
32602
|
closeStandaloneSSEStream: extra?.closeStandaloneSSEStream
|
|
32510
32603
|
};
|
|
32511
|
-
Promise.resolve().then(() => {
|
|
32604
|
+
(relatedTaskLookup ?? Promise.resolve()).then(() => {
|
|
32605
|
+
if (relatedTaskLookup && abortController.signal.aborted) {
|
|
32606
|
+
throw new McpError(ErrorCode.ConnectionClosed, "Request was cancelled");
|
|
32607
|
+
}
|
|
32512
32608
|
if (taskCreationParams) {
|
|
32513
32609
|
this.assertTaskHandlerCapability(request.method);
|
|
32514
32610
|
}
|
|
@@ -32543,7 +32639,7 @@ class Protocol {
|
|
|
32543
32639
|
...error2["data"] !== undefined && { data: error2["data"] }
|
|
32544
32640
|
}
|
|
32545
32641
|
};
|
|
32546
|
-
if (relatedTaskId && this._taskMessageQueue) {
|
|
32642
|
+
if (relatedTaskId && this._taskMessageQueue && relatedTaskFound) {
|
|
32547
32643
|
await this._enqueueTaskMessage(relatedTaskId, {
|
|
32548
32644
|
type: "error",
|
|
32549
32645
|
message: errorResponse,
|
|
@@ -32931,7 +33027,7 @@ class Protocol {
|
|
|
32931
33027
|
throw new Error("Cannot enqueue task message: taskStore and taskMessageQueue are not configured");
|
|
32932
33028
|
}
|
|
32933
33029
|
const maxQueueSize = this._options?.maxTaskQueueSize;
|
|
32934
|
-
await this._taskMessageQueue.enqueue(taskId, message, sessionId, maxQueueSize);
|
|
33030
|
+
await this._taskMessageQueue.enqueue(taskId, message, sessionId ?? this._transport?.sessionId, maxQueueSize);
|
|
32935
33031
|
}
|
|
32936
33032
|
async _clearTaskQueue(taskId, sessionId) {
|
|
32937
33033
|
if (this._taskMessageQueue) {
|
|
@@ -32950,10 +33046,10 @@ class Protocol {
|
|
|
32950
33046
|
}
|
|
32951
33047
|
}
|
|
32952
33048
|
}
|
|
32953
|
-
async _waitForTaskUpdate(taskId, signal) {
|
|
33049
|
+
async _waitForTaskUpdate(taskId, signal, sessionId) {
|
|
32954
33050
|
let interval = this._options?.defaultTaskPollInterval ?? 1000;
|
|
32955
33051
|
try {
|
|
32956
|
-
const task = await this._taskStore?.getTask(taskId);
|
|
33052
|
+
const task = await this._taskStore?.getTask(taskId, sessionId);
|
|
32957
33053
|
if (task?.pollInterval) {
|
|
32958
33054
|
interval = task.pollInterval;
|
|
32959
33055
|
}
|
|
@@ -33999,30 +34095,6 @@ function getBaseURL() {
|
|
|
33999
34095
|
const doc2 = "document" in globalThis ? globalThis.document : undefined;
|
|
34000
34096
|
return doc2 && typeof doc2 == "object" && "baseURI" in doc2 && typeof doc2.baseURI == "string" ? doc2.baseURI : undefined;
|
|
34001
34097
|
}
|
|
34002
|
-
function normalizeHeaders(headers) {
|
|
34003
|
-
if (!headers)
|
|
34004
|
-
return {};
|
|
34005
|
-
if (headers instanceof Headers) {
|
|
34006
|
-
return Object.fromEntries(headers.entries());
|
|
34007
|
-
}
|
|
34008
|
-
if (Array.isArray(headers)) {
|
|
34009
|
-
return Object.fromEntries(headers);
|
|
34010
|
-
}
|
|
34011
|
-
return { ...headers };
|
|
34012
|
-
}
|
|
34013
|
-
function createFetchWithInit(baseFetch = fetch, baseInit) {
|
|
34014
|
-
if (!baseInit) {
|
|
34015
|
-
return baseFetch;
|
|
34016
|
-
}
|
|
34017
|
-
return async (url2, init) => {
|
|
34018
|
-
const mergedInit = {
|
|
34019
|
-
...baseInit,
|
|
34020
|
-
...init,
|
|
34021
|
-
headers: init?.headers ? { ...normalizeHeaders(baseInit.headers), ...normalizeHeaders(init.headers) } : baseInit.headers
|
|
34022
|
-
};
|
|
34023
|
-
return baseFetch(url2, mergedInit);
|
|
34024
|
-
};
|
|
34025
|
-
}
|
|
34026
34098
|
|
|
34027
34099
|
class SseError extends Error {
|
|
34028
34100
|
constructor(code, message, event) {
|
|
@@ -34042,6 +34114,15 @@ class SSEClientTransport {
|
|
|
34042
34114
|
this._authProvider = opts?.authProvider;
|
|
34043
34115
|
this._fetch = opts?.fetch;
|
|
34044
34116
|
this._fetchWithInit = createFetchWithInit(opts?.fetch, opts?.requestInit);
|
|
34117
|
+
this._followRedirects = opts?.redirectPolicy === "follow";
|
|
34118
|
+
if (this._followRedirects) {
|
|
34119
|
+
this._fetch = fetchLeavingRedirects(this._fetch);
|
|
34120
|
+
this._fetchWithInit = fetchLeavingRedirects(this._fetchWithInit);
|
|
34121
|
+
}
|
|
34122
|
+
}
|
|
34123
|
+
_unfollowedRedirect(response, url2) {
|
|
34124
|
+
const text = unfollowedRedirect(response, url2);
|
|
34125
|
+
return text && !this._followRedirects ? `${text} (redirectPolicy: 'same-origin')` : text;
|
|
34045
34126
|
}
|
|
34046
34127
|
async _authThenStart() {
|
|
34047
34128
|
if (!this._authProvider) {
|
|
@@ -34082,7 +34163,9 @@ class SSEClientTransport {
|
|
|
34082
34163
|
});
|
|
34083
34164
|
}
|
|
34084
34165
|
_startOrAuth() {
|
|
34085
|
-
const
|
|
34166
|
+
const baseFetch = this?._eventSourceInit?.fetch ?? this._fetch ?? fetch;
|
|
34167
|
+
const fetchImpl = this._followRedirects ? baseFetch : fetchWithinOrigin(baseFetch);
|
|
34168
|
+
let redirect;
|
|
34086
34169
|
return new Promise((resolve3, reject) => {
|
|
34087
34170
|
this._eventSource = new EventSource(this._url.href, {
|
|
34088
34171
|
...this._eventSourceInit,
|
|
@@ -34093,6 +34176,7 @@ class SSEClientTransport {
|
|
|
34093
34176
|
...init,
|
|
34094
34177
|
headers
|
|
34095
34178
|
});
|
|
34179
|
+
redirect = this._unfollowedRedirect(response, url2);
|
|
34096
34180
|
if (response.status === 401 && response.headers.has("www-authenticate")) {
|
|
34097
34181
|
const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);
|
|
34098
34182
|
this._resourceMetadataUrl = resourceMetadataUrl;
|
|
@@ -34107,7 +34191,7 @@ class SSEClientTransport {
|
|
|
34107
34191
|
this._authThenStart().then(resolve3, reject);
|
|
34108
34192
|
return;
|
|
34109
34193
|
}
|
|
34110
|
-
const error2 = new SseError(event.code, event.message, event);
|
|
34194
|
+
const error2 = new SseError(event.code, redirect ?? event.message, event);
|
|
34111
34195
|
reject(error2);
|
|
34112
34196
|
this.onerror?.(error2);
|
|
34113
34197
|
};
|
|
@@ -34180,7 +34264,7 @@ class SSEClientTransport {
|
|
|
34180
34264
|
body: JSON.stringify(message),
|
|
34181
34265
|
signal: this._abortController?.signal
|
|
34182
34266
|
};
|
|
34183
|
-
const response = await (this._fetch ?? fetch)(this._endpoint, init);
|
|
34267
|
+
const response = await fetchWithinOrigin(this._fetch ?? fetch)(this._endpoint, init);
|
|
34184
34268
|
if (!response.ok) {
|
|
34185
34269
|
const text = await response.text().catch(() => null);
|
|
34186
34270
|
if (response.status === 401 && this._authProvider) {
|
|
@@ -34198,7 +34282,7 @@ class SSEClientTransport {
|
|
|
34198
34282
|
}
|
|
34199
34283
|
return this.send(message);
|
|
34200
34284
|
}
|
|
34201
|
-
throw new Error(`Error POSTing to endpoint (HTTP ${response.status}): ${text}`);
|
|
34285
|
+
throw new Error(`Error POSTing to endpoint (HTTP ${response.status}): ${this._unfollowedRedirect(response, this._endpoint) ?? text}`);
|
|
34202
34286
|
}
|
|
34203
34287
|
await response.body?.cancel();
|
|
34204
34288
|
} catch (error2) {
|
|
@@ -34459,9 +34543,18 @@ class StreamableHTTPClientTransport {
|
|
|
34459
34543
|
this._authProvider = opts?.authProvider;
|
|
34460
34544
|
this._fetch = opts?.fetch;
|
|
34461
34545
|
this._fetchWithInit = createFetchWithInit(opts?.fetch, opts?.requestInit);
|
|
34546
|
+
this._followRedirects = opts?.redirectPolicy === "follow";
|
|
34547
|
+
if (this._followRedirects) {
|
|
34548
|
+
this._fetch = fetchLeavingRedirects(this._fetch);
|
|
34549
|
+
this._fetchWithInit = fetchLeavingRedirects(this._fetchWithInit);
|
|
34550
|
+
}
|
|
34462
34551
|
this._sessionId = opts?.sessionId;
|
|
34463
34552
|
this._reconnectionOptions = opts?.reconnectionOptions ?? DEFAULT_STREAMABLE_HTTP_RECONNECTION_OPTIONS;
|
|
34464
34553
|
}
|
|
34554
|
+
_unfollowedRedirect(response, url2) {
|
|
34555
|
+
const text = unfollowedRedirect(response, url2);
|
|
34556
|
+
return text && !this._followRedirects ? `${text} (redirectPolicy: 'same-origin')` : text;
|
|
34557
|
+
}
|
|
34465
34558
|
async _authThenStart() {
|
|
34466
34559
|
if (!this._authProvider) {
|
|
34467
34560
|
throw new UnauthorizedError("No auth provider");
|
|
@@ -34511,11 +34604,13 @@ class StreamableHTTPClientTransport {
|
|
|
34511
34604
|
if (resumptionToken) {
|
|
34512
34605
|
headers.set("last-event-id", resumptionToken);
|
|
34513
34606
|
}
|
|
34514
|
-
const
|
|
34515
|
-
|
|
34516
|
-
|
|
34517
|
-
|
|
34518
|
-
|
|
34607
|
+
const fetchFn = this._fetch ?? fetch;
|
|
34608
|
+
const init = { method: "GET", headers, signal: this._abortController?.signal };
|
|
34609
|
+
let response = await fetchFn(this._url, this._followRedirects ? init : { ...init, redirect: "manual" });
|
|
34610
|
+
const followed = this._followRedirects ? undefined : followWithinOrigin(fetchFn, this._url, init, response);
|
|
34611
|
+
if (followed) {
|
|
34612
|
+
response = await followed;
|
|
34613
|
+
}
|
|
34519
34614
|
if (!response.ok) {
|
|
34520
34615
|
await response.body?.cancel();
|
|
34521
34616
|
if (response.status === 401 && this._authProvider) {
|
|
@@ -34524,7 +34619,7 @@ class StreamableHTTPClientTransport {
|
|
|
34524
34619
|
if (response.status === 405) {
|
|
34525
34620
|
return;
|
|
34526
34621
|
}
|
|
34527
|
-
throw new StreamableHTTPError(response.status, `Failed to open SSE stream: ${response.statusText}`);
|
|
34622
|
+
throw new StreamableHTTPError(response.status, `Failed to open SSE stream: ${this._unfollowedRedirect(response, this._url) ?? response.statusText}`);
|
|
34528
34623
|
}
|
|
34529
34624
|
this._handleSseStream(response.body, options, true);
|
|
34530
34625
|
} catch (error2) {
|
|
@@ -34672,7 +34767,7 @@ class StreamableHTTPClientTransport {
|
|
|
34672
34767
|
body: JSON.stringify(message),
|
|
34673
34768
|
signal: this._abortController?.signal
|
|
34674
34769
|
};
|
|
34675
|
-
const response = await (this._fetch ?? fetch)(this._url, init);
|
|
34770
|
+
const response = await fetchWithinOrigin(this._fetch ?? fetch)(this._url, init);
|
|
34676
34771
|
const sessionId = response.headers.get("mcp-session-id");
|
|
34677
34772
|
if (sessionId) {
|
|
34678
34773
|
this._sessionId = sessionId;
|
|
@@ -34724,7 +34819,7 @@ class StreamableHTTPClientTransport {
|
|
|
34724
34819
|
return this.send(message);
|
|
34725
34820
|
}
|
|
34726
34821
|
}
|
|
34727
|
-
throw new StreamableHTTPError(response.status, `Error POSTing to endpoint: ${text}`);
|
|
34822
|
+
throw new StreamableHTTPError(response.status, `Error POSTing to endpoint: ${this._unfollowedRedirect(response, this._url) ?? text}`);
|
|
34728
34823
|
}
|
|
34729
34824
|
this._hasCompletedAuthFlow = false;
|
|
34730
34825
|
this._lastUpscopingHeader = undefined;
|
|
@@ -34775,10 +34870,10 @@ class StreamableHTTPClientTransport {
|
|
|
34775
34870
|
headers,
|
|
34776
34871
|
signal: this._abortController?.signal
|
|
34777
34872
|
};
|
|
34778
|
-
const response = await (this._fetch ?? fetch)(this._url, init);
|
|
34873
|
+
const response = await fetchWithinOrigin(this._fetch ?? fetch)(this._url, init);
|
|
34779
34874
|
await response.body?.cancel();
|
|
34780
34875
|
if (!response.ok && response.status !== 405) {
|
|
34781
|
-
throw new StreamableHTTPError(response.status, `Failed to terminate session: ${response.statusText}`);
|
|
34876
|
+
throw new StreamableHTTPError(response.status, `Failed to terminate session: ${this._unfollowedRedirect(response, this._url) ?? response.statusText}`);
|
|
34782
34877
|
}
|
|
34783
34878
|
this._sessionId = undefined;
|
|
34784
34879
|
} catch (error2) {
|
|
@@ -34801,7 +34896,7 @@ class StreamableHTTPClientTransport {
|
|
|
34801
34896
|
}
|
|
34802
34897
|
var DEFAULT_CLIENT_INFO = {
|
|
34803
34898
|
name: "letta-code",
|
|
34804
|
-
version: "0.34.
|
|
34899
|
+
version: "0.34.26"
|
|
34805
34900
|
};
|
|
34806
34901
|
async function connectMcpServer(config2, options = {}) {
|
|
34807
34902
|
let client = new Client(options.clientInfo ?? DEFAULT_CLIENT_INFO);
|
|
@@ -35829,4 +35924,4 @@ export {
|
|
|
35829
35924
|
CloudManagedSandboxExpiredError
|
|
35830
35925
|
};
|
|
35831
35926
|
|
|
35832
|
-
//# debugId=
|
|
35927
|
+
//# debugId=59E6DEB40A201AA464756E2164756E21
|