@inkeep/agents-core 0.36.1 → 0.37.1
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/auth/auth-schema.js +1 -1
- package/dist/auth/auth-validation-schemas.js +1 -1
- package/dist/auth/auth.d.ts +3 -3
- package/dist/auth/auth.js +32 -5
- package/dist/{auth-detection-CGqhPDnj.d.ts → auth-detection-7G0Dxt55.d.ts} +11 -0
- package/dist/chunk-CMNLBV2A.js +39 -0
- package/dist/{chunk-SG75RA63.js → chunk-I6IF7ZTL.js} +2 -2
- package/dist/{chunk-ZCEKN54E.js → chunk-K6GMXJPW.js} +6 -6
- package/dist/{chunk-4RVJB4KV.js → chunk-LL6F3EAR.js} +4 -1
- package/dist/{chunk-TGESM3JG.js → chunk-MQMMFK2K.js} +14 -3
- package/dist/{chunk-NFYCSHD3.js → chunk-PVRIMF6N.js} +2 -1
- package/dist/{chunk-4OISWRFK.js → chunk-ROXPFQAM.js} +357 -40
- package/dist/{chunk-OEHP46F7.js → chunk-W3QDM7WH.js} +1 -1
- package/dist/{chunk-KMLLKRUY.js → chunk-ZEZCCHV7.js} +1 -1
- package/dist/{client-HrEgt7wv.d.ts → client-B_3j-V4-.d.ts} +1 -1
- package/dist/client-exports.d.ts +6 -3
- package/dist/client-exports.js +3 -3
- package/dist/constants/schema-validation/index.js +1 -1
- package/dist/credential-stores/index.d.ts +3 -3
- package/dist/db/schema.d.ts +2 -2
- package/dist/db/schema.js +2 -2
- package/dist/db/test-client.d.ts +3 -3
- package/dist/db/test-client.js +1 -1
- package/dist/index.d.ts +143 -9
- package/dist/index.js +280 -67
- package/dist/{schema-CoC3tYFX.d.ts → schema-DKbG39on.d.ts} +24 -1
- package/dist/server-BXoUiBMg.d.ts +127 -0
- package/dist/types/index.d.ts +33 -113
- package/dist/types/index.js +1 -1
- package/dist/{utility-C4QAannk.d.ts → utility-Lo5NoRHK.d.ts} +146 -11
- package/dist/validation/index.d.ts +2 -2
- package/dist/validation/index.js +2 -2
- package/drizzle/{0001_fair_malice.sql → 0001_calm_sheva_callister.sql} +1 -16
- package/drizzle/meta/0001_snapshot.json +7 -1
- package/drizzle/meta/_journal.json +2 -2
- package/package.json +12 -6
- package/dist/chunk-H2F72PDA.js +0 -15
- /package/dist/{chunk-NOPEANIU.js → chunk-NFTJ5JBY.js} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { loadEnvironmentFiles, env } from './chunk-
|
|
1
|
+
import { loadEnvironmentFiles, env } from './chunk-LL6F3EAR.js';
|
|
2
2
|
import { getLogger } from './chunk-DN4B564Y.js';
|
|
3
3
|
import { CredentialStoreType, MCPTransportType } from './chunk-YFHT5M2R.js';
|
|
4
4
|
import { z } from 'zod';
|
|
@@ -15,6 +15,13 @@ import { CallToolResultSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
|
15
15
|
import { tool } from 'ai';
|
|
16
16
|
import { asyncExitHook, gracefulExit } from 'exit-hook';
|
|
17
17
|
import { match } from 'ts-pattern';
|
|
18
|
+
import { createAnthropic, anthropic } from '@ai-sdk/anthropic';
|
|
19
|
+
import { createGateway, gateway } from '@ai-sdk/gateway';
|
|
20
|
+
import { createGoogleGenerativeAI, google } from '@ai-sdk/google';
|
|
21
|
+
import { createOpenAI, openai } from '@ai-sdk/openai';
|
|
22
|
+
import { createOpenAICompatible } from '@ai-sdk/openai-compatible';
|
|
23
|
+
import { createOpenRouter, openrouter } from '@openrouter/ai-sdk-provider';
|
|
24
|
+
import * as jose from 'jose';
|
|
18
25
|
import { SignJWT, jwtVerify } from 'jose';
|
|
19
26
|
import { Composio } from '@composio/core';
|
|
20
27
|
import { SpanStatusCode, trace } from '@opentelemetry/api';
|
|
@@ -177,10 +184,17 @@ function normalizeDateString(dateString) {
|
|
|
177
184
|
}
|
|
178
185
|
const pgTimestampPattern = /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(\.\d{1,3})?$/;
|
|
179
186
|
if (pgTimestampPattern.test(dateString)) {
|
|
180
|
-
return dateString.replace(" ", "T")
|
|
187
|
+
return `${dateString.replace(" ", "T")}Z`;
|
|
181
188
|
}
|
|
182
189
|
return dateString;
|
|
183
190
|
}
|
|
191
|
+
function toISODateString(dateValue) {
|
|
192
|
+
if (typeof dateValue === "string") {
|
|
193
|
+
const normalized = normalizeDateString(dateValue);
|
|
194
|
+
return typeof normalized === "string" ? normalized : normalized.toISOString();
|
|
195
|
+
}
|
|
196
|
+
return dateValue.toISOString();
|
|
197
|
+
}
|
|
184
198
|
var ErrorCode = z$1.enum([
|
|
185
199
|
"bad_request",
|
|
186
200
|
"unauthorized",
|
|
@@ -460,6 +474,28 @@ function getRequestExecutionContext(c) {
|
|
|
460
474
|
}
|
|
461
475
|
return executionContext;
|
|
462
476
|
}
|
|
477
|
+
|
|
478
|
+
// src/utils/format-messages.ts
|
|
479
|
+
function formatMessagesForLLM(messages) {
|
|
480
|
+
return messages.map((message) => {
|
|
481
|
+
const role = message.role === "user" ? "user" : message.role === "agent" ? "assistant" : "system";
|
|
482
|
+
const content = typeof message.content === "object" && message.content && "text" in message.content ? message.content.text : String(message.content || "");
|
|
483
|
+
return {
|
|
484
|
+
role,
|
|
485
|
+
content,
|
|
486
|
+
timestamp: message.createdAt,
|
|
487
|
+
fromSubAgentId: message.fromSubAgentId
|
|
488
|
+
};
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
function formatMessagesForLLMContext(messages) {
|
|
492
|
+
const formattedMessages = formatMessagesForLLM(messages);
|
|
493
|
+
return formattedMessages.map((msg) => {
|
|
494
|
+
const roleLabel = msg.role === "user" ? "User" : msg.role === "assistant" ? "Agent" : "System";
|
|
495
|
+
const agentInfo = msg.fromSubAgentId ? ` (${msg.fromSubAgentId})` : "";
|
|
496
|
+
return `${roleLabel}${agentInfo}: ${msg.content}`;
|
|
497
|
+
}).join("\n\n");
|
|
498
|
+
}
|
|
463
499
|
var McpClient = class {
|
|
464
500
|
name;
|
|
465
501
|
client;
|
|
@@ -596,6 +632,9 @@ var McpClient = class {
|
|
|
596
632
|
case "array":
|
|
597
633
|
zodType = z.array(z.any());
|
|
598
634
|
break;
|
|
635
|
+
case "object":
|
|
636
|
+
zodType = createZodSchema(propDef);
|
|
637
|
+
break;
|
|
599
638
|
default:
|
|
600
639
|
zodType = z.any();
|
|
601
640
|
}
|
|
@@ -634,7 +673,268 @@ var McpClient = class {
|
|
|
634
673
|
return results;
|
|
635
674
|
}
|
|
636
675
|
};
|
|
637
|
-
var logger2 = getLogger("
|
|
676
|
+
var logger2 = getLogger("ModelFactory");
|
|
677
|
+
var nimDefault = createOpenAICompatible({
|
|
678
|
+
name: "nim",
|
|
679
|
+
baseURL: "https://integrate.api.nvidia.com/v1",
|
|
680
|
+
headers: {
|
|
681
|
+
Authorization: `Bearer ${process.env.NIM_API_KEY}`
|
|
682
|
+
}
|
|
683
|
+
});
|
|
684
|
+
var ModelFactory = class _ModelFactory {
|
|
685
|
+
/**
|
|
686
|
+
* Create a provider instance with custom configuration
|
|
687
|
+
*/
|
|
688
|
+
static createProvider(provider, config) {
|
|
689
|
+
switch (provider) {
|
|
690
|
+
case "anthropic":
|
|
691
|
+
return createAnthropic(config);
|
|
692
|
+
case "openai":
|
|
693
|
+
return createOpenAI(config);
|
|
694
|
+
case "google":
|
|
695
|
+
return createGoogleGenerativeAI(config);
|
|
696
|
+
case "openrouter":
|
|
697
|
+
return {
|
|
698
|
+
...createOpenRouter(config),
|
|
699
|
+
textEmbeddingModel: () => {
|
|
700
|
+
throw new Error("OpenRouter does not support text embeddings");
|
|
701
|
+
},
|
|
702
|
+
imageModel: () => {
|
|
703
|
+
throw new Error("OpenRouter does not support image generation");
|
|
704
|
+
}
|
|
705
|
+
};
|
|
706
|
+
case "gateway":
|
|
707
|
+
return createGateway(config);
|
|
708
|
+
case "nim": {
|
|
709
|
+
const nimConfig = {
|
|
710
|
+
name: "nim",
|
|
711
|
+
baseURL: "https://integrate.api.nvidia.com/v1",
|
|
712
|
+
headers: {
|
|
713
|
+
Authorization: `Bearer ${process.env.NIM_API_KEY}`
|
|
714
|
+
},
|
|
715
|
+
...config
|
|
716
|
+
};
|
|
717
|
+
return createOpenAICompatible(nimConfig);
|
|
718
|
+
}
|
|
719
|
+
case "custom": {
|
|
720
|
+
if (!config.baseURL && !config.baseUrl) {
|
|
721
|
+
throw new Error(
|
|
722
|
+
"Custom provider requires baseURL. Please provide it in providerOptions.baseURL or providerOptions.baseUrl"
|
|
723
|
+
);
|
|
724
|
+
}
|
|
725
|
+
const customConfig = {
|
|
726
|
+
name: "custom",
|
|
727
|
+
baseURL: config.baseURL || config.baseUrl,
|
|
728
|
+
headers: {
|
|
729
|
+
...process.env.CUSTOM_LLM_API_KEY && {
|
|
730
|
+
Authorization: `Bearer ${process.env.CUSTOM_LLM_API_KEY}`
|
|
731
|
+
},
|
|
732
|
+
...config.headers || {}
|
|
733
|
+
},
|
|
734
|
+
...config
|
|
735
|
+
};
|
|
736
|
+
logger2.info(
|
|
737
|
+
{
|
|
738
|
+
config: {
|
|
739
|
+
baseURL: customConfig.baseURL,
|
|
740
|
+
hasApiKey: !!process.env.CUSTOM_LLM_API_KEY,
|
|
741
|
+
apiKeyPrefix: `${process.env.CUSTOM_LLM_API_KEY?.substring(0, 10)}...`,
|
|
742
|
+
headers: Object.keys(customConfig.headers || {})
|
|
743
|
+
}
|
|
744
|
+
},
|
|
745
|
+
"Creating custom OpenAI-compatible provider"
|
|
746
|
+
);
|
|
747
|
+
return createOpenAICompatible(customConfig);
|
|
748
|
+
}
|
|
749
|
+
default:
|
|
750
|
+
throw new Error(`Unsupported provider: ${provider}`);
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
/**
|
|
754
|
+
* Extract provider configuration from providerOptions
|
|
755
|
+
* Only includes settings that go to the provider constructor (baseURL, apiKey, etc.)
|
|
756
|
+
*/
|
|
757
|
+
static extractProviderConfig(providerOptions) {
|
|
758
|
+
if (!providerOptions) {
|
|
759
|
+
return {};
|
|
760
|
+
}
|
|
761
|
+
const providerConfig = {};
|
|
762
|
+
if (providerOptions.baseUrl || providerOptions.baseURL) {
|
|
763
|
+
providerConfig.baseURL = providerOptions.baseUrl || providerOptions.baseURL;
|
|
764
|
+
}
|
|
765
|
+
if (providerOptions.headers) {
|
|
766
|
+
providerConfig.headers = providerOptions.headers;
|
|
767
|
+
}
|
|
768
|
+
if (providerOptions.gateway) {
|
|
769
|
+
Object.assign(providerConfig, providerOptions.gateway);
|
|
770
|
+
}
|
|
771
|
+
if (providerOptions.nim) {
|
|
772
|
+
Object.assign(providerConfig, providerOptions.nim);
|
|
773
|
+
}
|
|
774
|
+
if (providerOptions.custom) {
|
|
775
|
+
Object.assign(providerConfig, providerOptions.custom);
|
|
776
|
+
}
|
|
777
|
+
return providerConfig;
|
|
778
|
+
}
|
|
779
|
+
/**
|
|
780
|
+
* Create a language model instance from configuration
|
|
781
|
+
* Throws error if no config provided - models must be configured at project level
|
|
782
|
+
*/
|
|
783
|
+
static createModel(config) {
|
|
784
|
+
if (!config?.model?.trim()) {
|
|
785
|
+
throw new Error(
|
|
786
|
+
"Model configuration is required. Please configure models at the project level."
|
|
787
|
+
);
|
|
788
|
+
}
|
|
789
|
+
const modelSettings = config;
|
|
790
|
+
if (!modelSettings.model) {
|
|
791
|
+
throw new Error("Model configuration is required");
|
|
792
|
+
}
|
|
793
|
+
const modelString = modelSettings.model.trim();
|
|
794
|
+
const { provider, modelName } = _ModelFactory.parseModelString(modelString);
|
|
795
|
+
logger2.debug(
|
|
796
|
+
{
|
|
797
|
+
provider,
|
|
798
|
+
model: modelName,
|
|
799
|
+
fullModelString: modelSettings.model,
|
|
800
|
+
hasProviderOptions: !!modelSettings.providerOptions
|
|
801
|
+
},
|
|
802
|
+
"Creating language model from config"
|
|
803
|
+
);
|
|
804
|
+
const providerConfig = _ModelFactory.extractProviderConfig(modelSettings.providerOptions);
|
|
805
|
+
if (Object.keys(providerConfig).length > 0) {
|
|
806
|
+
logger2.info({ config: providerConfig }, `Applying custom ${provider} provider configuration`);
|
|
807
|
+
const customProvider = _ModelFactory.createProvider(provider, providerConfig);
|
|
808
|
+
return customProvider.languageModel(modelName);
|
|
809
|
+
}
|
|
810
|
+
switch (provider) {
|
|
811
|
+
case "anthropic":
|
|
812
|
+
return anthropic(modelName);
|
|
813
|
+
case "openai":
|
|
814
|
+
return openai(modelName);
|
|
815
|
+
case "google":
|
|
816
|
+
return google(modelName);
|
|
817
|
+
case "openrouter":
|
|
818
|
+
return openrouter(modelName);
|
|
819
|
+
case "gateway":
|
|
820
|
+
return gateway(modelName);
|
|
821
|
+
case "nim":
|
|
822
|
+
return nimDefault(modelName);
|
|
823
|
+
case "custom":
|
|
824
|
+
throw new Error(
|
|
825
|
+
"Custom provider requires configuration. Please provide baseURL in providerOptions.custom.baseURL or providerOptions.baseURL"
|
|
826
|
+
);
|
|
827
|
+
default:
|
|
828
|
+
throw new Error(
|
|
829
|
+
`Unsupported provider: ${provider}. Supported providers are: ${_ModelFactory.BUILT_IN_PROVIDERS.join(", ")}. To access other models, use OpenRouter (openrouter/model-id), Vercel AI Gateway (gateway/model-id), NVIDIA NIM (nim/model-id), or Custom OpenAI-compatible (custom/model-id).`
|
|
830
|
+
);
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
/**
|
|
834
|
+
* Built-in providers that have special handling
|
|
835
|
+
*/
|
|
836
|
+
static BUILT_IN_PROVIDERS = [
|
|
837
|
+
"anthropic",
|
|
838
|
+
"openai",
|
|
839
|
+
"google",
|
|
840
|
+
"openrouter",
|
|
841
|
+
"gateway",
|
|
842
|
+
"nim",
|
|
843
|
+
"custom"
|
|
844
|
+
];
|
|
845
|
+
/**
|
|
846
|
+
* Parse model string to extract provider and model name
|
|
847
|
+
* Examples: "anthropic/claude-sonnet-4" -> { provider: "anthropic", modelName: "claude-sonnet-4" }
|
|
848
|
+
* "openrouter/anthropic/claude-sonnet-4" -> { provider: "openrouter", modelName: "anthropic/claude-sonnet-4" }
|
|
849
|
+
* "claude-sonnet-4" -> { provider: "anthropic", modelName: "claude-sonnet-4" } (default to anthropic)
|
|
850
|
+
*/
|
|
851
|
+
static parseModelString(modelString) {
|
|
852
|
+
if (modelString.includes("/")) {
|
|
853
|
+
const [provider, ...modelParts] = modelString.split("/");
|
|
854
|
+
const normalizedProvider = provider.toLowerCase();
|
|
855
|
+
if (!_ModelFactory.BUILT_IN_PROVIDERS.includes(normalizedProvider)) {
|
|
856
|
+
throw new Error(
|
|
857
|
+
`Unsupported provider: ${normalizedProvider}. Supported providers are: ${_ModelFactory.BUILT_IN_PROVIDERS.join(", ")}. To access other models, use OpenRouter (openrouter/model-id), Vercel AI Gateway (gateway/model-id), NVIDIA NIM (nim/model-id), or Custom OpenAI-compatible (custom/model-id).`
|
|
858
|
+
);
|
|
859
|
+
}
|
|
860
|
+
return {
|
|
861
|
+
provider: normalizedProvider,
|
|
862
|
+
modelName: modelParts.join("/")
|
|
863
|
+
};
|
|
864
|
+
}
|
|
865
|
+
throw new Error(`No provider specified in model string: ${modelString}`);
|
|
866
|
+
}
|
|
867
|
+
/**
|
|
868
|
+
* Get generation parameters from provider options
|
|
869
|
+
* These are parameters that get passed to generateText/streamText calls
|
|
870
|
+
*/
|
|
871
|
+
static getGenerationParams(providerOptions) {
|
|
872
|
+
if (!providerOptions) {
|
|
873
|
+
return {};
|
|
874
|
+
}
|
|
875
|
+
const excludedKeys = [
|
|
876
|
+
"apiKey",
|
|
877
|
+
"baseURL",
|
|
878
|
+
"baseUrl",
|
|
879
|
+
"maxDuration",
|
|
880
|
+
"headers",
|
|
881
|
+
"gateway",
|
|
882
|
+
"nim",
|
|
883
|
+
"custom"
|
|
884
|
+
];
|
|
885
|
+
const params = {};
|
|
886
|
+
for (const [key, value] of Object.entries(providerOptions)) {
|
|
887
|
+
if (!excludedKeys.includes(key) && value !== void 0) {
|
|
888
|
+
params[key] = value;
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
return params;
|
|
892
|
+
}
|
|
893
|
+
/**
|
|
894
|
+
* Prepare complete generation configuration from model settings
|
|
895
|
+
* Returns model instance and generation parameters ready to spread into generateText/streamText
|
|
896
|
+
* Includes maxDuration if specified in provider options (in seconds, following Vercel standard)
|
|
897
|
+
*/
|
|
898
|
+
static prepareGenerationConfig(modelSettings) {
|
|
899
|
+
const modelString = modelSettings?.model?.trim();
|
|
900
|
+
const model = _ModelFactory.createModel({
|
|
901
|
+
model: modelString,
|
|
902
|
+
providerOptions: modelSettings?.providerOptions
|
|
903
|
+
});
|
|
904
|
+
const generationParams = _ModelFactory.getGenerationParams(modelSettings?.providerOptions);
|
|
905
|
+
const maxDuration = modelSettings?.providerOptions?.maxDuration;
|
|
906
|
+
return {
|
|
907
|
+
model,
|
|
908
|
+
...generationParams,
|
|
909
|
+
...maxDuration !== void 0 && { maxDuration }
|
|
910
|
+
};
|
|
911
|
+
}
|
|
912
|
+
/**
|
|
913
|
+
* Validate model settingsuration
|
|
914
|
+
* Basic validation only - let AI SDK handle parameter-specific validation
|
|
915
|
+
*/
|
|
916
|
+
static validateConfig(config) {
|
|
917
|
+
const errors = [];
|
|
918
|
+
if (!config.model) {
|
|
919
|
+
errors.push("Model name is required");
|
|
920
|
+
}
|
|
921
|
+
if (config.providerOptions) {
|
|
922
|
+
if (config.providerOptions.apiKey) {
|
|
923
|
+
errors.push(
|
|
924
|
+
"API keys should not be stored in provider options. Use environment variables (ANTHROPIC_API_KEY, OPENAI_API_KEY) or credential store instead."
|
|
925
|
+
);
|
|
926
|
+
}
|
|
927
|
+
if (config.providerOptions.maxDuration !== void 0) {
|
|
928
|
+
const maxDuration = config.providerOptions.maxDuration;
|
|
929
|
+
if (typeof maxDuration !== "number" || maxDuration <= 0) {
|
|
930
|
+
errors.push("maxDuration must be a positive number (in seconds)");
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
return errors;
|
|
935
|
+
}
|
|
936
|
+
};
|
|
937
|
+
var logger3 = getLogger("service-token-auth");
|
|
638
938
|
function getJwtSecret() {
|
|
639
939
|
const secret = env.INKEEP_AGENTS_JWT_SIGNING_SECRET;
|
|
640
940
|
const dev_secret = "insecure-dev-secret-change-in-production-min-32-chars";
|
|
@@ -644,7 +944,7 @@ function getJwtSecret() {
|
|
|
644
944
|
"INKEEP_AGENTS_JWT_SIGNING_SECRET environment variable is required in production"
|
|
645
945
|
);
|
|
646
946
|
}
|
|
647
|
-
|
|
947
|
+
logger3.warn(
|
|
648
948
|
{},
|
|
649
949
|
"INKEEP_AGENTS_JWT_SIGNING_SECRET not set, using insecure default. DO NOT USE IN PRODUCTION!"
|
|
650
950
|
);
|
|
@@ -659,7 +959,7 @@ async function generateServiceToken(params) {
|
|
|
659
959
|
tenantId: params.tenantId,
|
|
660
960
|
projectId: params.projectId
|
|
661
961
|
}).setProtectedHeader({ alg: "HS256", typ: "JWT" }).setIssuer("inkeep-agents").setSubject(params.originAgentId).setAudience(params.targetAgentId).setIssuedAt().setExpirationTime("5m").sign(secret);
|
|
662
|
-
|
|
962
|
+
logger3.debug(
|
|
663
963
|
{
|
|
664
964
|
originAgentId: params.originAgentId,
|
|
665
965
|
targetAgentId: params.targetAgentId,
|
|
@@ -669,7 +969,7 @@ async function generateServiceToken(params) {
|
|
|
669
969
|
);
|
|
670
970
|
return token;
|
|
671
971
|
} catch (error) {
|
|
672
|
-
|
|
972
|
+
logger3.error({ error }, "Failed to generate service token");
|
|
673
973
|
throw new Error("Failed to generate service token");
|
|
674
974
|
}
|
|
675
975
|
}
|
|
@@ -681,7 +981,7 @@ async function verifyServiceToken(token) {
|
|
|
681
981
|
algorithms: ["HS256"]
|
|
682
982
|
});
|
|
683
983
|
if (typeof payload.sub !== "string" || typeof payload.aud !== "string" || typeof payload.tenantId !== "string" || typeof payload.projectId !== "string") {
|
|
684
|
-
|
|
984
|
+
logger3.warn({ payload }, "Invalid service token: missing required claims");
|
|
685
985
|
return {
|
|
686
986
|
valid: false,
|
|
687
987
|
error: "Invalid token: missing required claims"
|
|
@@ -696,7 +996,7 @@ async function verifyServiceToken(token) {
|
|
|
696
996
|
iat: payload.iat,
|
|
697
997
|
exp: payload.exp
|
|
698
998
|
};
|
|
699
|
-
|
|
999
|
+
logger3.debug(
|
|
700
1000
|
{
|
|
701
1001
|
originAgentId: validPayload.sub,
|
|
702
1002
|
targetAgentId: validPayload.aud,
|
|
@@ -710,13 +1010,13 @@ async function verifyServiceToken(token) {
|
|
|
710
1010
|
};
|
|
711
1011
|
} catch (error) {
|
|
712
1012
|
if (error instanceof Error) {
|
|
713
|
-
|
|
1013
|
+
logger3.warn({ error: error.message }, "Team agent token verification failed");
|
|
714
1014
|
return {
|
|
715
1015
|
valid: false,
|
|
716
1016
|
error: error.message
|
|
717
1017
|
};
|
|
718
1018
|
}
|
|
719
|
-
|
|
1019
|
+
logger3.warn({ error }, "Team agent token verification failed with unknown error");
|
|
720
1020
|
return {
|
|
721
1021
|
valid: false,
|
|
722
1022
|
error: "Token verification failed"
|
|
@@ -725,7 +1025,7 @@ async function verifyServiceToken(token) {
|
|
|
725
1025
|
}
|
|
726
1026
|
function validateTenantId(payload, expectedTenantId) {
|
|
727
1027
|
if (payload.tenantId !== expectedTenantId) {
|
|
728
|
-
|
|
1028
|
+
logger3.warn(
|
|
729
1029
|
{
|
|
730
1030
|
tokenTenantId: payload.tenantId,
|
|
731
1031
|
expectedTenantId,
|
|
@@ -740,7 +1040,7 @@ function validateTenantId(payload, expectedTenantId) {
|
|
|
740
1040
|
}
|
|
741
1041
|
function validateTargetAgent(payload, expectedTargetAgentId) {
|
|
742
1042
|
if (payload.aud !== expectedTargetAgentId) {
|
|
743
|
-
|
|
1043
|
+
logger3.warn(
|
|
744
1044
|
{
|
|
745
1045
|
tokenTargetAgentId: payload.aud,
|
|
746
1046
|
expectedTargetAgentId,
|
|
@@ -774,7 +1074,24 @@ async function verifyAuthorizationHeader(authHeader) {
|
|
|
774
1074
|
}
|
|
775
1075
|
return verifyServiceToken(token);
|
|
776
1076
|
}
|
|
777
|
-
|
|
1077
|
+
async function signTempToken(privateKeyPem, payload, userId) {
|
|
1078
|
+
const privateKey = await jose.importPKCS8(privateKeyPem, "RS256");
|
|
1079
|
+
const jwt = await new jose.SignJWT(payload).setProtectedHeader({ alg: "RS256", typ: "JWT" }).setIssuedAt().setExpirationTime("1h").setIssuer("inkeep-manage-api").setAudience("inkeep-run-api").setSubject(userId).setJti(generateId()).sign(privateKey);
|
|
1080
|
+
const expiresAt = new Date(Date.now() + 60 * 60 * 1e3).toISOString();
|
|
1081
|
+
return { token: jwt, expiresAt };
|
|
1082
|
+
}
|
|
1083
|
+
async function verifyTempToken(publicKeyPem, token) {
|
|
1084
|
+
const publicKey = await jose.importSPKI(publicKeyPem, "RS256");
|
|
1085
|
+
const { payload } = await jose.jwtVerify(token, publicKey, {
|
|
1086
|
+
issuer: "inkeep-manage-api",
|
|
1087
|
+
audience: "inkeep-run-api"
|
|
1088
|
+
});
|
|
1089
|
+
if (payload.type !== "temporary") {
|
|
1090
|
+
throw new Error("Invalid token type");
|
|
1091
|
+
}
|
|
1092
|
+
return payload;
|
|
1093
|
+
}
|
|
1094
|
+
var logger4 = getLogger("composio-client");
|
|
778
1095
|
var TOOLKIT_TO_CATEGORY = {
|
|
779
1096
|
github: "development",
|
|
780
1097
|
gitlab: "development",
|
|
@@ -848,21 +1165,21 @@ function addUserIdToUrl(url, userId) {
|
|
|
848
1165
|
async function deleteComposioConnectedAccount(accountId) {
|
|
849
1166
|
const composioInstance = getComposioInstance();
|
|
850
1167
|
if (!composioInstance) {
|
|
851
|
-
|
|
1168
|
+
logger4.info({}, "Composio not configured, skipping account deletion");
|
|
852
1169
|
return false;
|
|
853
1170
|
}
|
|
854
1171
|
try {
|
|
855
1172
|
await composioInstance.connectedAccounts.delete(accountId);
|
|
856
1173
|
return true;
|
|
857
1174
|
} catch (error) {
|
|
858
|
-
|
|
1175
|
+
logger4.warn({ error }, "Error deleting Composio connected account");
|
|
859
1176
|
return false;
|
|
860
1177
|
}
|
|
861
1178
|
}
|
|
862
1179
|
async function fetchComposioConnectedAccounts(derivedUserId) {
|
|
863
1180
|
const composioInstance = getComposioInstance();
|
|
864
1181
|
if (!composioInstance) {
|
|
865
|
-
|
|
1182
|
+
logger4.info({}, "Composio not configured, skipping connected accounts fetch");
|
|
866
1183
|
return null;
|
|
867
1184
|
}
|
|
868
1185
|
try {
|
|
@@ -871,25 +1188,25 @@ async function fetchComposioConnectedAccounts(derivedUserId) {
|
|
|
871
1188
|
});
|
|
872
1189
|
return connectedAccounts;
|
|
873
1190
|
} catch (error) {
|
|
874
|
-
|
|
1191
|
+
logger4.error({ error }, "Error fetching Composio connected accounts");
|
|
875
1192
|
return null;
|
|
876
1193
|
}
|
|
877
1194
|
}
|
|
878
1195
|
async function isComposioMCPServerAuthenticated(tenantId, projectId, mcpServerUrl) {
|
|
879
1196
|
const composioApiKey = process.env.COMPOSIO_API_KEY;
|
|
880
1197
|
if (!composioApiKey) {
|
|
881
|
-
|
|
1198
|
+
logger4.info({}, "Composio API key not configured, skipping auth check");
|
|
882
1199
|
return false;
|
|
883
1200
|
}
|
|
884
1201
|
const serverId = extractComposioServerId(mcpServerUrl);
|
|
885
1202
|
if (!serverId) {
|
|
886
|
-
|
|
1203
|
+
logger4.info({ mcpServerUrl }, "Could not extract Composio server ID from URL");
|
|
887
1204
|
return false;
|
|
888
1205
|
}
|
|
889
1206
|
const derivedUserId = deriveComposioUserId(tenantId, projectId);
|
|
890
1207
|
const composioInstance = getComposioInstance();
|
|
891
1208
|
if (!composioInstance) {
|
|
892
|
-
|
|
1209
|
+
logger4.info({}, "Composio not configured, skipping auth check");
|
|
893
1210
|
return false;
|
|
894
1211
|
}
|
|
895
1212
|
try {
|
|
@@ -907,7 +1224,7 @@ async function isComposioMCPServerAuthenticated(tenantId, projectId, mcpServerUr
|
|
|
907
1224
|
);
|
|
908
1225
|
return !!activeAccount;
|
|
909
1226
|
} catch (error) {
|
|
910
|
-
|
|
1227
|
+
logger4.error({ error, mcpServerUrl }, "Error checking Composio authentication status");
|
|
911
1228
|
return false;
|
|
912
1229
|
}
|
|
913
1230
|
}
|
|
@@ -931,7 +1248,7 @@ function transformComposioServerData(composioMcpServer, isAuthenticated, url, th
|
|
|
931
1248
|
async function ensureComposioAccount(composioMcpServer, derivedUserId, initiatedAccounts) {
|
|
932
1249
|
const firstAuthConfigId = composioMcpServer.authConfigIds[0];
|
|
933
1250
|
if (!firstAuthConfigId) {
|
|
934
|
-
|
|
1251
|
+
logger4.error({ serverId: composioMcpServer.id }, "No auth config ID found for MCP server");
|
|
935
1252
|
return null;
|
|
936
1253
|
}
|
|
937
1254
|
const existingInitiatedAccount = initiatedAccounts.find(
|
|
@@ -943,7 +1260,7 @@ async function ensureComposioAccount(composioMcpServer, derivedUserId, initiated
|
|
|
943
1260
|
try {
|
|
944
1261
|
const composioInstance = getComposioInstance();
|
|
945
1262
|
if (!composioInstance) {
|
|
946
|
-
|
|
1263
|
+
logger4.error({ serverId: composioMcpServer.id }, "Composio not configured");
|
|
947
1264
|
return null;
|
|
948
1265
|
}
|
|
949
1266
|
const createAccountResponse = await composioInstance.connectedAccounts.link(
|
|
@@ -952,7 +1269,7 @@ async function ensureComposioAccount(composioMcpServer, derivedUserId, initiated
|
|
|
952
1269
|
);
|
|
953
1270
|
return createAccountResponse.redirectUrl ?? null;
|
|
954
1271
|
} catch (error) {
|
|
955
|
-
|
|
1272
|
+
logger4.error(
|
|
956
1273
|
{ serverId: composioMcpServer.id, error },
|
|
957
1274
|
"Error creating connected account for MCP server"
|
|
958
1275
|
);
|
|
@@ -989,13 +1306,13 @@ async function transformComposioServer(composioMcpServer, authenticatedAuthConfi
|
|
|
989
1306
|
async function fetchComposioServers(tenantId, projectId) {
|
|
990
1307
|
const composioApiKey = process.env.COMPOSIO_API_KEY;
|
|
991
1308
|
if (!composioApiKey) {
|
|
992
|
-
|
|
1309
|
+
logger4.info({}, "COMPOSIO_API_KEY not configured, skipping Composio servers");
|
|
993
1310
|
return [];
|
|
994
1311
|
}
|
|
995
1312
|
const derivedUserId = deriveComposioUserId(tenantId, projectId);
|
|
996
1313
|
const composioInstance = getComposioInstance();
|
|
997
1314
|
if (!composioInstance) {
|
|
998
|
-
|
|
1315
|
+
logger4.info({}, "Composio not configured, returning empty list");
|
|
999
1316
|
return [];
|
|
1000
1317
|
}
|
|
1001
1318
|
try {
|
|
@@ -1032,26 +1349,26 @@ async function fetchComposioServers(tenantId, projectId) {
|
|
|
1032
1349
|
);
|
|
1033
1350
|
return validServers;
|
|
1034
1351
|
} catch (error) {
|
|
1035
|
-
|
|
1352
|
+
logger4.error({ error }, "Failed to fetch Composio servers");
|
|
1036
1353
|
return [];
|
|
1037
1354
|
}
|
|
1038
1355
|
}
|
|
1039
1356
|
async function fetchSingleComposioServer(tenantId, projectId, mcpServerUrl) {
|
|
1040
1357
|
const composioApiKey = process.env.COMPOSIO_API_KEY;
|
|
1041
1358
|
if (!composioApiKey) {
|
|
1042
|
-
|
|
1359
|
+
logger4.debug({}, "COMPOSIO_API_KEY not configured");
|
|
1043
1360
|
return null;
|
|
1044
1361
|
}
|
|
1045
1362
|
const derivedUserId = deriveComposioUserId(tenantId, projectId);
|
|
1046
1363
|
const composioInstance = getComposioInstance();
|
|
1047
1364
|
if (!composioInstance) {
|
|
1048
|
-
|
|
1365
|
+
logger4.info({}, "Composio not configured, returning null");
|
|
1049
1366
|
return null;
|
|
1050
1367
|
}
|
|
1051
1368
|
try {
|
|
1052
1369
|
const serverId = extractComposioServerId(mcpServerUrl);
|
|
1053
1370
|
if (!serverId) {
|
|
1054
|
-
|
|
1371
|
+
logger4.error({ mcpServerUrl }, "Could not extract Composio server ID from URL");
|
|
1055
1372
|
return null;
|
|
1056
1373
|
}
|
|
1057
1374
|
const composioMcpServer = await composioInstance.mcp.get(serverId);
|
|
@@ -1075,23 +1392,23 @@ async function fetchSingleComposioServer(tenantId, projectId, mcpServerUrl) {
|
|
|
1075
1392
|
);
|
|
1076
1393
|
return transformedServer;
|
|
1077
1394
|
} catch (error) {
|
|
1078
|
-
|
|
1395
|
+
logger4.error({ error, mcpServerUrl }, "Failed to fetch single Composio server");
|
|
1079
1396
|
return null;
|
|
1080
1397
|
}
|
|
1081
1398
|
}
|
|
1082
1399
|
|
|
1083
1400
|
// src/utils/third-party-mcp-servers/third-party-check.ts
|
|
1084
|
-
var
|
|
1401
|
+
var logger5 = getLogger("third-party-check");
|
|
1085
1402
|
async function isThirdPartyMCPServerAuthenticated(tenantId, projectId, mcpServerUrl) {
|
|
1086
1403
|
const composioServerId = extractComposioServerId(mcpServerUrl);
|
|
1087
1404
|
if (composioServerId) {
|
|
1088
|
-
|
|
1405
|
+
logger5.debug({ mcpServerUrl }, "Detected Composio MCP server, checking auth status");
|
|
1089
1406
|
return isComposioMCPServerAuthenticated(tenantId, projectId, mcpServerUrl);
|
|
1090
1407
|
}
|
|
1091
|
-
|
|
1408
|
+
logger5.info({ mcpServerUrl }, "Unknown third-party MCP server provider");
|
|
1092
1409
|
return false;
|
|
1093
1410
|
}
|
|
1094
|
-
var
|
|
1411
|
+
var logger6 = getLogger("tracer");
|
|
1095
1412
|
var createNoOpSpan = () => ({
|
|
1096
1413
|
setAttributes: () => ({}),
|
|
1097
1414
|
recordException: () => ({}),
|
|
@@ -1120,23 +1437,23 @@ var noopTracer = {
|
|
|
1120
1437
|
return createNoOpSpan();
|
|
1121
1438
|
}
|
|
1122
1439
|
};
|
|
1123
|
-
function setSpanWithError(span, error,
|
|
1440
|
+
function setSpanWithError(span, error, logger7, logMessage) {
|
|
1124
1441
|
span.recordException(error);
|
|
1125
1442
|
span.setStatus({
|
|
1126
1443
|
code: SpanStatusCode.ERROR,
|
|
1127
1444
|
message: error.message
|
|
1128
1445
|
});
|
|
1129
|
-
if (
|
|
1130
|
-
|
|
1446
|
+
if (logger7 && logMessage) {
|
|
1447
|
+
logger7.error({ error: error.message }, logMessage);
|
|
1131
1448
|
}
|
|
1132
1449
|
}
|
|
1133
1450
|
function getTracer(serviceName, serviceVersion) {
|
|
1134
1451
|
try {
|
|
1135
1452
|
return trace.getTracer(serviceName, serviceVersion);
|
|
1136
1453
|
} catch (_error) {
|
|
1137
|
-
|
|
1454
|
+
logger6.debug({}, "OpenTelemetry tracer not available, using no-op tracer");
|
|
1138
1455
|
return noopTracer;
|
|
1139
1456
|
}
|
|
1140
1457
|
}
|
|
1141
1458
|
|
|
1142
|
-
export { CONVERSATION_HISTORY_DEFAULT_LIMIT, CONVERSATION_HISTORY_MAX_OUTPUT_TOKENS_DEFAULT, ERROR_DOCS_BASE_URL, ErrorCode, MCP_TOOL_CONNECTION_TIMEOUT_MS, MCP_TOOL_INITIAL_RECONNECTION_DELAY_MS, MCP_TOOL_MAX_RECONNECTION_DELAY_MS, MCP_TOOL_MAX_RETRIES, MCP_TOOL_RECONNECTION_DELAY_GROWTH_FACTOR, McpClient, commonCreateErrorResponses, commonDeleteErrorResponses, commonGetErrorResponses, commonUpdateErrorResponses, createApiError, createExecutionContext, errorResponseSchema, errorSchemaFactory, executionLimitsSharedDefaults, extractComposioServerId, extractPublicId, fetchComposioServers, fetchSingleComposioServer, generateApiKey, generateId, generateServiceToken, getConversationId, getCredentialStoreLookupKeyFromRetrievalParams, getRequestExecutionContext, getTracer, handleApiError, hashApiKey, isApiKeyExpired, isComposioMCPServerAuthenticated, isThirdPartyMCPServerAuthenticated, maskApiKey, normalizeDateString, problemDetailsSchema, setSpanWithError, validateApiKey, validateTargetAgent, validateTenantId, verifyAuthorizationHeader, verifyServiceToken };
|
|
1459
|
+
export { CONVERSATION_HISTORY_DEFAULT_LIMIT, CONVERSATION_HISTORY_MAX_OUTPUT_TOKENS_DEFAULT, ERROR_DOCS_BASE_URL, ErrorCode, MCP_TOOL_CONNECTION_TIMEOUT_MS, MCP_TOOL_INITIAL_RECONNECTION_DELAY_MS, MCP_TOOL_MAX_RECONNECTION_DELAY_MS, MCP_TOOL_MAX_RETRIES, MCP_TOOL_RECONNECTION_DELAY_GROWTH_FACTOR, McpClient, ModelFactory, commonCreateErrorResponses, commonDeleteErrorResponses, commonGetErrorResponses, commonUpdateErrorResponses, createApiError, createExecutionContext, errorResponseSchema, errorSchemaFactory, executionLimitsSharedDefaults, extractComposioServerId, extractPublicId, fetchComposioServers, fetchSingleComposioServer, formatMessagesForLLM, formatMessagesForLLMContext, generateApiKey, generateId, generateServiceToken, getConversationId, getCredentialStoreLookupKeyFromRetrievalParams, getRequestExecutionContext, getTracer, handleApiError, hashApiKey, isApiKeyExpired, isComposioMCPServerAuthenticated, isThirdPartyMCPServerAuthenticated, maskApiKey, normalizeDateString, problemDetailsSchema, setSpanWithError, signTempToken, toISODateString, validateApiKey, validateTargetAgent, validateTenantId, verifyAuthorizationHeader, verifyServiceToken, verifyTempToken };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AgentWithinContextOfProjectSchema, resourceIdSchema, MAX_ID_LENGTH } from './chunk-
|
|
1
|
+
import { AgentWithinContextOfProjectSchema, resourceIdSchema, MAX_ID_LENGTH } from './chunk-K6GMXJPW.js';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
|
|
4
4
|
// src/validation/cycleDetection.ts
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NodePgDatabase } from 'drizzle-orm/node-postgres';
|
|
2
2
|
import { PgliteDatabase } from 'drizzle-orm/pglite';
|
|
3
|
-
import { s as schema } from './schema-
|
|
3
|
+
import { s as schema } from './schema-DKbG39on.js';
|
|
4
4
|
|
|
5
5
|
type DatabaseClient = NodePgDatabase<typeof schema> | PgliteDatabase<typeof schema>;
|
|
6
6
|
interface DatabaseConfig {
|