@kontext-dev/js-sdk 0.3.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/ai/index.cjs +12 -2
- package/dist/adapters/ai/index.cjs.map +1 -1
- package/dist/adapters/ai/index.js +12 -2
- package/dist/adapters/ai/index.js.map +1 -1
- package/dist/adapters/cloudflare/index.cjs +13 -0
- package/dist/adapters/cloudflare/index.cjs.map +1 -1
- package/dist/adapters/cloudflare/index.js +13 -0
- package/dist/adapters/cloudflare/index.js.map +1 -1
- package/dist/adapters/cloudflare/react.cjs +12 -2
- package/dist/adapters/cloudflare/react.cjs.map +1 -1
- package/dist/adapters/cloudflare/react.js +12 -2
- package/dist/adapters/cloudflare/react.js.map +1 -1
- package/dist/adapters/react/index.cjs +12 -2
- package/dist/adapters/react/index.cjs.map +1 -1
- package/dist/adapters/react/index.js +12 -2
- package/dist/adapters/react/index.js.map +1 -1
- package/dist/client/index.cjs +108 -69
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.d.cts +2 -0
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.js +109 -71
- package/dist/client/index.js.map +1 -1
- package/dist/errors.cjs +78 -0
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.cts +7 -1
- package/dist/errors.d.ts +7 -1
- package/dist/errors.js +78 -1
- package/dist/errors.js.map +1 -1
- package/dist/index.cjs +151 -87
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +152 -88
- package/dist/index.js.map +1 -1
- package/dist/{kontext-CgIBANFo.d.cts → kontext-CBPuE-hq.d.cts} +3 -0
- package/dist/{kontext-CgIBANFo.d.ts → kontext-CBPuE-hq.d.ts} +3 -0
- package/dist/management/index.cjs +15 -0
- package/dist/management/index.cjs.map +1 -1
- package/dist/management/index.d.cts +2 -2
- package/dist/management/index.d.ts +2 -2
- package/dist/management/index.js +15 -1
- package/dist/management/index.js.map +1 -1
- package/dist/mcp/index.cjs +32 -3
- package/dist/mcp/index.cjs.map +1 -1
- package/dist/mcp/index.d.cts +7 -1
- package/dist/mcp/index.d.ts +7 -1
- package/dist/mcp/index.js +33 -4
- package/dist/mcp/index.js.map +1 -1
- package/dist/oauth/index.cjs +12 -2
- package/dist/oauth/index.cjs.map +1 -1
- package/dist/oauth/index.d.cts +1 -1
- package/dist/oauth/index.d.ts +1 -1
- package/dist/oauth/index.js +12 -2
- package/dist/oauth/index.js.map +1 -1
- package/dist/server/index.cjs +55 -20
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +2 -2
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.js +56 -21
- package/dist/server/index.js.map +1 -1
- package/dist/{types-CzhnlJHW.d.cts → types-DicGI7ix.d.cts} +23 -1
- package/dist/{types-CzhnlJHW.d.ts → types-DicGI7ix.d.ts} +23 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { ClientState, ConnectSessionResult, IntegrationInfo, KontextClient, KontextClientConfig, KontextTool, ToolResult, createKontextClient } from './client/index.cjs';
|
|
2
2
|
export { K as KontextOrchestrator, a as KontextOrchestratorConfig, b as KontextOrchestratorState, c as createKontextOrchestrator } from './index-DcL4a5Vq.cjs';
|
|
3
|
-
export { I as IntegrationCredential, a as IntegrationName, b as IntegrationResolvedCredentials, K as KnownIntegration, c as Kontext, d as KontextOptions, M as McpServerFactory, e as McpServerOrFactory, f as MiddlewareOptions } from './kontext-
|
|
3
|
+
export { I as IntegrationCredential, a as IntegrationName, b as IntegrationResolvedCredentials, K as KnownIntegration, c as Kontext, d as KontextOptions, M as McpServerFactory, e as McpServerOrFactory, f as MiddlewareOptions } from './kontext-CBPuE-hq.cjs';
|
|
4
4
|
export { K as KontextTokenVerifier, a as KontextTokenVerifierConfig } from './verifier-CoJmYiw3.cjs';
|
|
5
5
|
export { AuthorizationRequiredError, ConfigError, ElicitationEntry, HttpError, IntegrationConnectionRequiredError, KontextError, NetworkError, OAuthError, isKontextError, isNetworkError, isUnauthorizedError, parseHttpError } from './errors.cjs';
|
|
6
6
|
import './mcp/index.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { ClientState, ConnectSessionResult, IntegrationInfo, KontextClient, KontextClientConfig, KontextTool, ToolResult, createKontextClient } from './client/index.js';
|
|
2
2
|
export { K as KontextOrchestrator, a as KontextOrchestratorConfig, b as KontextOrchestratorState, c as createKontextOrchestrator } from './index-D5hS5PGn.js';
|
|
3
|
-
export { I as IntegrationCredential, a as IntegrationName, b as IntegrationResolvedCredentials, K as KnownIntegration, c as Kontext, d as KontextOptions, M as McpServerFactory, e as McpServerOrFactory, f as MiddlewareOptions } from './kontext-
|
|
3
|
+
export { I as IntegrationCredential, a as IntegrationName, b as IntegrationResolvedCredentials, K as KnownIntegration, c as Kontext, d as KontextOptions, M as McpServerFactory, e as McpServerOrFactory, f as MiddlewareOptions } from './kontext-CBPuE-hq.js';
|
|
4
4
|
export { K as KontextTokenVerifier, a as KontextTokenVerifierConfig } from './verifier-CoJmYiw3.js';
|
|
5
5
|
export { AuthorizationRequiredError, ConfigError, ElicitationEntry, HttpError, IntegrationConnectionRequiredError, KontextError, NetworkError, OAuthError, isKontextError, isNetworkError, isUnauthorizedError, parseHttpError } from './errors.js';
|
|
6
6
|
import './mcp/index.js';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
2
2
|
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
3
|
-
import { isInitializeRequest, UrlElicitationRequiredError, ElicitRequestSchema, ElicitationCompleteNotificationSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import { ErrorCode, isInitializeRequest, UrlElicitationRequiredError, ElicitRequestSchema, ElicitationCompleteNotificationSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
4
4
|
import { createHash, randomBytes } from 'crypto';
|
|
5
5
|
import { createRequire } from 'module';
|
|
6
6
|
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
@@ -73,8 +73,6 @@ var StorageKeys = {
|
|
|
73
73
|
function resourceTokenKey(resource) {
|
|
74
74
|
return `${StorageKeys.RESOURCE_TOKENS}:${resource}`;
|
|
75
75
|
}
|
|
76
|
-
|
|
77
|
-
// src/errors.ts
|
|
78
76
|
var KontextError = class extends Error {
|
|
79
77
|
/** Brand field for type narrowing without instanceof */
|
|
80
78
|
kontextError = true;
|
|
@@ -207,12 +205,20 @@ function isNetworkError(err) {
|
|
|
207
205
|
if (typeof causeCode === "string" && NETWORK_ERROR_CODES.has(causeCode))
|
|
208
206
|
return true;
|
|
209
207
|
}
|
|
208
|
+
if (err.name === "TypeError") {
|
|
209
|
+
const msg = err.message.toLowerCase();
|
|
210
|
+
if (msg === "failed to fetch" || msg === "load failed" || msg.includes("networkerror")) {
|
|
211
|
+
return true;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
210
214
|
return false;
|
|
211
215
|
}
|
|
212
216
|
function isUnauthorizedError(err) {
|
|
213
217
|
const props = errorProps(err);
|
|
214
218
|
if (props.statusCode === 401 || props.status === 401) return true;
|
|
219
|
+
if (props.code === 401) return true;
|
|
215
220
|
if (err.name === "UnauthorizedError") return true;
|
|
221
|
+
if (err.constructor?.name === "UnauthorizedError") return true;
|
|
216
222
|
if (err.message === "Unauthorized") return true;
|
|
217
223
|
return false;
|
|
218
224
|
}
|
|
@@ -271,6 +277,73 @@ function parseHttpError(statusCode, body) {
|
|
|
271
277
|
});
|
|
272
278
|
}
|
|
273
279
|
}
|
|
280
|
+
var MCP_CODE_MAP = {
|
|
281
|
+
[ErrorCode.ParseError]: { code: "kontext_mcp_parse_error" },
|
|
282
|
+
[ErrorCode.InvalidRequest]: { code: "kontext_mcp_invalid_request" },
|
|
283
|
+
[ErrorCode.MethodNotFound]: { code: "kontext_mcp_method_not_found" },
|
|
284
|
+
[ErrorCode.InvalidParams]: { code: "kontext_mcp_invalid_params" },
|
|
285
|
+
[ErrorCode.InternalError]: {
|
|
286
|
+
code: "kontext_mcp_internal_error",
|
|
287
|
+
statusCode: 500
|
|
288
|
+
},
|
|
289
|
+
[ErrorCode.RequestTimeout]: {
|
|
290
|
+
code: "kontext_mcp_session_expired",
|
|
291
|
+
statusCode: 401
|
|
292
|
+
},
|
|
293
|
+
[ErrorCode.ConnectionClosed]: { code: "kontext_mcp_session_error" }
|
|
294
|
+
};
|
|
295
|
+
function translateError(err) {
|
|
296
|
+
if (isKontextError(err)) return err;
|
|
297
|
+
if (!(err instanceof Error)) {
|
|
298
|
+
return new KontextError(String(err), "kontext_unknown_error");
|
|
299
|
+
}
|
|
300
|
+
const props = err;
|
|
301
|
+
if (props.code === ErrorCode.UrlElicitationRequired) {
|
|
302
|
+
const elicitations = props.elicitations ?? props.data?.elicitations;
|
|
303
|
+
const elicitation = elicitations?.[0];
|
|
304
|
+
return new IntegrationConnectionRequiredError(
|
|
305
|
+
elicitation?.integrationId ?? "unknown",
|
|
306
|
+
{
|
|
307
|
+
integrationName: elicitation?.integrationName,
|
|
308
|
+
connectUrl: elicitation?.url,
|
|
309
|
+
message: elicitation?.message,
|
|
310
|
+
cause: err
|
|
311
|
+
}
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
if (typeof props.code === "number" && props.code < 0) {
|
|
315
|
+
const entry = MCP_CODE_MAP[props.code];
|
|
316
|
+
if (entry) {
|
|
317
|
+
return new KontextError(err.message, entry.code, {
|
|
318
|
+
statusCode: entry.statusCode,
|
|
319
|
+
cause: err
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
return new KontextError(err.message, "kontext_mcp_error", {
|
|
323
|
+
cause: err,
|
|
324
|
+
meta: { mcpCode: props.code }
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
const statusCode = props.statusCode ?? props.status ?? (typeof props.code === "number" && props.code >= 400 && props.code < 600 ? props.code : void 0);
|
|
328
|
+
if (typeof statusCode === "number" && statusCode >= 400) {
|
|
329
|
+
if (statusCode === 401) {
|
|
330
|
+
return new AuthorizationRequiredError(err.message, { cause: err });
|
|
331
|
+
}
|
|
332
|
+
return new KontextError(err.message, "kontext_server_error", {
|
|
333
|
+
statusCode,
|
|
334
|
+
cause: err
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
if (isUnauthorizedError(err)) {
|
|
338
|
+
return new AuthorizationRequiredError(err.message, { cause: err });
|
|
339
|
+
}
|
|
340
|
+
if (isNetworkError(err)) {
|
|
341
|
+
return new NetworkError(err.message, { cause: err });
|
|
342
|
+
}
|
|
343
|
+
return new KontextError(err.message, "kontext_unknown_error", {
|
|
344
|
+
cause: err
|
|
345
|
+
});
|
|
346
|
+
}
|
|
274
347
|
|
|
275
348
|
// src/oauth/provider.ts
|
|
276
349
|
var KontextOAuthProvider = class {
|
|
@@ -708,7 +781,22 @@ var KontextMcp = class {
|
|
|
708
781
|
const url = typeof item.url === "string" ? item.url : "";
|
|
709
782
|
if (!id || !url) return null;
|
|
710
783
|
const category = item.category === "internal_mcp_credentials" ? "internal_mcp_credentials" : "gateway_remote_mcp";
|
|
711
|
-
const
|
|
784
|
+
const rawConnectType = item.connectType;
|
|
785
|
+
if (typeof rawConnectType !== "string") {
|
|
786
|
+
throw new KontextError(
|
|
787
|
+
"Runtime integration connectType is required in API response.",
|
|
788
|
+
"kontext_runtime_integrations_invalid_response",
|
|
789
|
+
{ meta: { integrationId: id, connectType: rawConnectType } }
|
|
790
|
+
);
|
|
791
|
+
}
|
|
792
|
+
const connectType = rawConnectType === "credentials" || rawConnectType === "oauth" || rawConnectType === "user_token" || rawConnectType === "none" ? rawConnectType : null;
|
|
793
|
+
if (!connectType) {
|
|
794
|
+
throw new KontextError(
|
|
795
|
+
`Unknown runtime integration connectType "${rawConnectType}".`,
|
|
796
|
+
"kontext_runtime_integrations_invalid_response",
|
|
797
|
+
{ meta: { integrationId: id, connectType: rawConnectType } }
|
|
798
|
+
);
|
|
799
|
+
}
|
|
712
800
|
const rawConnection = item.connection && typeof item.connection === "object" ? item.connection : void 0;
|
|
713
801
|
const connected = rawConnection && typeof rawConnection.connected === "boolean" ? rawConnection.connected : false;
|
|
714
802
|
const status = rawConnection?.status === "connected" ? "connected" : "disconnected";
|
|
@@ -719,6 +807,9 @@ var KontextMcp = class {
|
|
|
719
807
|
category,
|
|
720
808
|
connectType,
|
|
721
809
|
authMode: item.authMode === "oauth" || item.authMode === "user_token" || item.authMode === "server_token" || item.authMode === "none" ? item.authMode : void 0,
|
|
810
|
+
tokenLabel: typeof item.tokenLabel === "string" ? item.tokenLabel : void 0,
|
|
811
|
+
tokenHelpUrl: typeof item.tokenHelpUrl === "string" ? item.tokenHelpUrl : void 0,
|
|
812
|
+
tokenPlaceholder: typeof item.tokenPlaceholder === "string" ? item.tokenPlaceholder : void 0,
|
|
722
813
|
credentialSchema: item.credentialSchema,
|
|
723
814
|
requiresOauth: typeof item.requiresOauth === "boolean" ? item.requiresOauth : void 0,
|
|
724
815
|
connection: rawConnection ? {
|
|
@@ -1420,35 +1511,21 @@ async function withTransientRetry(operation, maxRetries = 1) {
|
|
|
1420
1511
|
function toKontextError(err, context) {
|
|
1421
1512
|
const contextMeta = context ? { ...context } : void 0;
|
|
1422
1513
|
const mergeMeta = (base) => contextMeta ? { ...base ?? {}, ...contextMeta } : base ?? {};
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
}
|
|
1427
|
-
const cloned = Object.create(Object.getPrototypeOf(err));
|
|
1428
|
-
Object.defineProperties(cloned, Object.getOwnPropertyDescriptors(err));
|
|
1429
|
-
Object.defineProperty(cloned, "meta", {
|
|
1430
|
-
value: mergeMeta(err.meta),
|
|
1431
|
-
enumerable: true,
|
|
1432
|
-
writable: true,
|
|
1433
|
-
configurable: true
|
|
1434
|
-
});
|
|
1435
|
-
return cloned;
|
|
1436
|
-
}
|
|
1437
|
-
if (err instanceof Error) {
|
|
1438
|
-
if (isUnauthorizedError(err)) {
|
|
1439
|
-
return new AuthorizationRequiredError(err.message, {
|
|
1440
|
-
meta: mergeMeta(),
|
|
1441
|
-
cause: err
|
|
1442
|
-
});
|
|
1443
|
-
}
|
|
1444
|
-
return new KontextError(err.message, "kontext_unknown_error", {
|
|
1445
|
-
meta: mergeMeta(),
|
|
1446
|
-
cause: err
|
|
1447
|
-
});
|
|
1514
|
+
const translated = translateError(err);
|
|
1515
|
+
if (!contextMeta) {
|
|
1516
|
+
return translated;
|
|
1448
1517
|
}
|
|
1449
|
-
|
|
1450
|
-
|
|
1518
|
+
const cloned = Object.create(
|
|
1519
|
+
Object.getPrototypeOf(translated)
|
|
1520
|
+
);
|
|
1521
|
+
Object.defineProperties(cloned, Object.getOwnPropertyDescriptors(translated));
|
|
1522
|
+
Object.defineProperty(cloned, "meta", {
|
|
1523
|
+
value: mergeMeta(translated.meta),
|
|
1524
|
+
enumerable: true,
|
|
1525
|
+
writable: true,
|
|
1526
|
+
configurable: true
|
|
1451
1527
|
});
|
|
1528
|
+
return cloned;
|
|
1452
1529
|
}
|
|
1453
1530
|
function isAuthorizationRequired(err) {
|
|
1454
1531
|
if (err instanceof AuthorizationRequiredError) return true;
|
|
@@ -2162,45 +2239,6 @@ function extractTextContent(result) {
|
|
|
2162
2239
|
}
|
|
2163
2240
|
return JSON.stringify(result);
|
|
2164
2241
|
}
|
|
2165
|
-
function translateError(err) {
|
|
2166
|
-
if (isKontextError(err)) return err;
|
|
2167
|
-
if (!(err instanceof Error)) {
|
|
2168
|
-
return new KontextError(String(err), "kontext_unknown_error");
|
|
2169
|
-
}
|
|
2170
|
-
const props = err;
|
|
2171
|
-
if (props.code === -32042) {
|
|
2172
|
-
const elicitations = props.elicitations ?? props.data?.elicitations;
|
|
2173
|
-
const elicitation = elicitations?.[0];
|
|
2174
|
-
return new IntegrationConnectionRequiredError(
|
|
2175
|
-
elicitation?.integrationId ?? "unknown",
|
|
2176
|
-
{
|
|
2177
|
-
integrationName: elicitation?.integrationName,
|
|
2178
|
-
connectUrl: elicitation?.url,
|
|
2179
|
-
message: elicitation?.message,
|
|
2180
|
-
cause: err
|
|
2181
|
-
}
|
|
2182
|
-
);
|
|
2183
|
-
}
|
|
2184
|
-
const statusCode = props.statusCode ?? props.status;
|
|
2185
|
-
if (typeof statusCode === "number" && statusCode >= 400) {
|
|
2186
|
-
if (statusCode === 401) {
|
|
2187
|
-
return new AuthorizationRequiredError(err.message, { cause: err });
|
|
2188
|
-
}
|
|
2189
|
-
return new KontextError(err.message, "kontext_server_error", {
|
|
2190
|
-
statusCode,
|
|
2191
|
-
cause: err
|
|
2192
|
-
});
|
|
2193
|
-
}
|
|
2194
|
-
if (isUnauthorizedError(err)) {
|
|
2195
|
-
return new AuthorizationRequiredError(err.message, { cause: err });
|
|
2196
|
-
}
|
|
2197
|
-
if (isNetworkError(err)) {
|
|
2198
|
-
return new NetworkError(err.message, { cause: err });
|
|
2199
|
-
}
|
|
2200
|
-
return new KontextError(err.message, "kontext_unknown_error", {
|
|
2201
|
-
cause: err
|
|
2202
|
-
});
|
|
2203
|
-
}
|
|
2204
2242
|
function createSingleEndpointKontextClient(config) {
|
|
2205
2243
|
if (!config.clientId) {
|
|
2206
2244
|
throw new ConfigError(
|
|
@@ -2490,6 +2528,7 @@ function createKontextClient(config) {
|
|
|
2490
2528
|
// src/management/types.ts
|
|
2491
2529
|
var TOKEN_EXCHANGE_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:token-exchange";
|
|
2492
2530
|
var TOKEN_TYPE_ACCESS_TOKEN = "urn:ietf:params:oauth:token-type:access_token";
|
|
2531
|
+
var TOKEN_TYPE_USER_ID = "urn:kontext:user-id";
|
|
2493
2532
|
|
|
2494
2533
|
// src/oauth/token-exchange.ts
|
|
2495
2534
|
async function exchangeToken(config, subjectToken, resource, scope, subjectTokenType = TOKEN_TYPE_ACCESS_TOKEN) {
|
|
@@ -2969,7 +3008,7 @@ var Kontext = class _Kontext {
|
|
|
2969
3008
|
oauthMetadata = null;
|
|
2970
3009
|
metadataFetchedAt = 0;
|
|
2971
3010
|
metadataPromise = null;
|
|
2972
|
-
// Token exchange caching: keyed by `${integration}\0${subjectToken}`
|
|
3011
|
+
// Token exchange caching: keyed by `${mode}\0${integration}\0${subjectToken}`
|
|
2973
3012
|
credentialCache = /* @__PURE__ */ new Map();
|
|
2974
3013
|
resolvedCredentialCache = /* @__PURE__ */ new Map();
|
|
2975
3014
|
runtimeAuthCache = /* @__PURE__ */ new Map();
|
|
@@ -3127,23 +3166,28 @@ var Kontext = class _Kontext {
|
|
|
3127
3166
|
router.delete(mcpPath, mcpHandler.delete);
|
|
3128
3167
|
return router;
|
|
3129
3168
|
}
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3169
|
+
async require(integration, tokenOrOpts) {
|
|
3170
|
+
let isUserIdMode = false;
|
|
3171
|
+
let subjectToken = "";
|
|
3172
|
+
if (typeof tokenOrOpts === "string") {
|
|
3173
|
+
subjectToken = tokenOrOpts;
|
|
3174
|
+
} else if (tokenOrOpts !== null && typeof tokenOrOpts === "object" && typeof tokenOrOpts.userId === "string") {
|
|
3175
|
+
isUserIdMode = true;
|
|
3176
|
+
subjectToken = tokenOrOpts.userId.trim();
|
|
3177
|
+
if (!subjectToken) {
|
|
3178
|
+
throw new TypeError(
|
|
3179
|
+
"Kontext.require() expects a non-empty userId when called with { userId }."
|
|
3180
|
+
);
|
|
3181
|
+
}
|
|
3182
|
+
} else {
|
|
3183
|
+
throw new TypeError(
|
|
3184
|
+
"Kontext.require() expects a token string or { userId: string }."
|
|
3185
|
+
);
|
|
3186
|
+
}
|
|
3187
|
+
const subjectTokenType = isUserIdMode ? TOKEN_TYPE_USER_ID : void 0;
|
|
3144
3188
|
const now = Date.now();
|
|
3145
3189
|
this.evictExpiredCredentials(now);
|
|
3146
|
-
const cacheKey =
|
|
3190
|
+
const cacheKey = isUserIdMode ? `u\0${integration}\0${subjectToken}` : `t\0${integration}\0${subjectToken}`;
|
|
3147
3191
|
const cached = this.credentialCache.get(cacheKey);
|
|
3148
3192
|
if (cached && now < cached.expiresAt) {
|
|
3149
3193
|
this.credentialCache.delete(cacheKey);
|
|
@@ -3160,13 +3204,25 @@ var Kontext = class _Kontext {
|
|
|
3160
3204
|
};
|
|
3161
3205
|
let response;
|
|
3162
3206
|
try {
|
|
3163
|
-
response = await exchangeToken(
|
|
3207
|
+
response = await exchangeToken(
|
|
3208
|
+
exchangeConfig,
|
|
3209
|
+
subjectToken,
|
|
3210
|
+
integration,
|
|
3211
|
+
void 0,
|
|
3212
|
+
subjectTokenType
|
|
3213
|
+
);
|
|
3164
3214
|
} catch (err) {
|
|
3165
3215
|
if (err instanceof OAuthError) {
|
|
3166
3216
|
if (err.errorCode === "integration_required" || err.message.includes("not connected") || err.message.includes("expired") && err.message.includes("reconnect")) {
|
|
3167
3217
|
const integrationId = err.meta.integrationId || integration;
|
|
3218
|
+
if (isUserIdMode) {
|
|
3219
|
+
throw new IntegrationConnectionRequiredError(integrationId, {
|
|
3220
|
+
integrationName: err.meta.integrationName,
|
|
3221
|
+
message: err.message
|
|
3222
|
+
});
|
|
3223
|
+
}
|
|
3168
3224
|
const connectUrl = await this.fetchConnectUrl(
|
|
3169
|
-
|
|
3225
|
+
subjectToken,
|
|
3170
3226
|
integrationId,
|
|
3171
3227
|
exchangeConfig
|
|
3172
3228
|
);
|
|
@@ -3677,6 +3733,12 @@ var Kontext = class _Kontext {
|
|
|
3677
3733
|
// ===========================================================================
|
|
3678
3734
|
createAgentSession(userToken, mcpSessionId, metadata) {
|
|
3679
3735
|
if (!this.clientSecret || !userToken) return;
|
|
3736
|
+
if (!metadata?.authenticatedUserId) {
|
|
3737
|
+
console.warn(
|
|
3738
|
+
"[kontext:sessions] create skipped: missing authenticated user id"
|
|
3739
|
+
);
|
|
3740
|
+
return;
|
|
3741
|
+
}
|
|
3680
3742
|
const tokenIdentifier = createHash("sha256").update(userToken).digest("hex");
|
|
3681
3743
|
this.getServiceToken().then(
|
|
3682
3744
|
(token) => fetch(`${this.apiUrl}/api/v1/agent-sessions`, {
|
|
@@ -3687,6 +3749,7 @@ var Kontext = class _Kontext {
|
|
|
3687
3749
|
},
|
|
3688
3750
|
body: JSON.stringify({
|
|
3689
3751
|
tokenIdentifier,
|
|
3752
|
+
authenticatedUserId: metadata.authenticatedUserId,
|
|
3690
3753
|
clientSessionId: mcpSessionId,
|
|
3691
3754
|
hostname: metadata?.hostname,
|
|
3692
3755
|
userAgent: metadata?.userAgent,
|
|
@@ -3908,6 +3971,7 @@ var Kontext = class _Kontext {
|
|
|
3908
3971
|
status: "ok"
|
|
3909
3972
|
});
|
|
3910
3973
|
this.createAgentSession(authInfo?.token, sid, {
|
|
3974
|
+
authenticatedUserId: typeof authInfo?.extra?.sub === "string" ? authInfo.extra.sub : void 0,
|
|
3911
3975
|
hostname: req.headers["x-forwarded-for"],
|
|
3912
3976
|
userAgent: req.headers["user-agent"],
|
|
3913
3977
|
tokenExpiresAt: authInfo?.expiresAt
|