@inkeep/agents-core 0.8.7 → 0.10.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/index.cjs CHANGED
@@ -1638,6 +1638,7 @@ var StatusUpdateSchema = zodOpenapi.z.object({
1638
1638
  statusComponents: zodOpenapi.z.array(StatusComponentSchema).optional()
1639
1639
  });
1640
1640
  var CanUseItemSchema = zodOpenapi.z.object({
1641
+ agentToolRelationId: zodOpenapi.z.string().optional(),
1641
1642
  toolId: zodOpenapi.z.string(),
1642
1643
  toolSelection: zodOpenapi.z.array(zodOpenapi.z.string()).nullish(),
1643
1644
  headers: zodOpenapi.z.record(zodOpenapi.z.string(), zodOpenapi.z.string()).nullish()
@@ -3696,7 +3697,8 @@ var getFullGraphDefinition = (db) => async ({
3696
3697
  projectId: tools.projectId,
3697
3698
  imageUrl: tools.imageUrl,
3698
3699
  selectedTools: agentToolRelations.selectedTools,
3699
- headers: agentToolRelations.headers
3700
+ headers: agentToolRelations.headers,
3701
+ agentToolRelationId: agentToolRelations.id
3700
3702
  }).from(agentToolRelations).innerJoin(
3701
3703
  tools,
3702
3704
  drizzleOrm.and(
@@ -3729,6 +3731,7 @@ var getFullGraphDefinition = (db) => async ({
3729
3731
  (rel) => rel.artifactComponentId
3730
3732
  );
3731
3733
  const canUse = agentTools.map((tool2) => ({
3734
+ agentToolRelationId: tool2.agentToolRelationId,
3732
3735
  toolId: tool2.id,
3733
3736
  toolSelection: tool2.selectedTools || null,
3734
3737
  headers: tool2.headers || null
@@ -6060,28 +6063,19 @@ var removeToolFromAgent = (db) => async (params) => {
6060
6063
  return deleted;
6061
6064
  };
6062
6065
  var upsertAgentToolRelation = (db) => async (params) => {
6063
- const existing = await db.query.agentToolRelations.findFirst({
6064
- where: drizzleOrm.and(
6065
- drizzleOrm.eq(agentToolRelations.tenantId, params.scopes.tenantId),
6066
- drizzleOrm.eq(agentToolRelations.projectId, params.scopes.projectId),
6067
- drizzleOrm.eq(agentToolRelations.graphId, params.scopes.graphId),
6068
- drizzleOrm.eq(agentToolRelations.agentId, params.agentId),
6069
- drizzleOrm.eq(agentToolRelations.toolId, params.toolId)
6070
- )
6071
- });
6072
- if (!existing) {
6073
- return await addToolToAgent(db)(params);
6066
+ if (params.relationId) {
6067
+ return await updateAgentToolRelation(db)({
6068
+ scopes: params.scopes,
6069
+ relationId: params.relationId,
6070
+ data: {
6071
+ agentId: params.agentId,
6072
+ toolId: params.toolId,
6073
+ selectedTools: params.selectedTools,
6074
+ headers: params.headers
6075
+ }
6076
+ });
6074
6077
  }
6075
- return await updateAgentToolRelation(db)({
6076
- scopes: params.scopes,
6077
- relationId: existing.id,
6078
- data: {
6079
- agentId: params.agentId,
6080
- toolId: params.toolId,
6081
- selectedTools: params.selectedTools,
6082
- headers: params.headers
6083
- }
6084
- });
6078
+ return await addToolToAgent(db)(params);
6085
6079
  };
6086
6080
  var upsertTool = (db) => async (params) => {
6087
6081
  const scopes = { tenantId: params.data.tenantId, projectId: params.data.projectId };
@@ -6340,14 +6334,15 @@ var createFullGraphServerSide = (db, logger12 = defaultLogger) => async (scopes,
6340
6334
  agentToolPromises.push(
6341
6335
  (async () => {
6342
6336
  try {
6343
- const { toolId, toolSelection, headers } = canUseItem;
6337
+ const { toolId, toolSelection, headers, agentToolRelationId } = canUseItem;
6344
6338
  logger12.info({ agentId, toolId }, "Processing agent-tool relation");
6345
6339
  await upsertAgentToolRelation(db)({
6346
6340
  scopes: { tenantId, projectId, graphId: finalGraphId },
6347
6341
  agentId,
6348
6342
  toolId,
6349
6343
  selectedTools: toolSelection || void 0,
6350
- headers: headers || void 0
6344
+ headers: headers || void 0,
6345
+ relationId: agentToolRelationId
6351
6346
  });
6352
6347
  logger12.info({ agentId, toolId }, "Agent-tool relation processed successfully");
6353
6348
  } catch (error) {
@@ -6711,6 +6706,53 @@ var updateFullGraphServerSide = (db, logger12 = defaultLogger) => async (scopes,
6711
6706
  ([_, agentData]) => isExternalAgent(agentData)
6712
6707
  ).length;
6713
6708
  logger12.info({ externalAgentCount }, "All external agents created/updated successfully");
6709
+ const incomingAgentIds = new Set(Object.keys(typedGraphDefinition.agents));
6710
+ const existingInternalAgents = await listAgents(db)({
6711
+ scopes: { tenantId, projectId, graphId: finalGraphId }
6712
+ });
6713
+ const existingExternalAgents = await listExternalAgents(db)({
6714
+ scopes: { tenantId, projectId, graphId: finalGraphId }
6715
+ });
6716
+ let deletedInternalCount = 0;
6717
+ for (const agent of existingInternalAgents) {
6718
+ if (!incomingAgentIds.has(agent.id)) {
6719
+ try {
6720
+ await deleteAgent(db)({
6721
+ scopes: { tenantId, projectId, graphId: finalGraphId },
6722
+ agentId: agent.id
6723
+ });
6724
+ deletedInternalCount++;
6725
+ logger12.info({ agentId: agent.id }, "Deleted orphaned internal agent");
6726
+ } catch (error) {
6727
+ logger12.error({ agentId: agent.id, error }, "Failed to delete orphaned internal agent");
6728
+ }
6729
+ }
6730
+ }
6731
+ let deletedExternalCount = 0;
6732
+ for (const agent of existingExternalAgents) {
6733
+ if (!incomingAgentIds.has(agent.id)) {
6734
+ try {
6735
+ await deleteExternalAgent(db)({
6736
+ scopes: { tenantId, projectId, graphId: finalGraphId },
6737
+ agentId: agent.id
6738
+ });
6739
+ deletedExternalCount++;
6740
+ logger12.info({ agentId: agent.id }, "Deleted orphaned external agent");
6741
+ } catch (error) {
6742
+ logger12.error({ agentId: agent.id, error }, "Failed to delete orphaned external agent");
6743
+ }
6744
+ }
6745
+ }
6746
+ if (deletedInternalCount > 0 || deletedExternalCount > 0) {
6747
+ logger12.info(
6748
+ {
6749
+ deletedInternalCount,
6750
+ deletedExternalCount,
6751
+ totalDeleted: deletedInternalCount + deletedExternalCount
6752
+ },
6753
+ "Deleted orphaned agents from graph"
6754
+ );
6755
+ }
6714
6756
  await updateAgentGraph(db)({
6715
6757
  scopes: { tenantId, projectId, graphId: typedGraphDefinition.id },
6716
6758
  data: {
@@ -6725,10 +6767,47 @@ var updateFullGraphServerSide = (db, logger12 = defaultLogger) => async (scopes,
6725
6767
  }
6726
6768
  });
6727
6769
  logger12.info({ graphId: typedGraphDefinition.id }, "Graph metadata updated");
6770
+ const incomingRelationshipIds = /* @__PURE__ */ new Set();
6771
+ for (const [_agentId, agentData] of Object.entries(typedGraphDefinition.agents)) {
6772
+ if (isInternalAgent(agentData) && agentData.canUse && Array.isArray(agentData.canUse)) {
6773
+ for (const canUseItem of agentData.canUse) {
6774
+ if (canUseItem.agentToolRelationId) {
6775
+ incomingRelationshipIds.add(canUseItem.agentToolRelationId);
6776
+ }
6777
+ }
6778
+ }
6779
+ }
6728
6780
  for (const agentId of Object.keys(typedGraphDefinition.agents)) {
6729
- await deleteAgentToolRelationByAgent(db)({
6730
- scopes: { tenantId, projectId, graphId: finalGraphId, agentId }
6731
- });
6781
+ try {
6782
+ let deletedCount = 0;
6783
+ if (incomingRelationshipIds.size === 0) {
6784
+ const result = await db.delete(agentToolRelations).where(
6785
+ drizzleOrm.and(
6786
+ drizzleOrm.eq(agentToolRelations.tenantId, tenantId),
6787
+ drizzleOrm.eq(agentToolRelations.projectId, projectId),
6788
+ drizzleOrm.eq(agentToolRelations.graphId, finalGraphId),
6789
+ drizzleOrm.eq(agentToolRelations.agentId, agentId)
6790
+ )
6791
+ );
6792
+ deletedCount = result.rowsAffected || 0;
6793
+ } else {
6794
+ const result = await db.delete(agentToolRelations).where(
6795
+ drizzleOrm.and(
6796
+ drizzleOrm.eq(agentToolRelations.tenantId, tenantId),
6797
+ drizzleOrm.eq(agentToolRelations.projectId, projectId),
6798
+ drizzleOrm.eq(agentToolRelations.graphId, finalGraphId),
6799
+ drizzleOrm.eq(agentToolRelations.agentId, agentId),
6800
+ drizzleOrm.not(drizzleOrm.inArray(agentToolRelations.id, Array.from(incomingRelationshipIds)))
6801
+ )
6802
+ );
6803
+ deletedCount = result.rowsAffected || 0;
6804
+ }
6805
+ if (deletedCount > 0) {
6806
+ logger12.info({ agentId, deletedCount }, "Deleted orphaned agent-tool relations");
6807
+ }
6808
+ } catch (error) {
6809
+ logger12.error({ agentId, error }, "Failed to delete orphaned agent-tool relations");
6810
+ }
6732
6811
  }
6733
6812
  const agentToolPromises = [];
6734
6813
  for (const [agentId, agentData] of Object.entries(typedGraphDefinition.agents)) {
@@ -6737,21 +6816,28 @@ var updateFullGraphServerSide = (db, logger12 = defaultLogger) => async (scopes,
6737
6816
  agentToolPromises.push(
6738
6817
  (async () => {
6739
6818
  try {
6740
- const { toolId, toolSelection, headers } = canUseItem;
6741
- await createAgentToolRelation(db)({
6819
+ const { toolId, toolSelection, headers, agentToolRelationId } = canUseItem;
6820
+ await upsertAgentToolRelation(db)({
6742
6821
  scopes: { tenantId, projectId, graphId: finalGraphId },
6743
- data: {
6744
- agentId,
6745
- toolId,
6746
- selectedTools: toolSelection || void 0,
6747
- headers: headers || void 0
6748
- }
6822
+ agentId,
6823
+ toolId,
6824
+ selectedTools: toolSelection || void 0,
6825
+ headers: headers || void 0,
6826
+ relationId: agentToolRelationId
6749
6827
  });
6750
- logger12.info({ agentId, toolId }, "Agent-tool relation created");
6828
+ logger12.info(
6829
+ { agentId, toolId, relationId: agentToolRelationId },
6830
+ "Agent-tool relation upserted"
6831
+ );
6751
6832
  } catch (error) {
6752
6833
  logger12.error(
6753
- { agentId, toolId: canUseItem.toolId, error },
6754
- "Failed to create agent-tool relation"
6834
+ {
6835
+ agentId,
6836
+ toolId: canUseItem.toolId,
6837
+ relationId: canUseItem.agentToolRelationId,
6838
+ error
6839
+ },
6840
+ "Failed to upsert agent-tool relation"
6755
6841
  );
6756
6842
  }
6757
6843
  })()
@@ -8115,6 +8201,36 @@ var updateFullProjectServerSide = (db, logger12 = defaultLogger2) => async (scop
8115
8201
  "All project artifactComponents updated successfully"
8116
8202
  );
8117
8203
  }
8204
+ const incomingGraphIds = new Set(Object.keys(typed.graphs || {}));
8205
+ const existingGraphs = await listAgentGraphs(db)({
8206
+ scopes: { tenantId, projectId: typed.id }
8207
+ });
8208
+ let deletedGraphCount = 0;
8209
+ for (const graph of existingGraphs) {
8210
+ if (!incomingGraphIds.has(graph.id)) {
8211
+ try {
8212
+ await deleteFullGraph(db, logger12)({
8213
+ scopes: { tenantId, projectId: typed.id, graphId: graph.id }
8214
+ });
8215
+ deletedGraphCount++;
8216
+ logger12.info({ graphId: graph.id }, "Deleted orphaned graph from project");
8217
+ } catch (error) {
8218
+ logger12.error(
8219
+ { graphId: graph.id, error },
8220
+ "Failed to delete orphaned graph from project"
8221
+ );
8222
+ }
8223
+ }
8224
+ }
8225
+ if (deletedGraphCount > 0) {
8226
+ logger12.info(
8227
+ {
8228
+ deletedGraphCount,
8229
+ projectId: typed.id
8230
+ },
8231
+ "Deleted orphaned graphs from project"
8232
+ );
8233
+ }
8118
8234
  if (typed.graphs && Object.keys(typed.graphs).length > 0) {
8119
8235
  logger12.info(
8120
8236
  {
@@ -8930,7 +9046,42 @@ var ContextResolver = class {
8930
9046
  * Resolve a single context variable
8931
9047
  */
8932
9048
  async resolveSingleFetchDefinition(contextConfig2, definition, templateKey, options, requestHash, result) {
8933
- return tracer.startActiveSpan(
9049
+ const cachedEntry = await this.cache.get({
9050
+ conversationId: options.conversationId,
9051
+ contextConfigId: contextConfig2.id,
9052
+ contextVariableKey: templateKey,
9053
+ requestHash
9054
+ });
9055
+ if (cachedEntry) {
9056
+ result.resolvedContext[templateKey] = cachedEntry.value;
9057
+ result.cacheHits.push(definition.id);
9058
+ logger7.debug(
9059
+ {
9060
+ definitionId: definition.id,
9061
+ templateKey,
9062
+ conversationId: options.conversationId
9063
+ },
9064
+ "Cache hit for context variable"
9065
+ );
9066
+ return;
9067
+ }
9068
+ result.cacheMisses.push(definition.id);
9069
+ logger7.debug(
9070
+ {
9071
+ definitionId: definition.id,
9072
+ templateKey,
9073
+ conversationId: options.conversationId
9074
+ },
9075
+ "Cache miss for context variable, fetching data"
9076
+ );
9077
+ const definitionWithConversationId = {
9078
+ ...definition,
9079
+ fetchConfig: {
9080
+ ...definition.fetchConfig,
9081
+ conversationId: options.conversationId
9082
+ }
9083
+ };
9084
+ const fetchedData = await tracer.startActiveSpan(
8934
9085
  "context-resolver.resolve_single_fetch_definition",
8935
9086
  {
8936
9087
  attributes: {
@@ -8943,78 +9094,17 @@ var ContextResolver = class {
8943
9094
  },
8944
9095
  async (parentSpan) => {
8945
9096
  try {
8946
- const cachedEntry = await this.cache.get({
8947
- conversationId: options.conversationId,
8948
- contextConfigId: contextConfig2.id,
8949
- contextVariableKey: templateKey,
8950
- requestHash
8951
- });
8952
- if (cachedEntry) {
8953
- result.resolvedContext[templateKey] = cachedEntry.value;
8954
- result.cacheHits.push(definition.id);
8955
- parentSpan.setStatus({ code: api.SpanStatusCode.OK });
8956
- parentSpan.addEvent("context.cache_hit", {
8957
- definition_id: definition.id,
8958
- template_key: templateKey
8959
- });
8960
- logger7.debug(
8961
- {
8962
- definitionId: definition.id,
8963
- templateKey,
8964
- conversationId: options.conversationId
8965
- },
8966
- "Cache hit for context variable"
8967
- );
8968
- return;
8969
- }
8970
- result.cacheMisses.push(definition.id);
8971
- parentSpan.addEvent("context.cache_miss", {
8972
- definition_id: definition.id,
8973
- template_key: templateKey
8974
- });
8975
- logger7.debug(
8976
- {
8977
- definitionId: definition.id,
8978
- templateKey,
8979
- conversationId: options.conversationId
8980
- },
8981
- "Cache miss for context variable, fetching data"
8982
- );
8983
- const definitionWithConversationId = {
8984
- ...definition,
8985
- fetchConfig: {
8986
- ...definition.fetchConfig,
8987
- conversationId: options.conversationId
8988
- }
8989
- };
8990
- const fetchedData = await this.fetcher.fetch(
9097
+ const data = await this.fetcher.fetch(
8991
9098
  definitionWithConversationId,
8992
9099
  result.resolvedContext
8993
9100
  );
8994
- result.resolvedContext[templateKey] = fetchedData;
8995
- result.fetchedDefinitions.push(definition.id);
8996
- await this.cache.set({
8997
- contextConfigId: contextConfig2.id,
8998
- contextVariableKey: templateKey,
8999
- conversationId: options.conversationId,
9000
- value: fetchedData,
9001
- requestHash,
9002
- tenantId: this.tenantId
9003
- });
9004
9101
  parentSpan.setStatus({ code: api.SpanStatusCode.OK });
9005
9102
  parentSpan.addEvent("context.fetch_success", {
9006
9103
  definition_id: definition.id,
9007
9104
  template_key: templateKey,
9008
9105
  source: definition.fetchConfig.url
9009
9106
  });
9010
- logger7.debug(
9011
- {
9012
- definitionId: definition.id,
9013
- templateKey,
9014
- conversationId: options.conversationId
9015
- },
9016
- "Context variable resolved and cached"
9017
- );
9107
+ return data;
9018
9108
  } catch (error) {
9019
9109
  setSpanWithError(parentSpan, error);
9020
9110
  throw error;
@@ -9023,6 +9113,24 @@ var ContextResolver = class {
9023
9113
  }
9024
9114
  }
9025
9115
  );
9116
+ result.resolvedContext[templateKey] = fetchedData;
9117
+ result.fetchedDefinitions.push(definition.id);
9118
+ await this.cache.set({
9119
+ contextConfigId: contextConfig2.id,
9120
+ contextVariableKey: templateKey,
9121
+ conversationId: options.conversationId,
9122
+ value: fetchedData,
9123
+ requestHash,
9124
+ tenantId: this.tenantId
9125
+ });
9126
+ logger7.debug(
9127
+ {
9128
+ definitionId: definition.id,
9129
+ templateKey,
9130
+ conversationId: options.conversationId
9131
+ },
9132
+ "Context variable resolved and cached"
9133
+ );
9026
9134
  }
9027
9135
  /**
9028
9136
  * Resolve the request context for a given conversation
@@ -10290,14 +10398,31 @@ var NangoCredentialStore = class {
10290
10398
  if (!isSupportedAuthMode(type)) {
10291
10399
  return null;
10292
10400
  }
10401
+ const extractAccessTokenForBearerType = (tokenString) => {
10402
+ if (tokenString && typeof tokenString === "string") {
10403
+ try {
10404
+ const parsedToken = JSON.parse(tokenString);
10405
+ if (parsedToken.access_token && typeof parsedToken.access_token === "string") {
10406
+ return parsedToken.access_token;
10407
+ }
10408
+ } catch {
10409
+ }
10410
+ return tokenString;
10411
+ }
10412
+ return void 0;
10413
+ };
10293
10414
  switch (type) {
10294
10415
  case "API_KEY":
10295
10416
  return {
10296
- token: credentials.apiKey || credentials.api_key
10417
+ token: extractAccessTokenForBearerType(
10418
+ credentials.apiKey || credentials.api_key
10419
+ )
10297
10420
  };
10298
10421
  case "APP":
10299
10422
  return {
10300
- token: credentials.accessToken || credentials.access_token
10423
+ token: extractAccessTokenForBearerType(
10424
+ credentials.accessToken || credentials.access_token
10425
+ )
10301
10426
  };
10302
10427
  case "BASIC":
10303
10428
  return {
@@ -10308,7 +10433,7 @@ var NangoCredentialStore = class {
10308
10433
  return credentials.raw;
10309
10434
  case "JWT":
10310
10435
  return {
10311
- token: credentials.token
10436
+ token: extractAccessTokenForBearerType(credentials.token)
10312
10437
  };
10313
10438
  case "OAUTH1":
10314
10439
  return {
@@ -10317,12 +10442,12 @@ var NangoCredentialStore = class {
10317
10442
  };
10318
10443
  case "OAUTH2":
10319
10444
  return {
10320
- token: credentials.access_token,
10445
+ token: extractAccessTokenForBearerType(credentials.access_token),
10321
10446
  refresh_token: credentials.refresh_token
10322
10447
  };
10323
10448
  case "OAUTH2_CC":
10324
10449
  return {
10325
- token: credentials.token,
10450
+ token: extractAccessTokenForBearerType(credentials.token),
10326
10451
  client_certificate: credentials.client_certificate,
10327
10452
  client_id: credentials.client_id,
10328
10453
  client_private_key: credentials.client_private_key,
@@ -10348,6 +10473,104 @@ var NangoCredentialStore = class {
10348
10473
  }
10349
10474
  return result;
10350
10475
  }
10476
+ /**
10477
+ * Fetch a specific Nango integration
10478
+ */
10479
+ async fetchNangoIntegration(uniqueKey) {
10480
+ try {
10481
+ const response = await this.nangoClient.getIntegration(
10482
+ { uniqueKey },
10483
+ { include: ["credentials"] }
10484
+ );
10485
+ const integration = response.data;
10486
+ let areCredentialsSet = false;
10487
+ if (integration.credentials?.type === "OAUTH2" || integration.credentials?.type === "OAUTH1" || integration.credentials?.type === "TBA") {
10488
+ areCredentialsSet = !!(integration.credentials?.client_id && integration.credentials?.client_secret);
10489
+ } else if (integration.credentials?.type === "APP") {
10490
+ areCredentialsSet = !!(integration.credentials?.app_id && integration.credentials?.app_link);
10491
+ } else {
10492
+ areCredentialsSet = true;
10493
+ }
10494
+ const { credentials: _credentials, ...integrationWithoutCredentials } = integration;
10495
+ return {
10496
+ ...integrationWithoutCredentials,
10497
+ areCredentialsSet
10498
+ };
10499
+ } catch (error) {
10500
+ if (error && typeof error === "object" && "status" in error && error.status === 404) {
10501
+ return null;
10502
+ }
10503
+ console.error(`Failed to fetch integration ${uniqueKey}:`, error);
10504
+ return null;
10505
+ }
10506
+ }
10507
+ /**
10508
+ * Create an API key credential by setting up Nango integration and importing the connection
10509
+ */
10510
+ async createNangoApiKeyConnection({
10511
+ name,
10512
+ apiKeyToSet,
10513
+ metadata
10514
+ }) {
10515
+ const provider = "private-api-bearer";
10516
+ try {
10517
+ let integration;
10518
+ try {
10519
+ const response2 = await this.nangoClient.createIntegration({
10520
+ provider,
10521
+ unique_key: name,
10522
+ display_name: name
10523
+ });
10524
+ integration = response2.data;
10525
+ } catch (error) {
10526
+ const existingIntegration = await this.fetchNangoIntegration(name);
10527
+ if (existingIntegration) {
10528
+ integration = existingIntegration;
10529
+ } else {
10530
+ console.log(`Integration creation failed for unexpected reasons`, error);
10531
+ }
10532
+ }
10533
+ if (!integration) {
10534
+ throw new Error(`Integration '${name}' not found`);
10535
+ }
10536
+ const importConnectionUrl = `${process.env.NANGO_SERVER_URL || "https://api.nango.dev"}/connections`;
10537
+ const credentials = {
10538
+ type: "API_KEY",
10539
+ apiKey: apiKeyToSet
10540
+ };
10541
+ const body = {
10542
+ provider_config_key: integration.unique_key,
10543
+ connection_id: name,
10544
+ metadata,
10545
+ credentials
10546
+ };
10547
+ const response = await fetch(importConnectionUrl, {
10548
+ method: "POST",
10549
+ headers: {
10550
+ Authorization: `Bearer ${process.env.NANGO_SECRET_KEY}`,
10551
+ "Content-Type": "application/json"
10552
+ },
10553
+ body: JSON.stringify(body)
10554
+ });
10555
+ if (!response.ok) {
10556
+ throw new Error(
10557
+ `Failed to import connection: HTTP ${response.status} - ${response.statusText}`
10558
+ );
10559
+ }
10560
+ } catch (error) {
10561
+ console.error("Unexpected error creating API key credential:", error);
10562
+ logger11.error(
10563
+ {
10564
+ error: error instanceof Error ? error.message : "Unknown error",
10565
+ name
10566
+ },
10567
+ `Unexpected error creating API key credential '${name}'`
10568
+ );
10569
+ throw new Error(
10570
+ `Failed to create API key credential '${name}': ${error instanceof Error ? error.message : "Unknown error"}`
10571
+ );
10572
+ }
10573
+ }
10351
10574
  /**
10352
10575
  * Fetch credentials from Nango API using connection information
10353
10576
  * @param connectionId - The connection ID for the Nango connection
@@ -10437,8 +10660,12 @@ var NangoCredentialStore = class {
10437
10660
  /**
10438
10661
  * Set credentials - not supported for Nango (OAuth flow handles this)
10439
10662
  */
10440
- async set(_key, _value) {
10441
- throw new Error("Setting credentials not supported for Nango store - use OAuth flow instead");
10663
+ async set(key, value) {
10664
+ await this.createNangoApiKeyConnection({
10665
+ name: key,
10666
+ apiKeyToSet: value,
10667
+ metadata: {}
10668
+ });
10442
10669
  }
10443
10670
  /**
10444
10671
  * Check if credentials exist by attempting to fetch them
@@ -10532,7 +10759,16 @@ function createDefaultCredentialStores() {
10532
10759
  })
10533
10760
  );
10534
10761
  }
10535
- stores.push(createKeyChainStore("keychain-default"));
10762
+ if (process.env.ENABLE_KEYCHAIN_STORE === "true") {
10763
+ try {
10764
+ stores.push(createKeyChainStore("keychain-default"));
10765
+ } catch (error) {
10766
+ console.warn(
10767
+ "Failed to create keychain store:",
10768
+ error instanceof Error ? error.message : error
10769
+ );
10770
+ }
10771
+ }
10536
10772
  return stores;
10537
10773
  }
10538
10774
  var loadEnvironmentFiles = () => {
@@ -10852,7 +11088,6 @@ exports.createExternalAgentRelation = createExternalAgentRelation;
10852
11088
  exports.createFullGraphServerSide = createFullGraphServerSide;
10853
11089
  exports.createFullProjectServerSide = createFullProjectServerSide;
10854
11090
  exports.createInMemoryDatabaseClient = createInMemoryDatabaseClient;
10855
- exports.createKeyChainStore = createKeyChainStore;
10856
11091
  exports.createMessage = createMessage;
10857
11092
  exports.createNangoCredentialStore = createNangoCredentialStore;
10858
11093
  exports.createOrGetConversation = createOrGetConversation;