@letta-ai/letta-code 0.34.25 → 0.34.27
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/cursor-worker.js +168 -0
- package/dist/agent-presets.js +5 -68
- package/dist/agent-presets.js.map +2 -2
- package/dist/channels-slack.js +30 -24
- package/dist/channels-slack.js.map +3 -3
- package/dist/mcp-client.js +233 -75
- package/dist/mcp-client.js.map +9 -9
- package/dist/mcp-oauth.js +257 -89
- package/dist/mcp-oauth.js.map +12 -11
- package/dist/memory-confinement.js +109 -51
- package/dist/memory-confinement.js.map +9 -8
- package/dist/types/agent/mcp-originator-authority-file.d.ts +1 -0
- package/dist/types/agent/mcp-originator-authority-file.d.ts.map +1 -1
- package/dist/types/agent/memory-filesystem.d.ts +3 -3
- package/dist/types/agent/memory-filesystem.d.ts.map +1 -1
- package/dist/types/agent/memory-git.d.ts +2 -2
- package/dist/types/agent/memory-git.d.ts.map +1 -1
- package/dist/types/agent/skills.d.ts +3 -3
- package/dist/types/agent/skills.d.ts.map +1 -1
- package/dist/types/agent/subagents/index.d.ts +8 -0
- package/dist/types/agent/subagents/index.d.ts.map +1 -1
- package/dist/types/agent/subagents/manager.d.ts.map +1 -1
- package/dist/types/agent/subagents/memory-worker.d.ts +2 -8
- package/dist/types/agent/subagents/memory-worker.d.ts.map +1 -1
- package/dist/types/agent/subagents/subagent-launcher.d.ts.map +1 -1
- package/dist/types/backend/api/providers.d.ts +8 -2
- package/dist/types/backend/api/providers.d.ts.map +1 -1
- package/dist/types/backend/api/schedules.d.ts +16 -2
- package/dist/types/backend/api/schedules.d.ts.map +1 -1
- package/dist/types/backend/backend.d.ts +5 -2
- package/dist/types/backend/backend.d.ts.map +1 -1
- package/dist/types/backend/dev/fake-headless-backend.d.ts +2 -1
- package/dist/types/backend/dev/fake-headless-backend.d.ts.map +1 -1
- package/dist/types/backend/dev/pi-model-factory.d.ts.map +1 -1
- package/dist/types/backend/local/local-provider-auth-store.d.ts +2 -0
- package/dist/types/backend/local/local-provider-auth-store.d.ts.map +1 -1
- package/dist/types/backend/local/local-transcript-history.d.ts +10 -0
- package/dist/types/backend/local/local-transcript-history.d.ts.map +1 -0
- package/dist/types/backend/local/local-transcript.d.ts +6 -0
- package/dist/types/backend/local/local-transcript.d.ts.map +1 -1
- package/dist/types/channels/slack/attachment-primitives.d.ts +2 -1
- package/dist/types/channels/slack/attachment-primitives.d.ts.map +1 -1
- package/dist/types/channels/types.d.ts +1 -1
- package/dist/types/cli/helpers/chunk-log.d.ts.map +1 -1
- package/dist/types/cli/subcommands/mcp.d.ts +2 -2
- package/dist/types/cli/subcommands/mcp.d.ts.map +1 -1
- package/dist/types/cron/cron-file.d.ts.map +1 -1
- package/dist/types/cron/process-identity.d.ts.map +1 -1
- package/dist/types/cron/run-log.d.ts +1 -0
- package/dist/types/cron/run-log.d.ts.map +1 -1
- package/dist/types/headless-environment-response.d.ts +27 -0
- package/dist/types/headless-environment-response.d.ts.map +1 -1
- package/dist/types/hooks/loader.d.ts.map +1 -1
- package/dist/types/mods/paths.d.ts +3 -3
- package/dist/types/mods/paths.d.ts.map +1 -1
- package/dist/types/permissions/agent-memory-prefixes.d.ts.map +1 -1
- package/dist/types/permissions/analyzer.d.ts +1 -0
- package/dist/types/permissions/analyzer.d.ts.map +1 -1
- package/dist/types/permissions/cross-agent-guard.d.ts.map +1 -1
- package/dist/types/permissions/loader.d.ts +2 -1
- package/dist/types/permissions/loader.d.ts.map +1 -1
- package/dist/types/permissions/sandbox-policy.d.ts +9 -7
- package/dist/types/permissions/sandbox-policy.d.ts.map +1 -1
- package/dist/types/providers/byok-providers.d.ts +14 -0
- package/dist/types/providers/byok-providers.d.ts.map +1 -1
- package/dist/types/sandbox/bwrap.d.ts +2 -2
- package/dist/types/sandbox/bwrap.d.ts.map +1 -1
- package/dist/types/sandbox/policy.d.ts +20 -3
- package/dist/types/sandbox/policy.d.ts.map +1 -1
- package/dist/types/sandbox/seatbelt.d.ts +1 -1
- package/dist/types/sandbox/seatbelt.d.ts.map +1 -1
- package/dist/types/settings-manager.d.ts +4 -12
- package/dist/types/settings-manager.d.ts.map +1 -1
- package/dist/types/tools/commit-trailer.d.ts +27 -0
- package/dist/types/tools/commit-trailer.d.ts.map +1 -0
- package/dist/types/tools/impl/claude-stream-session.d.ts.map +1 -1
- package/dist/types/tools/impl/codex-app-server.d.ts +2 -0
- package/dist/types/tools/impl/codex-app-server.d.ts.map +1 -1
- package/dist/types/tools/impl/cursor-session.d.ts +28 -0
- package/dist/types/tools/impl/cursor-session.d.ts.map +1 -0
- package/dist/types/tools/impl/cursor-worker.d.ts +35 -0
- package/dist/types/tools/impl/cursor-worker.d.ts.map +1 -0
- package/dist/types/tools/impl/external-coding-agent-task.d.ts.map +1 -1
- package/dist/types/tools/impl/external-coding-agent.d.ts +1 -1
- package/dist/types/tools/impl/external-coding-agent.d.ts.map +1 -1
- package/dist/types/tools/impl/memory-task-lifecycle.d.ts +2 -2
- package/dist/types/tools/impl/memory-task-lifecycle.d.ts.map +1 -1
- package/dist/types/tools/impl/overflow.d.ts +1 -1
- package/dist/types/tools/impl/overflow.d.ts.map +1 -1
- package/dist/types/tools/impl/remote-external-coding-agent.d.ts.map +1 -1
- package/dist/types/tools/impl/ripgrep-manager.d.ts.map +1 -1
- package/dist/types/tools/impl/send-agent-message.d.ts.map +1 -1
- package/dist/types/tools/impl/shell-env.d.ts.map +1 -1
- package/dist/types/tools/impl/task.d.ts.map +1 -1
- package/dist/types/tools/impl/wake.d.ts.map +1 -1
- package/dist/types/tools/script-tool-scope.d.ts.map +1 -1
- package/dist/types/tools/tool-definitions.d.ts.map +1 -1
- package/dist/types/tools/workflow/sdk-spawner.d.ts.map +1 -1
- package/dist/types/utils/fs.d.ts +5 -1
- package/dist/types/utils/fs.d.ts.map +1 -1
- package/dist/types/utils/local-backend-paths.d.ts +1 -1
- package/dist/types/utils/local-backend-paths.d.ts.map +1 -1
- package/dist/types/utils/native-cli-env.d.ts +3 -0
- package/dist/types/utils/native-cli-env.d.ts.map +1 -0
- package/dist/types/utils/process-liveness.d.ts +9 -0
- package/dist/types/utils/process-liveness.d.ts.map +1 -1
- package/dist/types/utils/secrets.d.ts +1 -1
- package/dist/types/utils/secrets.d.ts.map +1 -1
- package/dist/types/utils/settings-path.d.ts +14 -0
- package/dist/types/utils/settings-path.d.ts.map +1 -0
- package/dist/types/utils/transcript-paths.d.ts +1 -1
- package/dist/types/websocket/listener/constants.d.ts +6 -0
- package/dist/types/websocket/listener/constants.d.ts.map +1 -1
- package/dist/types/websocket/listener/input-disposition-path.d.ts.map +1 -1
- package/dist/types/websocket/listener/interrupted-turn-storage.d.ts.map +1 -1
- package/dist/types/websocket/listener/org-credentials.d.ts.map +1 -1
- package/dist/types/websocket/listener/remote-settings.d.ts +2 -2
- package/dist/types/websocket/listener/remote-settings.d.ts.map +1 -1
- package/dist/types/websocket/listener/turn-finished-replay.d.ts +1 -0
- package/dist/types/websocket/listener/turn-finished-replay.d.ts.map +1 -1
- package/letta.js +5769 -4506
- package/npm-shrinkwrap.json +293 -115
- package/package.json +6 -3
- package/scripts/agent-watch/verify-pr-identity.test.ts +148 -0
- package/scripts/agent-watch/verify-pr-identity.ts +72 -14
- package/scripts/claude-watch/agent-watch.ts +8 -2
- package/scripts/claude-watch/release-source.test.ts +120 -0
- package/scripts/claude-watch/release-source.ts +79 -9
- package/scripts/codex-watch/agent-watch.ts +2 -2
- package/scripts/codex-watch/release-analysis.test.ts +112 -6
- package/scripts/codex-watch/release-analysis.ts +63 -6
- package/scripts/isolated-unit-tests.json +10 -0
- package/scripts/source-file-size-baseline.json +5 -4
- package/scripts/test-home-preload.ts +1 -0
- package/skills/acquiring-skills/SKILL.md +4 -4
- package/skills/creating-mods/SKILL.md +3 -3
- package/skills/creating-mods/references/analysis-mode.md +7 -5
- package/skills/creating-mods/references/architecture.md +2 -2
- package/skills/creating-mods/references/plan-mode.md +12 -11
- package/skills/creating-mods/references/providers.md +1 -1
- package/skills/creating-skills/scripts/init-skill.ts +4 -2
- package/skills/customizing-commands/SKILL.md +3 -3
- package/skills/customizing-statusline/SKILL.md +3 -3
- package/skills/customizing-statusline/references/api.md +3 -3
- package/skills/customizing-statusline/references/migration.md +2 -2
- package/skills/initializing-memory/SKILL.md +2 -2
- package/skills/managing-agent-webhooks/SKILL.md +23 -3
- package/skills/managing-agent-webhooks/scripts/manage-agent-webhooks.mjs +40 -11
- package/skills/self-configuration/SKILL.md +5 -5
- package/skills/self-configuration/scripts/add_permission.py +26 -5
- package/skills/self-configuration/scripts/show_config.py +17 -2
- package/skills/syncing-memory-filesystem/SKILL.md +2 -10
- package/skills/video-generation/SKILL.md +152 -0
- package/skills/workflow-authoring/SKILL.md +1 -1
- package/dist/types/agent/memory-worktree.d.ts +0 -83
- package/dist/types/agent/memory-worktree.d.ts.map +0 -1
package/dist/mcp-oauth.js
CHANGED
|
@@ -7612,14 +7612,14 @@ var execFile5, __dirname2, localXdgOpenPath, platform, arch, pTryEach = async (a
|
|
|
7612
7612
|
}
|
|
7613
7613
|
const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);
|
|
7614
7614
|
if (options.wait) {
|
|
7615
|
-
return new Promise((
|
|
7615
|
+
return new Promise((resolve2, reject) => {
|
|
7616
7616
|
subprocess.once("error", reject);
|
|
7617
7617
|
subprocess.once("close", (exitCode) => {
|
|
7618
7618
|
if (!options.allowNonzeroExitCode && exitCode > 0) {
|
|
7619
7619
|
reject(new Error(`Exited with code ${exitCode}`));
|
|
7620
7620
|
return;
|
|
7621
7621
|
}
|
|
7622
|
-
|
|
7622
|
+
resolve2(subprocess);
|
|
7623
7623
|
});
|
|
7624
7624
|
});
|
|
7625
7625
|
}
|
|
@@ -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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
14309
|
-
clientInformation
|
|
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
|
|
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
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
14793
|
+
clientInformation ?? (clientInformation = await readClientInformation());
|
|
14655
14794
|
return executeTokenRequest(authorizationServerUrl, {
|
|
14656
14795
|
metadata,
|
|
14657
14796
|
tokenRequestParams,
|
|
14658
|
-
clientInformation
|
|
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
|
|
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 &&
|
|
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
|
|
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
|
|
17104
|
-
|
|
17105
|
-
|
|
17106
|
-
|
|
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.
|
|
17553
|
+
version: "0.34.27"
|
|
17396
17554
|
};
|
|
17397
17555
|
async function connectMcpServer(config2, options = {}) {
|
|
17398
17556
|
let client = new Client(options.clientInfo ?? DEFAULT_CLIENT_INFO);
|
|
@@ -17776,9 +17934,24 @@ import {
|
|
|
17776
17934
|
readFileSync,
|
|
17777
17935
|
unlinkSync
|
|
17778
17936
|
} from "node:fs";
|
|
17937
|
+
import { join as join2 } from "node:path";
|
|
17938
|
+
|
|
17939
|
+
// src/utils/settings-path.ts
|
|
17779
17940
|
import { homedir } from "node:os";
|
|
17780
|
-
import { join } from "node:path";
|
|
17781
|
-
|
|
17941
|
+
import { isAbsolute, join, normalize, resolve } from "node:path";
|
|
17942
|
+
function resolveGlobalConfigDir(env = process.env, fallbackHome = homedir()) {
|
|
17943
|
+
const override = env.LETTA_CONFIG_DIR?.trim();
|
|
17944
|
+
if (override) {
|
|
17945
|
+
if (!isAbsolute(override)) {
|
|
17946
|
+
throw new Error("LETTA_CONFIG_DIR must be absolute");
|
|
17947
|
+
}
|
|
17948
|
+
return normalize(override);
|
|
17949
|
+
}
|
|
17950
|
+
return join(env.HOME || fallbackHome, ".letta");
|
|
17951
|
+
}
|
|
17952
|
+
|
|
17953
|
+
// src/utils/debug.ts
|
|
17954
|
+
var DEBUG_LOG_DIR = join2(resolveGlobalConfigDir(), "logs", "debug");
|
|
17782
17955
|
var MAX_SESSION_FILES = 5;
|
|
17783
17956
|
var MAX_LOG_BYTES = 10 * 1024 * 1024;
|
|
17784
17957
|
var DEFAULT_TAIL_LINES = 50;
|
|
@@ -17794,8 +17967,8 @@ class DebugLogFile {
|
|
|
17794
17967
|
const telem = process.env.LETTA_CODE_TELEM;
|
|
17795
17968
|
if (telem === "0" || telem === "false")
|
|
17796
17969
|
return;
|
|
17797
|
-
this.agentDir =
|
|
17798
|
-
this.logPath =
|
|
17970
|
+
this.agentDir = join2(options.dir ?? DEBUG_LOG_DIR, agentId);
|
|
17971
|
+
this.logPath = join2(this.agentDir, `${sessionId}.log`);
|
|
17799
17972
|
this.maxBytes = options.maxBytes ?? MAX_LOG_BYTES;
|
|
17800
17973
|
this.dirCreated = false;
|
|
17801
17974
|
this.bytesWritten = 0;
|
|
@@ -17860,7 +18033,7 @@ class DebugLogFile {
|
|
|
17860
18033
|
const toDelete = files.slice(0, files.length - MAX_SESSION_FILES + 1);
|
|
17861
18034
|
for (const file of toDelete) {
|
|
17862
18035
|
try {
|
|
17863
|
-
unlinkSync(
|
|
18036
|
+
unlinkSync(join2(this.agentDir, file));
|
|
17864
18037
|
} catch {}
|
|
17865
18038
|
}
|
|
17866
18039
|
}
|
|
@@ -17871,11 +18044,6 @@ var debugLogFile = new DebugLogFile;
|
|
|
17871
18044
|
|
|
17872
18045
|
// src/utils/secrets.ts
|
|
17873
18046
|
var secrets = globalThis.Bun?.secrets;
|
|
17874
|
-
function scopeServiceName(name) {
|
|
17875
|
-
const testPrefix = process.env.LETTA_TEST_SECRETS_SERVICE_PREFIX?.trim();
|
|
17876
|
-
return testPrefix ? `${testPrefix}:${name}` : name;
|
|
17877
|
-
}
|
|
17878
|
-
var SERVICE_NAME = scopeServiceName("letta-code");
|
|
17879
18047
|
var warnedSecretReadFailures = new Set;
|
|
17880
18048
|
|
|
17881
18049
|
// src/mcp-oauth.ts
|
|
@@ -18557,7 +18725,7 @@ function subscribeToAuthorization(flightKey, flight, signal) {
|
|
|
18557
18725
|
flight.controller.abort();
|
|
18558
18726
|
}
|
|
18559
18727
|
};
|
|
18560
|
-
return new Promise((
|
|
18728
|
+
return new Promise((resolve2, reject) => {
|
|
18561
18729
|
let settled = false;
|
|
18562
18730
|
const abort = () => {
|
|
18563
18731
|
if (settled)
|
|
@@ -18575,7 +18743,7 @@ function subscribeToAuthorization(flightKey, flight, signal) {
|
|
|
18575
18743
|
settled = true;
|
|
18576
18744
|
signal?.removeEventListener("abort", abort);
|
|
18577
18745
|
release();
|
|
18578
|
-
|
|
18746
|
+
resolve2({ ...credentials });
|
|
18579
18747
|
}, (error2) => {
|
|
18580
18748
|
if (settled)
|
|
18581
18749
|
return;
|
|
@@ -18608,4 +18776,4 @@ export {
|
|
|
18608
18776
|
authorizeMcpServerWithStorage
|
|
18609
18777
|
};
|
|
18610
18778
|
|
|
18611
|
-
//# debugId=
|
|
18779
|
+
//# debugId=A8351E3D1202779664756E2164756E21
|