@inkeep/agents-core 0.8.7 → 0.9.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.
@@ -452,6 +452,7 @@ var StatusUpdateSchema = z.object({
452
452
  statusComponents: z.array(StatusComponentSchema).optional()
453
453
  });
454
454
  var CanUseItemSchema = z.object({
455
+ agentToolRelationId: z.string().optional(),
455
456
  toolId: z.string(),
456
457
  toolSelection: z.array(z.string()).nullish(),
457
458
  headers: z.record(z.string(), z.string()).nullish()
@@ -1,4 +1,4 @@
1
- import { FullGraphDefinitionSchema, resourceIdSchema, MAX_ID_LENGTH } from './chunk-AX77SEE3.js';
1
+ import { FullGraphDefinitionSchema, resourceIdSchema, MAX_ID_LENGTH } from './chunk-JXAL2ALG.js';
2
2
 
3
3
  // src/validation/graphFull.ts
4
4
  function isInternalAgent(agent) {
@@ -1388,6 +1388,7 @@ var StatusUpdateSchema = zodOpenapi.z.object({
1388
1388
  statusComponents: zodOpenapi.z.array(StatusComponentSchema).optional()
1389
1389
  });
1390
1390
  var CanUseItemSchema = zodOpenapi.z.object({
1391
+ agentToolRelationId: zodOpenapi.z.string().optional(),
1391
1392
  toolId: zodOpenapi.z.string(),
1392
1393
  toolSelection: zodOpenapi.z.array(zodOpenapi.z.string()).nullish(),
1393
1394
  headers: zodOpenapi.z.record(zodOpenapi.z.string(), zodOpenapi.z.string()).nullish()
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
- import { C as ConversationHistoryConfig, A as ApiKeyApiUpdateSchema, F as FullGraphAgentInsertSchema } from './utility-DP6lt8z3.cjs';
3
- export { d as AgentStopWhen, a as AgentStopWhenSchema, e as CredentialStoreType, c as GraphStopWhen, G as GraphStopWhenSchema, M as MCPTransportType, b as StopWhen, S as StopWhenSchema } from './utility-DP6lt8z3.cjs';
2
+ import { C as ConversationHistoryConfig, A as ApiKeyApiUpdateSchema, F as FullGraphAgentInsertSchema } from './utility-8RXSemmL.cjs';
3
+ export { d as AgentStopWhen, a as AgentStopWhenSchema, e as CredentialStoreType, c as GraphStopWhen, G as GraphStopWhenSchema, M as MCPTransportType, b as StopWhen, S as StopWhenSchema } from './utility-8RXSemmL.cjs';
4
4
  import 'drizzle-zod';
5
5
  import 'drizzle-orm/sqlite-core';
6
6
  import '@hono/zod-openapi';
@@ -67,8 +67,8 @@ declare const AgentApiInsertSchema: z.ZodObject<{
67
67
  canTransferTo: z.ZodOptional<z.ZodArray<z.ZodString>>;
68
68
  canDelegateTo: z.ZodOptional<z.ZodArray<z.ZodString>>;
69
69
  type: z.ZodOptional<z.ZodEnum<{
70
- external: "external";
71
70
  internal: "internal";
71
+ external: "external";
72
72
  }>>;
73
73
  }, z.core.$strip>;
74
74
  declare const ToolApiInsertSchema: z.ZodObject<{
@@ -171,6 +171,10 @@ declare const FullGraphDefinitionSchema: z.ZodObject<{
171
171
  id: z.ZodString;
172
172
  name: z.ZodString;
173
173
  description: z.ZodString;
174
+ prompt: z.ZodString;
175
+ createdAt: z.ZodOptional<z.ZodString>;
176
+ updatedAt: z.ZodOptional<z.ZodString>;
177
+ conversationHistoryConfig: z.ZodOptional<z.ZodNullable<z.ZodType<ConversationHistoryConfig, ConversationHistoryConfig, z.core.$ZodTypeInternals<ConversationHistoryConfig, ConversationHistoryConfig>>>>;
174
178
  models: z.ZodOptional<z.ZodObject<{
175
179
  base: z.ZodOptional<z.ZodObject<{
176
180
  model: z.ZodOptional<z.ZodString>;
@@ -194,12 +198,9 @@ declare const FullGraphDefinitionSchema: z.ZodObject<{
194
198
  }, {
195
199
  stepCountIs?: number | undefined;
196
200
  }>>>>;
197
- createdAt: z.ZodOptional<z.ZodString>;
198
- updatedAt: z.ZodOptional<z.ZodString>;
199
- prompt: z.ZodString;
200
- conversationHistoryConfig: z.ZodOptional<z.ZodNullable<z.ZodType<ConversationHistoryConfig, ConversationHistoryConfig, z.core.$ZodTypeInternals<ConversationHistoryConfig, ConversationHistoryConfig>>>>;
201
201
  type: z.ZodLiteral<"internal">;
202
202
  canUse: z.ZodArray<z.ZodObject<{
203
+ agentToolRelationId: z.ZodOptional<z.ZodString>;
203
204
  toolId: z.ZodString;
204
205
  toolSelection: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString>>>;
205
206
  headers: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodString>>>;
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
- import { C as ConversationHistoryConfig, A as ApiKeyApiUpdateSchema, F as FullGraphAgentInsertSchema } from './utility-DP6lt8z3.js';
3
- export { d as AgentStopWhen, a as AgentStopWhenSchema, e as CredentialStoreType, c as GraphStopWhen, G as GraphStopWhenSchema, M as MCPTransportType, b as StopWhen, S as StopWhenSchema } from './utility-DP6lt8z3.js';
2
+ import { C as ConversationHistoryConfig, A as ApiKeyApiUpdateSchema, F as FullGraphAgentInsertSchema } from './utility-8RXSemmL.js';
3
+ export { d as AgentStopWhen, a as AgentStopWhenSchema, e as CredentialStoreType, c as GraphStopWhen, G as GraphStopWhenSchema, M as MCPTransportType, b as StopWhen, S as StopWhenSchema } from './utility-8RXSemmL.js';
4
4
  import 'drizzle-zod';
5
5
  import 'drizzle-orm/sqlite-core';
6
6
  import '@hono/zod-openapi';
@@ -67,8 +67,8 @@ declare const AgentApiInsertSchema: z.ZodObject<{
67
67
  canTransferTo: z.ZodOptional<z.ZodArray<z.ZodString>>;
68
68
  canDelegateTo: z.ZodOptional<z.ZodArray<z.ZodString>>;
69
69
  type: z.ZodOptional<z.ZodEnum<{
70
- external: "external";
71
70
  internal: "internal";
71
+ external: "external";
72
72
  }>>;
73
73
  }, z.core.$strip>;
74
74
  declare const ToolApiInsertSchema: z.ZodObject<{
@@ -171,6 +171,10 @@ declare const FullGraphDefinitionSchema: z.ZodObject<{
171
171
  id: z.ZodString;
172
172
  name: z.ZodString;
173
173
  description: z.ZodString;
174
+ prompt: z.ZodString;
175
+ createdAt: z.ZodOptional<z.ZodString>;
176
+ updatedAt: z.ZodOptional<z.ZodString>;
177
+ conversationHistoryConfig: z.ZodOptional<z.ZodNullable<z.ZodType<ConversationHistoryConfig, ConversationHistoryConfig, z.core.$ZodTypeInternals<ConversationHistoryConfig, ConversationHistoryConfig>>>>;
174
178
  models: z.ZodOptional<z.ZodObject<{
175
179
  base: z.ZodOptional<z.ZodObject<{
176
180
  model: z.ZodOptional<z.ZodString>;
@@ -194,12 +198,9 @@ declare const FullGraphDefinitionSchema: z.ZodObject<{
194
198
  }, {
195
199
  stepCountIs?: number | undefined;
196
200
  }>>>>;
197
- createdAt: z.ZodOptional<z.ZodString>;
198
- updatedAt: z.ZodOptional<z.ZodString>;
199
- prompt: z.ZodString;
200
- conversationHistoryConfig: z.ZodOptional<z.ZodNullable<z.ZodType<ConversationHistoryConfig, ConversationHistoryConfig, z.core.$ZodTypeInternals<ConversationHistoryConfig, ConversationHistoryConfig>>>>;
201
201
  type: z.ZodLiteral<"internal">;
202
202
  canUse: z.ZodArray<z.ZodObject<{
203
+ agentToolRelationId: z.ZodOptional<z.ZodString>;
203
204
  toolId: z.ZodString;
204
205
  toolSelection: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString>>>;
205
206
  headers: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodString>>>;
@@ -1,5 +1,5 @@
1
- import { FullGraphAgentInsertSchema } from './chunk-AX77SEE3.js';
2
- export { AgentStopWhenSchema, GraphStopWhenSchema, StopWhenSchema } from './chunk-AX77SEE3.js';
1
+ import { FullGraphAgentInsertSchema } from './chunk-JXAL2ALG.js';
2
+ export { AgentStopWhenSchema, GraphStopWhenSchema, StopWhenSchema } from './chunk-JXAL2ALG.js';
3
3
  import { CredentialStoreType } from './chunk-YFHT5M2R.js';
4
4
  export { CredentialStoreType, MCPTransportType } from './chunk-YFHT5M2R.js';
5
5
  import { z } from 'zod';
@@ -1,7 +1,7 @@
1
1
  import 'drizzle-orm';
2
2
  import 'drizzle-orm/sqlite-core';
3
- import '../utility-DP6lt8z3.cjs';
4
- export { k as agentArtifactComponents, O as agentArtifactComponentsRelations, i as agentDataComponents, Q as agentDataComponentsRelations, a as agentGraph, F as agentGraphRelations, e as agentRelations, S as agentRelationsRelations, m as agentToolRelations, I as agentToolRelationsRelations, d as agents, E as agentsRelations, r as apiKeys, H as apiKeysRelations, j as artifactComponents, N as artifactComponentsRelations, b as contextCache, D as contextCacheRelations, c as contextConfigs, C as contextConfigsRelations, n as conversations, L as conversationsRelations, u as credentialReferences, J as credentialReferencesRelations, h as dataComponents, P as dataComponentsRelations, f as externalAgents, G as externalAgentsRelations, q as ledgerArtifacts, x as ledgerArtifactsContextIdIdx, R as ledgerArtifactsRelations, y as ledgerArtifactsTaskContextNameUnique, v as ledgerArtifactsTaskIdIdx, w as ledgerArtifactsToolCallIdIdx, o as messages, M as messagesRelations, p as projects, A as projectsRelations, g as taskRelations, B as taskRelationsRelations, t as tasks, z as tasksRelations, l as tools, K as toolsRelations } from '../schema-BsLudkuV.cjs';
3
+ import '../utility-8RXSemmL.cjs';
4
+ export { k as agentArtifactComponents, O as agentArtifactComponentsRelations, i as agentDataComponents, Q as agentDataComponentsRelations, a as agentGraph, F as agentGraphRelations, e as agentRelations, S as agentRelationsRelations, m as agentToolRelations, I as agentToolRelationsRelations, d as agents, E as agentsRelations, r as apiKeys, H as apiKeysRelations, j as artifactComponents, N as artifactComponentsRelations, b as contextCache, D as contextCacheRelations, c as contextConfigs, C as contextConfigsRelations, n as conversations, L as conversationsRelations, u as credentialReferences, J as credentialReferencesRelations, h as dataComponents, P as dataComponentsRelations, f as externalAgents, G as externalAgentsRelations, q as ledgerArtifacts, x as ledgerArtifactsContextIdIdx, R as ledgerArtifactsRelations, y as ledgerArtifactsTaskContextNameUnique, v as ledgerArtifactsTaskIdIdx, w as ledgerArtifactsToolCallIdIdx, o as messages, M as messagesRelations, p as projects, A as projectsRelations, g as taskRelations, B as taskRelationsRelations, t as tasks, z as tasksRelations, l as tools, K as toolsRelations } from '../schema-B0z-X5Hq.cjs';
5
5
  import 'zod';
6
6
  import 'drizzle-zod';
7
7
  import '@hono/zod-openapi';
@@ -1,7 +1,7 @@
1
1
  import 'drizzle-orm';
2
2
  import 'drizzle-orm/sqlite-core';
3
- import '../utility-DP6lt8z3.js';
4
- export { k as agentArtifactComponents, O as agentArtifactComponentsRelations, i as agentDataComponents, Q as agentDataComponentsRelations, a as agentGraph, F as agentGraphRelations, e as agentRelations, S as agentRelationsRelations, m as agentToolRelations, I as agentToolRelationsRelations, d as agents, E as agentsRelations, r as apiKeys, H as apiKeysRelations, j as artifactComponents, N as artifactComponentsRelations, b as contextCache, D as contextCacheRelations, c as contextConfigs, C as contextConfigsRelations, n as conversations, L as conversationsRelations, u as credentialReferences, J as credentialReferencesRelations, h as dataComponents, P as dataComponentsRelations, f as externalAgents, G as externalAgentsRelations, q as ledgerArtifacts, x as ledgerArtifactsContextIdIdx, R as ledgerArtifactsRelations, y as ledgerArtifactsTaskContextNameUnique, v as ledgerArtifactsTaskIdIdx, w as ledgerArtifactsToolCallIdIdx, o as messages, M as messagesRelations, p as projects, A as projectsRelations, g as taskRelations, B as taskRelationsRelations, t as tasks, z as tasksRelations, l as tools, K as toolsRelations } from '../schema-CjWNQuEl.js';
3
+ import '../utility-8RXSemmL.js';
4
+ export { k as agentArtifactComponents, O as agentArtifactComponentsRelations, i as agentDataComponents, Q as agentDataComponentsRelations, a as agentGraph, F as agentGraphRelations, e as agentRelations, S as agentRelationsRelations, m as agentToolRelations, I as agentToolRelationsRelations, d as agents, E as agentsRelations, r as apiKeys, H as apiKeysRelations, j as artifactComponents, N as artifactComponentsRelations, b as contextCache, D as contextCacheRelations, c as contextConfigs, C as contextConfigsRelations, n as conversations, L as conversationsRelations, u as credentialReferences, J as credentialReferencesRelations, h as dataComponents, P as dataComponentsRelations, f as externalAgents, G as externalAgentsRelations, q as ledgerArtifacts, x as ledgerArtifactsContextIdIdx, R as ledgerArtifactsRelations, y as ledgerArtifactsTaskContextNameUnique, v as ledgerArtifactsTaskIdIdx, w as ledgerArtifactsToolCallIdIdx, o as messages, M as messagesRelations, p as projects, A as projectsRelations, g as taskRelations, B as taskRelationsRelations, t as tasks, z as tasksRelations, l as tools, K as toolsRelations } from '../schema-BQoMyAN6.js';
5
5
  import 'zod';
6
6
  import 'drizzle-zod';
7
7
  import '@hono/zod-openapi';
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
  {