@kadoa/mcp 0.4.3-rc.1 → 0.4.3-rc.3
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.js +239 -298
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -44032,6 +44032,40 @@ function createCrawlerDomain(client) {
|
|
|
44032
44032
|
session: new CrawlerSessionService(client)
|
|
44033
44033
|
};
|
|
44034
44034
|
}
|
|
44035
|
+
function getFieldName(field) {
|
|
44036
|
+
return "name" in field && typeof field.name === "string" ? field.name : undefined;
|
|
44037
|
+
}
|
|
44038
|
+
function buildAgenticPrompt(params) {
|
|
44039
|
+
if (params.userPrompt) {
|
|
44040
|
+
return params.userPrompt;
|
|
44041
|
+
}
|
|
44042
|
+
const fieldNames = params.fields.map((field) => getFieldName(field)).filter((name) => Boolean(name));
|
|
44043
|
+
if (fieldNames.length === 0) {
|
|
44044
|
+
return DEFAULT_AGENTIC_PROMPT;
|
|
44045
|
+
}
|
|
44046
|
+
const fieldList = fieldNames.join(", ");
|
|
44047
|
+
if (params.entity) {
|
|
44048
|
+
return `extract all ${params.entity} entities from this page and return these fields: ${fieldList}`;
|
|
44049
|
+
}
|
|
44050
|
+
return `extract all records from this page and return these fields: ${fieldList}`;
|
|
44051
|
+
}
|
|
44052
|
+
function getFieldName2(field) {
|
|
44053
|
+
return "name" in field && typeof field.name === "string" ? field.name : undefined;
|
|
44054
|
+
}
|
|
44055
|
+
function buildAgenticPrompt2(params) {
|
|
44056
|
+
if (params.userPrompt) {
|
|
44057
|
+
return params.userPrompt;
|
|
44058
|
+
}
|
|
44059
|
+
const fieldNames = params.fields.map((field) => getFieldName2(field)).filter((name) => Boolean(name));
|
|
44060
|
+
if (fieldNames.length === 0) {
|
|
44061
|
+
return DEFAULT_AGENTIC_PROMPT2;
|
|
44062
|
+
}
|
|
44063
|
+
const fieldList = fieldNames.join(", ");
|
|
44064
|
+
if (params.entity) {
|
|
44065
|
+
return `extract all ${params.entity} entities from this page and return these fields: ${fieldList}`;
|
|
44066
|
+
}
|
|
44067
|
+
return `extract all records from this page and return these fields: ${fieldList}`;
|
|
44068
|
+
}
|
|
44035
44069
|
function validateEmailChannelConfig(config2) {
|
|
44036
44070
|
const issues = [];
|
|
44037
44071
|
if (!config2.recipients?.length) {
|
|
@@ -44194,7 +44228,6 @@ function createClientDomains(params) {
|
|
|
44194
44228
|
const dataFetcherService = new DataFetcherService(client.apis.workflows);
|
|
44195
44229
|
const channelsService = new NotificationChannelsService(client.apis.notifications, userService);
|
|
44196
44230
|
const settingsService = new NotificationSettingsService(client.apis.notifications);
|
|
44197
|
-
const entityResolverService = new EntityResolverService(client);
|
|
44198
44231
|
const workflowsCoreService = new WorkflowsCoreService(client.apis.workflows);
|
|
44199
44232
|
const schemasService = new SchemasService(client);
|
|
44200
44233
|
const templatesService = new TemplatesService(client);
|
|
@@ -44202,8 +44235,8 @@ function createClientDomains(params) {
|
|
|
44202
44235
|
const channelSetupService = new NotificationSetupService(channelsService, settingsService);
|
|
44203
44236
|
const coreService = new ValidationCoreService(client);
|
|
44204
44237
|
const rulesService = new ValidationRulesService(client);
|
|
44205
|
-
const extractionService = new ExtractionService(workflowsCoreService, dataFetcherService,
|
|
44206
|
-
const extractionBuilderService = new ExtractionBuilderService(workflowsCoreService,
|
|
44238
|
+
const extractionService = new ExtractionService(workflowsCoreService, dataFetcherService, channelSetupService, channelsService, settingsService);
|
|
44239
|
+
const extractionBuilderService = new ExtractionBuilderService(workflowsCoreService, dataFetcherService, channelSetupService);
|
|
44207
44240
|
const notification = createNotificationDomain({
|
|
44208
44241
|
notificationsApi: client.apis.notifications,
|
|
44209
44242
|
channelsService,
|
|
@@ -47371,12 +47404,19 @@ var import_debug, __require2, ChangeDifferenceType, KadoaErrorCode, _KadoaSdkExc
|
|
|
47371
47404
|
yield page;
|
|
47372
47405
|
}
|
|
47373
47406
|
}
|
|
47374
|
-
}, _SchemaBuilder = class _SchemaBuilder2 {
|
|
47407
|
+
}, RAW_HELPER_FIELD_CONFIG, _SchemaBuilder = class _SchemaBuilder2 {
|
|
47375
47408
|
constructor() {
|
|
47376
47409
|
this.fields = [];
|
|
47377
47410
|
}
|
|
47378
|
-
|
|
47379
|
-
return
|
|
47411
|
+
isRawHelperField(field) {
|
|
47412
|
+
return field.fieldType === "SCHEMA" && field.name in {
|
|
47413
|
+
rawHtml: true,
|
|
47414
|
+
rawMarkdown: true,
|
|
47415
|
+
rawPageUrl: true
|
|
47416
|
+
};
|
|
47417
|
+
}
|
|
47418
|
+
hasEntityRequiringSchemaFields() {
|
|
47419
|
+
return this.fields.some((field) => field.fieldType === "SCHEMA" && !this.isRawHelperField(field));
|
|
47380
47420
|
}
|
|
47381
47421
|
entity(entityName) {
|
|
47382
47422
|
this.entityName = entityName;
|
|
@@ -47412,20 +47452,23 @@ var import_debug, __require2, ChangeDifferenceType, KadoaErrorCode, _KadoaSdkExc
|
|
|
47412
47452
|
const names = Array.isArray(name) ? name : [name];
|
|
47413
47453
|
for (const name2 of names) {
|
|
47414
47454
|
const fieldName = `raw${upperFirst(camelCase(name2))}`;
|
|
47455
|
+
const rawKey = name2.toUpperCase();
|
|
47456
|
+
const config2 = RAW_HELPER_FIELD_CONFIG[rawKey];
|
|
47415
47457
|
if (this.fields.some((field) => field.name === fieldName)) {
|
|
47416
47458
|
continue;
|
|
47417
47459
|
}
|
|
47418
47460
|
this.fields.push({
|
|
47419
47461
|
name: fieldName,
|
|
47420
|
-
description:
|
|
47421
|
-
fieldType: "
|
|
47422
|
-
|
|
47462
|
+
description: config2.description,
|
|
47463
|
+
fieldType: "SCHEMA",
|
|
47464
|
+
dataType: config2.dataType,
|
|
47465
|
+
example: config2.example
|
|
47423
47466
|
});
|
|
47424
47467
|
}
|
|
47425
47468
|
return this;
|
|
47426
47469
|
}
|
|
47427
47470
|
build() {
|
|
47428
|
-
if (this.
|
|
47471
|
+
if (this.hasEntityRequiringSchemaFields() && !this.entityName) {
|
|
47429
47472
|
throw new KadoaSdkException("Entity name is required when schema fields are present", {
|
|
47430
47473
|
code: "VALIDATION_ERROR",
|
|
47431
47474
|
details: { entityName: this.entityName }
|
|
@@ -47530,88 +47573,10 @@ var import_debug, __require2, ChangeDifferenceType, KadoaErrorCode, _KadoaSdkExc
|
|
|
47530
47573
|
schemaId
|
|
47531
47574
|
});
|
|
47532
47575
|
}
|
|
47533
|
-
},
|
|
47534
|
-
constructor(
|
|
47535
|
-
this.client = client;
|
|
47536
|
-
this.schemasService = new SchemasService(client);
|
|
47537
|
-
}
|
|
47538
|
-
async resolveEntity(entityConfig, options) {
|
|
47539
|
-
if (entityConfig === "ai-detection") {
|
|
47540
|
-
if (!options?.link) {
|
|
47541
|
-
throw new KadoaSdkException(ERROR_MESSAGES.LINK_REQUIRED, {
|
|
47542
|
-
code: "VALIDATION_ERROR",
|
|
47543
|
-
details: { entityConfig, options }
|
|
47544
|
-
});
|
|
47545
|
-
}
|
|
47546
|
-
const entityPrediction = await this.fetchEntityFields({
|
|
47547
|
-
link: options.link,
|
|
47548
|
-
location: options.location,
|
|
47549
|
-
navigationMode: options.navigationMode,
|
|
47550
|
-
selectorMode: options.selectorMode ?? false
|
|
47551
|
-
});
|
|
47552
|
-
const entity = entityPrediction.entity;
|
|
47553
|
-
return {
|
|
47554
|
-
entity,
|
|
47555
|
-
fields: entityPrediction.fields
|
|
47556
|
-
};
|
|
47557
|
-
} else if (entityConfig) {
|
|
47558
|
-
if ("schemaId" in entityConfig) {
|
|
47559
|
-
const schema = await this.schemasService.getSchema(entityConfig.schemaId);
|
|
47560
|
-
return {
|
|
47561
|
-
entity: schema.entity ?? undefined,
|
|
47562
|
-
fields: schema.schema
|
|
47563
|
-
};
|
|
47564
|
-
} else if ("fields" in entityConfig) {
|
|
47565
|
-
return {
|
|
47566
|
-
entity: entityConfig.name,
|
|
47567
|
-
fields: entityConfig.fields
|
|
47568
|
-
};
|
|
47569
|
-
}
|
|
47570
|
-
}
|
|
47571
|
-
throw new KadoaSdkException(ERROR_MESSAGES.ENTITY_INVARIANT_VIOLATION, {
|
|
47572
|
-
details: {
|
|
47573
|
-
entity: entityConfig
|
|
47574
|
-
}
|
|
47575
|
-
});
|
|
47576
|
-
}
|
|
47577
|
-
async fetchEntityFields(options) {
|
|
47578
|
-
this.validateEntityOptions(options);
|
|
47579
|
-
const url3 = `${this.client.baseUrl}${ENTITY_API_ENDPOINT}`;
|
|
47580
|
-
const requestBody = options;
|
|
47581
|
-
const response = await this.client.axiosInstance.post(url3, requestBody, {
|
|
47582
|
-
headers: {
|
|
47583
|
-
"Content-Type": "application/json",
|
|
47584
|
-
Accept: "application/json",
|
|
47585
|
-
"x-api-key": this.client.apiKey
|
|
47586
|
-
}
|
|
47587
|
-
});
|
|
47588
|
-
const data = response.data;
|
|
47589
|
-
if (!data.success || !data.entityPrediction || data.entityPrediction.length === 0) {
|
|
47590
|
-
throw new KadoaSdkException(ERROR_MESSAGES.NO_PREDICTIONS, {
|
|
47591
|
-
code: "NOT_FOUND",
|
|
47592
|
-
details: {
|
|
47593
|
-
success: data.success,
|
|
47594
|
-
hasPredictions: !!data.entityPrediction,
|
|
47595
|
-
predictionCount: data.entityPrediction?.length || 0,
|
|
47596
|
-
link: options.link
|
|
47597
|
-
}
|
|
47598
|
-
});
|
|
47599
|
-
}
|
|
47600
|
-
return data.entityPrediction[0];
|
|
47601
|
-
}
|
|
47602
|
-
validateEntityOptions(options) {
|
|
47603
|
-
if (!options.link) {
|
|
47604
|
-
throw new KadoaSdkException(ERROR_MESSAGES.LINK_REQUIRED, {
|
|
47605
|
-
code: "VALIDATION_ERROR",
|
|
47606
|
-
details: { options }
|
|
47607
|
-
});
|
|
47608
|
-
}
|
|
47609
|
-
}
|
|
47610
|
-
}, debug3, SUCCESSFUL_RUN_STATES, DEFAULT_OPTIONS, ExtractionService = class {
|
|
47611
|
-
constructor(workflowsCoreService, dataFetcherService, entityResolverService, notificationSetupService, notificationChannelsService, notificationSettingsService) {
|
|
47576
|
+
}, debug3, SUCCESSFUL_RUN_STATES, DEFAULT_AGENTIC_PROMPT = "extract all the data for the main entity of this page", DEFAULT_OPTIONS, ExtractionService = class {
|
|
47577
|
+
constructor(workflowsCoreService, dataFetcherService, notificationSetupService, notificationChannelsService, notificationSettingsService) {
|
|
47612
47578
|
this.workflowsCoreService = workflowsCoreService;
|
|
47613
47579
|
this.dataFetcherService = dataFetcherService;
|
|
47614
|
-
this.entityResolverService = entityResolverService;
|
|
47615
47580
|
this.notificationSetupService = notificationSetupService;
|
|
47616
47581
|
this.notificationChannelsService = notificationChannelsService;
|
|
47617
47582
|
this.notificationSettingsService = notificationSettingsService;
|
|
@@ -47646,7 +47611,9 @@ var import_debug, __require2, ChangeDifferenceType, KadoaErrorCode, _KadoaSdkExc
|
|
|
47646
47611
|
}
|
|
47647
47612
|
async executeExtraction(options) {
|
|
47648
47613
|
this.validateOptions(options);
|
|
47649
|
-
const config2 =
|
|
47614
|
+
const config2 = {
|
|
47615
|
+
...merge3(DEFAULT_OPTIONS, options)
|
|
47616
|
+
};
|
|
47650
47617
|
const isRealTime = config2.interval === "REAL_TIME";
|
|
47651
47618
|
if (isRealTime) {
|
|
47652
47619
|
throw new KadoaSdkException("extraction.run()/submit() are not supported for real-time workflows. Use the builder API, call waitForReady(), and subscribe via client.realtime.onEvent(...).", {
|
|
@@ -47657,35 +47624,23 @@ var import_debug, __require2, ChangeDifferenceType, KadoaErrorCode, _KadoaSdkExc
|
|
|
47657
47624
|
});
|
|
47658
47625
|
}
|
|
47659
47626
|
let workflowId;
|
|
47660
|
-
const
|
|
47661
|
-
|
|
47662
|
-
|
|
47663
|
-
|
|
47664
|
-
|
|
47665
|
-
details: { navigationMode: config2.navigationMode }
|
|
47666
|
-
});
|
|
47667
|
-
}
|
|
47668
|
-
}
|
|
47669
|
-
let resolvedEntity;
|
|
47670
|
-
if (isAgenticNavigation) {
|
|
47671
|
-
const entityConfig = options.entity || "ai-detection";
|
|
47672
|
-
resolvedEntity = {
|
|
47673
|
-
entity: typeof entityConfig === "object" && "name" in entityConfig ? entityConfig.name : undefined,
|
|
47674
|
-
fields: typeof entityConfig === "object" && "fields" in entityConfig ? entityConfig.fields : []
|
|
47675
|
-
};
|
|
47676
|
-
} else {
|
|
47677
|
-
resolvedEntity = await this.entityResolverService.resolveEntity(options.entity || "ai-detection", {
|
|
47678
|
-
link: config2.urls[0],
|
|
47679
|
-
location: config2.location,
|
|
47680
|
-
navigationMode: config2.navigationMode
|
|
47681
|
-
});
|
|
47682
|
-
}
|
|
47627
|
+
const entityConfig = options.entity;
|
|
47628
|
+
const resolvedEntity = {
|
|
47629
|
+
entity: typeof entityConfig === "object" && "name" in entityConfig ? entityConfig.name : undefined,
|
|
47630
|
+
fields: typeof entityConfig === "object" && "fields" in entityConfig ? entityConfig.fields : []
|
|
47631
|
+
};
|
|
47683
47632
|
const hasNotifications = !!config2.notifications;
|
|
47633
|
+
const userPrompt = buildAgenticPrompt({
|
|
47634
|
+
entity: resolvedEntity.entity,
|
|
47635
|
+
fields: resolvedEntity.fields,
|
|
47636
|
+
userPrompt: config2.userPrompt
|
|
47637
|
+
});
|
|
47684
47638
|
const workflowRequest = {
|
|
47685
47639
|
...config2,
|
|
47640
|
+
navigationMode: "agentic-navigation",
|
|
47686
47641
|
fields: resolvedEntity.fields,
|
|
47687
47642
|
...resolvedEntity.entity !== undefined ? { entity: resolvedEntity.entity } : {},
|
|
47688
|
-
|
|
47643
|
+
userPrompt
|
|
47689
47644
|
};
|
|
47690
47645
|
const result = await this.workflowsCoreService.create(workflowRequest);
|
|
47691
47646
|
workflowId = result.id;
|
|
@@ -47770,10 +47725,9 @@ var import_debug, __require2, ChangeDifferenceType, KadoaErrorCode, _KadoaSdkExc
|
|
|
47770
47725
|
isExtractionSuccessful(runState) {
|
|
47771
47726
|
return runState ? SUCCESSFUL_RUN_STATES.has(runState.toUpperCase()) : false;
|
|
47772
47727
|
}
|
|
47773
|
-
}, debug4, ExtractionBuilderService = class {
|
|
47774
|
-
constructor(workflowsCoreService,
|
|
47728
|
+
}, debug4, DEFAULT_AGENTIC_PROMPT2 = "extract all the data for the main entity of this page", BUILD_NOT_READY_ERROR = "No completed build. Build the project first.", TERMINAL_RUN_STATES, ExtractionBuilderService = class {
|
|
47729
|
+
constructor(workflowsCoreService, dataFetcherService, notificationSetupService) {
|
|
47775
47730
|
this.workflowsCoreService = workflowsCoreService;
|
|
47776
|
-
this.entityResolverService = entityResolverService;
|
|
47777
47731
|
this.dataFetcherService = dataFetcherService;
|
|
47778
47732
|
this.notificationSetupService = notificationSetupService;
|
|
47779
47733
|
}
|
|
@@ -47799,7 +47753,6 @@ var import_debug, __require2, ChangeDifferenceType, KadoaErrorCode, _KadoaSdkExc
|
|
|
47799
47753
|
urls,
|
|
47800
47754
|
name,
|
|
47801
47755
|
description,
|
|
47802
|
-
navigationMode,
|
|
47803
47756
|
extraction,
|
|
47804
47757
|
additionalData,
|
|
47805
47758
|
bypassPreview,
|
|
@@ -47809,23 +47762,22 @@ var import_debug, __require2, ChangeDifferenceType, KadoaErrorCode, _KadoaSdkExc
|
|
|
47809
47762
|
location
|
|
47810
47763
|
}) {
|
|
47811
47764
|
let entity = "ai-detection";
|
|
47765
|
+
let builtFields = [];
|
|
47812
47766
|
if (extraction) {
|
|
47813
47767
|
const result = extraction(new SchemaBuilder);
|
|
47814
47768
|
if ("schemaId" in result) {
|
|
47815
47769
|
entity = { schemaId: result.schemaId };
|
|
47816
47770
|
} else {
|
|
47817
47771
|
const builtSchema = result.build();
|
|
47818
|
-
|
|
47772
|
+
builtFields = builtSchema.fields;
|
|
47773
|
+
entity = builtSchema.entityName ? { name: builtSchema.entityName, fields: builtFields } : { fields: builtFields };
|
|
47819
47774
|
}
|
|
47820
47775
|
}
|
|
47821
|
-
|
|
47822
|
-
this._userPrompt = userPrompt;
|
|
47823
|
-
}
|
|
47776
|
+
this._userPrompt = userPrompt;
|
|
47824
47777
|
this._options = {
|
|
47825
47778
|
urls,
|
|
47826
47779
|
name,
|
|
47827
47780
|
description,
|
|
47828
|
-
navigationMode: navigationMode || "single-page",
|
|
47829
47781
|
entity,
|
|
47830
47782
|
bypassPreview: bypassPreview ?? false,
|
|
47831
47783
|
additionalData,
|
|
@@ -47872,41 +47824,27 @@ var import_debug, __require2, ChangeDifferenceType, KadoaErrorCode, _KadoaSdkExc
|
|
|
47872
47824
|
}
|
|
47873
47825
|
async create() {
|
|
47874
47826
|
assert2(this._options, "Options are not set");
|
|
47875
|
-
const { urls, name, description,
|
|
47876
|
-
const
|
|
47877
|
-
|
|
47878
|
-
|
|
47879
|
-
|
|
47880
|
-
|
|
47881
|
-
|
|
47882
|
-
|
|
47883
|
-
|
|
47884
|
-
}
|
|
47885
|
-
|
|
47886
|
-
const
|
|
47887
|
-
|
|
47888
|
-
if (isAgenticNavigation) {
|
|
47889
|
-
resolvedEntity = {
|
|
47890
|
-
entity: typeof entity === "object" && "name" in entity ? entity.name : undefined,
|
|
47891
|
-
fields: typeof entity === "object" && "fields" in entity ? entity.fields : []
|
|
47892
|
-
};
|
|
47893
|
-
} else {
|
|
47894
|
-
resolvedEntity = await this.entityResolverService.resolveEntity(entity, {
|
|
47895
|
-
link: urls[0],
|
|
47896
|
-
location: this._options.location,
|
|
47897
|
-
navigationMode,
|
|
47898
|
-
selectorMode: useSelectorMode
|
|
47899
|
-
});
|
|
47900
|
-
}
|
|
47901
|
-
const hasSchemaId = typeof entity === "object" && "schemaId" in entity && entity.schemaId;
|
|
47827
|
+
const { urls, name, description, entity } = this.options;
|
|
47828
|
+
const resolvedEntity = {
|
|
47829
|
+
entity: typeof entity === "object" && "name" in entity ? entity.name : undefined,
|
|
47830
|
+
fields: typeof entity === "object" && "fields" in entity ? entity.fields : []
|
|
47831
|
+
};
|
|
47832
|
+
this._userPrompt = buildAgenticPrompt2({
|
|
47833
|
+
entity: resolvedEntity.entity,
|
|
47834
|
+
fields: resolvedEntity.fields,
|
|
47835
|
+
userPrompt: this._userPrompt
|
|
47836
|
+
});
|
|
47837
|
+
this._options.userPrompt = this._userPrompt;
|
|
47838
|
+
const schemaId = typeof entity === "object" && "schemaId" in entity ? entity.schemaId : undefined;
|
|
47839
|
+
const hasSchemaId = Boolean(schemaId);
|
|
47902
47840
|
const workflow = await this.workflowsCoreService.create({
|
|
47903
47841
|
urls,
|
|
47904
47842
|
name,
|
|
47905
47843
|
description,
|
|
47906
|
-
navigationMode,
|
|
47844
|
+
navigationMode: "agentic-navigation",
|
|
47907
47845
|
monitoring: this._monitoringOptions,
|
|
47908
47846
|
...hasSchemaId ? {
|
|
47909
|
-
schemaId
|
|
47847
|
+
schemaId,
|
|
47910
47848
|
entity: resolvedEntity.entity,
|
|
47911
47849
|
fields: resolvedEntity.fields
|
|
47912
47850
|
} : { entity: resolvedEntity.entity, fields: resolvedEntity.fields },
|
|
@@ -47952,7 +47890,10 @@ var import_debug, __require2, ChangeDifferenceType, KadoaErrorCode, _KadoaSdkExc
|
|
|
47952
47890
|
}
|
|
47953
47891
|
});
|
|
47954
47892
|
}
|
|
47955
|
-
const startedJob = await this.
|
|
47893
|
+
const startedJob = await this.startOrReuseWorkflowRun(this._workflowId, {
|
|
47894
|
+
variables: options?.variables,
|
|
47895
|
+
limit: options?.limit
|
|
47896
|
+
});
|
|
47956
47897
|
assert2(startedJob.jobId, "Job ID is not set");
|
|
47957
47898
|
debug4("Job started: %O", startedJob);
|
|
47958
47899
|
this._jobId = startedJob.jobId;
|
|
@@ -47972,7 +47913,10 @@ var import_debug, __require2, ChangeDifferenceType, KadoaErrorCode, _KadoaSdkExc
|
|
|
47972
47913
|
}
|
|
47973
47914
|
});
|
|
47974
47915
|
}
|
|
47975
|
-
const submittedJob = await this.
|
|
47916
|
+
const submittedJob = await this.startOrReuseWorkflowRun(this._workflowId, {
|
|
47917
|
+
variables: options?.variables,
|
|
47918
|
+
limit: options?.limit
|
|
47919
|
+
});
|
|
47976
47920
|
assert2(submittedJob.jobId, "Job ID is not set");
|
|
47977
47921
|
debug4("Job submitted: %O", submittedJob);
|
|
47978
47922
|
this._jobId = submittedJob.jobId;
|
|
@@ -48001,6 +47945,60 @@ var import_debug, __require2, ChangeDifferenceType, KadoaErrorCode, _KadoaSdkExc
|
|
|
48001
47945
|
...options
|
|
48002
47946
|
});
|
|
48003
47947
|
}
|
|
47948
|
+
async startOrReuseWorkflowRun(workflowId, input) {
|
|
47949
|
+
const currentJob = await this.findActiveWorkflowJob(workflowId);
|
|
47950
|
+
if (currentJob) {
|
|
47951
|
+
debug4("Reusing active workflow job: %O", currentJob);
|
|
47952
|
+
return currentJob;
|
|
47953
|
+
}
|
|
47954
|
+
try {
|
|
47955
|
+
return await this.workflowsCoreService.runWorkflow(workflowId, input);
|
|
47956
|
+
} catch (error48) {
|
|
47957
|
+
if (!this.isBuildNotReadyError(error48)) {
|
|
47958
|
+
throw error48;
|
|
47959
|
+
}
|
|
47960
|
+
const recoveredJob = await this.waitForWorkflowJob(workflowId);
|
|
47961
|
+
if (recoveredJob) {
|
|
47962
|
+
debug4("Recovered active workflow job after run rejection: %O", recoveredJob);
|
|
47963
|
+
return recoveredJob;
|
|
47964
|
+
}
|
|
47965
|
+
throw error48;
|
|
47966
|
+
}
|
|
47967
|
+
}
|
|
47968
|
+
async findActiveWorkflowJob(workflowId) {
|
|
47969
|
+
const workflow = await this.workflowsCoreService.get(workflowId);
|
|
47970
|
+
if (!workflow.jobId || !workflow.runState) {
|
|
47971
|
+
return;
|
|
47972
|
+
}
|
|
47973
|
+
if (TERMINAL_RUN_STATES.has(workflow.runState.toUpperCase())) {
|
|
47974
|
+
return;
|
|
47975
|
+
}
|
|
47976
|
+
return {
|
|
47977
|
+
jobId: workflow.jobId,
|
|
47978
|
+
status: workflow.runState,
|
|
47979
|
+
message: "Workflow already has an active run"
|
|
47980
|
+
};
|
|
47981
|
+
}
|
|
47982
|
+
async waitForWorkflowJob(workflowId) {
|
|
47983
|
+
for (let attempt2 = 0;attempt2 < 5; attempt2 += 1) {
|
|
47984
|
+
const currentJob = await this.findActiveWorkflowJob(workflowId);
|
|
47985
|
+
if (currentJob) {
|
|
47986
|
+
return currentJob;
|
|
47987
|
+
}
|
|
47988
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
47989
|
+
}
|
|
47990
|
+
return;
|
|
47991
|
+
}
|
|
47992
|
+
isBuildNotReadyError(error48) {
|
|
47993
|
+
if (!(error48 instanceof KadoaHttpException)) {
|
|
47994
|
+
return false;
|
|
47995
|
+
}
|
|
47996
|
+
const responseBody = error48.responseBody;
|
|
47997
|
+
if (responseBody && typeof responseBody === "object" && "error" in responseBody && typeof responseBody.error === "string") {
|
|
47998
|
+
return responseBody.error.includes(BUILD_NOT_READY_ERROR);
|
|
47999
|
+
}
|
|
48000
|
+
return typeof error48.message === "string" ? error48.message.includes(BUILD_NOT_READY_ERROR) : false;
|
|
48001
|
+
}
|
|
48004
48002
|
}, NotificationChannelType, EMAIL_REGEX, _NotificationChannelsService = class _NotificationChannelsService2 {
|
|
48005
48003
|
constructor(notificationsApi, userService) {
|
|
48006
48004
|
this.api = notificationsApi;
|
|
@@ -48327,7 +48325,7 @@ var import_debug, __require2, ChangeDifferenceType, KadoaErrorCode, _KadoaSdkExc
|
|
|
48327
48325
|
}));
|
|
48328
48326
|
return channels;
|
|
48329
48327
|
}
|
|
48330
|
-
}, PUBLIC_API_URI, WSS_API_URI, REALTIME_API_URI, SDK_VERSION = "0.
|
|
48328
|
+
}, PUBLIC_API_URI, WSS_API_URI, REALTIME_API_URI, SDK_VERSION = "0.28.0", SDK_NAME = "kadoa-node-sdk", SDK_LANGUAGE = "node", debug6, isDrainControlMessage = (message) => message.type === "control.draining", isRealtimeEvent = (message) => message.type !== "heartbeat" && message.type !== "control.draining", _Realtime = class _Realtime2 {
|
|
48331
48329
|
constructor(config2) {
|
|
48332
48330
|
this.drainingSockets = /* @__PURE__ */ new Set;
|
|
48333
48331
|
this.lastHeartbeat = Date.now();
|
|
@@ -48737,37 +48735,6 @@ var import_debug, __require2, ChangeDifferenceType, KadoaErrorCode, _KadoaSdkExc
|
|
|
48737
48735
|
});
|
|
48738
48736
|
return response.data.data ?? [];
|
|
48739
48737
|
}
|
|
48740
|
-
async listWorkflows(templateId) {
|
|
48741
|
-
debug7("Listing workflows for template: %s", templateId);
|
|
48742
|
-
const response = await this.templatesApi.v4TemplatesTemplateIdWorkflowsGet({
|
|
48743
|
-
templateId
|
|
48744
|
-
});
|
|
48745
|
-
return response.data.data ?? [];
|
|
48746
|
-
}
|
|
48747
|
-
async linkWorkflows(templateId, body) {
|
|
48748
|
-
debug7("Linking %d workflows to template: %s", body.workflowIds.length, templateId);
|
|
48749
|
-
const response = await this.templatesApi.v4TemplatesTemplateIdLinkPost({
|
|
48750
|
-
templateId,
|
|
48751
|
-
linkWorkflowsBody: body
|
|
48752
|
-
});
|
|
48753
|
-
return response.data;
|
|
48754
|
-
}
|
|
48755
|
-
async unlinkWorkflows(templateId, body) {
|
|
48756
|
-
debug7("Unlinking %d workflows from template: %s", body.workflowIds.length, templateId);
|
|
48757
|
-
const response = await this.templatesApi.v4TemplatesTemplateIdUnlinkPost({
|
|
48758
|
-
templateId,
|
|
48759
|
-
unlinkWorkflowsBody: body
|
|
48760
|
-
});
|
|
48761
|
-
return response.data;
|
|
48762
|
-
}
|
|
48763
|
-
async applyUpdate(templateId, body) {
|
|
48764
|
-
debug7("Applying version %d to %d workflows for template: %s", body.targetVersion, body.workflowIds.length, templateId);
|
|
48765
|
-
const response = await this.templatesApi.v4TemplatesTemplateIdApplyPost({
|
|
48766
|
-
templateId,
|
|
48767
|
-
applyTemplateUpdateBody: body
|
|
48768
|
-
});
|
|
48769
|
-
return response.data;
|
|
48770
|
-
}
|
|
48771
48738
|
async createFromWorkflow(body) {
|
|
48772
48739
|
debug7("Creating template from workflow: %s", body.workflowId);
|
|
48773
48740
|
const response = await this.templatesApi.v4TemplatesFromWorkflowPost({
|
|
@@ -49086,7 +49053,7 @@ var import_debug, __require2, ChangeDifferenceType, KadoaErrorCode, _KadoaSdkExc
|
|
|
49086
49053
|
variableId
|
|
49087
49054
|
});
|
|
49088
49055
|
}
|
|
49089
|
-
}, JobStateEnum, TERMINAL_JOB_STATES,
|
|
49056
|
+
}, JobStateEnum, TERMINAL_JOB_STATES, TERMINAL_RUN_STATES2, debug9, WorkflowsCoreService = class {
|
|
49090
49057
|
constructor(workflowsApi) {
|
|
49091
49058
|
this.workflowsApi = workflowsApi;
|
|
49092
49059
|
}
|
|
@@ -49208,7 +49175,7 @@ var import_debug, __require2, ChangeDifferenceType, KadoaErrorCode, _KadoaSdkExc
|
|
|
49208
49175
|
if (options?.targetState && current.state === options.targetState) {
|
|
49209
49176
|
return true;
|
|
49210
49177
|
}
|
|
49211
|
-
if (current.runState &&
|
|
49178
|
+
if (current.runState && TERMINAL_RUN_STATES2.has(current.runState.toUpperCase()) && current.state !== "QUEUED") {
|
|
49212
49179
|
return true;
|
|
49213
49180
|
}
|
|
49214
49181
|
return false;
|
|
@@ -49963,6 +49930,25 @@ var init_dist2 = __esm(() => {
|
|
|
49963
49930
|
Text: DataFieldDataTypeEnum.String,
|
|
49964
49931
|
Url: DataFieldDataTypeEnum.Link
|
|
49965
49932
|
};
|
|
49933
|
+
RAW_HELPER_FIELD_CONFIG = {
|
|
49934
|
+
HTML: {
|
|
49935
|
+
dataType: "STRING",
|
|
49936
|
+
description: "Full page HTML as a string. Return the raw HTML content.",
|
|
49937
|
+
example: "<html><body><h1>Example page</h1></body></html>"
|
|
49938
|
+
},
|
|
49939
|
+
MARKDOWN: {
|
|
49940
|
+
dataType: "STRING",
|
|
49941
|
+
description: "Main page content rendered as markdown. Return the markdown as a string.",
|
|
49942
|
+
example: `# Example page
|
|
49943
|
+
|
|
49944
|
+
This is the main page content.`
|
|
49945
|
+
},
|
|
49946
|
+
PAGE_URL: {
|
|
49947
|
+
dataType: "LINK",
|
|
49948
|
+
description: "Canonical page URL for the extracted page. Return the resolved page URL.",
|
|
49949
|
+
example: "https://example.com/page"
|
|
49950
|
+
}
|
|
49951
|
+
};
|
|
49966
49952
|
_SchemaBuilder.FIELD_NAME_PATTERN = /^[A-Za-z0-9]+$/;
|
|
49967
49953
|
_SchemaBuilder.TYPES_REQUIRING_EXAMPLE = [
|
|
49968
49954
|
"STRING",
|
|
@@ -49979,12 +49965,19 @@ var init_dist2 = __esm(() => {
|
|
|
49979
49965
|
mode: "run",
|
|
49980
49966
|
pollingInterval: 5000,
|
|
49981
49967
|
maxWaitTime: 300000,
|
|
49982
|
-
navigationMode: "single-page",
|
|
49983
49968
|
location: { type: "auto" },
|
|
49984
49969
|
bypassPreview: true,
|
|
49985
49970
|
autoStart: true
|
|
49986
49971
|
};
|
|
49987
49972
|
debug4 = logger.extraction;
|
|
49973
|
+
TERMINAL_RUN_STATES = /* @__PURE__ */ new Set([
|
|
49974
|
+
"FINISHED",
|
|
49975
|
+
"SUCCESS",
|
|
49976
|
+
"FAILED",
|
|
49977
|
+
"ERROR",
|
|
49978
|
+
"STOPPED",
|
|
49979
|
+
"CANCELLED"
|
|
49980
|
+
]);
|
|
49988
49981
|
NotificationChannelType = {
|
|
49989
49982
|
EMAIL: "EMAIL",
|
|
49990
49983
|
SLACK: "SLACK",
|
|
@@ -50028,7 +50021,7 @@ var init_dist2 = __esm(() => {
|
|
|
50028
50021
|
JobStateEnum.NotSupported,
|
|
50029
50022
|
JobStateEnum.FailedInsufficientFunds
|
|
50030
50023
|
]);
|
|
50031
|
-
|
|
50024
|
+
TERMINAL_RUN_STATES2 = /* @__PURE__ */ new Set([
|
|
50032
50025
|
"FINISHED",
|
|
50033
50026
|
"SUCCESS",
|
|
50034
50027
|
"FAILED",
|
|
@@ -50233,6 +50226,9 @@ function coerceBoolean() {
|
|
|
50233
50226
|
return val;
|
|
50234
50227
|
};
|
|
50235
50228
|
}
|
|
50229
|
+
function coerceNull() {
|
|
50230
|
+
return (val) => val === "null" ? undefined : val;
|
|
50231
|
+
}
|
|
50236
50232
|
function coerceJson() {
|
|
50237
50233
|
return (val) => {
|
|
50238
50234
|
if (typeof val === "string") {
|
|
@@ -50264,17 +50260,42 @@ function extractApiMessage(responseBody) {
|
|
|
50264
50260
|
const body = responseBody;
|
|
50265
50261
|
if (!body || typeof body !== "object")
|
|
50266
50262
|
return;
|
|
50267
|
-
|
|
50268
|
-
if (!msg)
|
|
50269
|
-
return;
|
|
50263
|
+
let msg = typeof body.error === "string" && body.error || typeof body.message === "string" && body.message || undefined;
|
|
50270
50264
|
if (body.validationErrors && typeof body.validationErrors === "object" && body.validationErrors !== null) {
|
|
50271
50265
|
const details = Object.entries(body.validationErrors).map(([field, err]) => `${field}: "${err}"`).join(", ");
|
|
50266
|
+
if (details) {
|
|
50267
|
+
msg = msg ? `${msg} — Details: ${details}` : `Validation failed — Details: ${details}`;
|
|
50268
|
+
}
|
|
50269
|
+
}
|
|
50270
|
+
if (!msg && Array.isArray(body.issues)) {
|
|
50271
|
+
const details = body.issues.map((issue2) => {
|
|
50272
|
+
const path = Array.isArray(issue2.path) ? issue2.path.join(".") : "";
|
|
50273
|
+
const message = typeof issue2.message === "string" ? issue2.message : String(issue2.code ?? "invalid");
|
|
50274
|
+
return path ? `${path}: "${message}"` : `"${message}"`;
|
|
50275
|
+
}).join(", ");
|
|
50272
50276
|
if (details)
|
|
50273
|
-
|
|
50277
|
+
msg = `Validation failed — Details: ${details}`;
|
|
50274
50278
|
}
|
|
50275
50279
|
return msg;
|
|
50276
50280
|
}
|
|
50277
|
-
function
|
|
50281
|
+
function inferResourceType(toolName) {
|
|
50282
|
+
if (!toolName)
|
|
50283
|
+
return "resource";
|
|
50284
|
+
if (toolName.includes("template") || toolName.includes("version"))
|
|
50285
|
+
return "template";
|
|
50286
|
+
if (toolName.includes("variable"))
|
|
50287
|
+
return "variable";
|
|
50288
|
+
if (toolName.includes("workflow") || toolName.includes("monitor"))
|
|
50289
|
+
return "workflow";
|
|
50290
|
+
if (toolName.includes("channel") || toolName.includes("notification"))
|
|
50291
|
+
return "notification channel";
|
|
50292
|
+
if (toolName.includes("schema"))
|
|
50293
|
+
return "schema";
|
|
50294
|
+
if (toolName.includes("change"))
|
|
50295
|
+
return "change record";
|
|
50296
|
+
return "resource";
|
|
50297
|
+
}
|
|
50298
|
+
function classifyError(error48, toolName) {
|
|
50278
50299
|
if (KadoaSdkException.isInstance(error48)) {
|
|
50279
50300
|
const code = error48.code;
|
|
50280
50301
|
if (KadoaHttpException.isInstance(error48)) {
|
|
@@ -50286,8 +50307,10 @@ function classifyError(error48) {
|
|
|
50286
50307
|
return `Access denied${status}. Your current team role may not have permission for this action. Use the whoami tool to check your role, or contact your team admin to request elevated access.`;
|
|
50287
50308
|
}
|
|
50288
50309
|
return `Authentication failed${status}. Please re-authenticate via OAuth.`;
|
|
50289
|
-
case "NOT_FOUND":
|
|
50290
|
-
|
|
50310
|
+
case "NOT_FOUND": {
|
|
50311
|
+
const resource = inferResourceType(toolName);
|
|
50312
|
+
return `Not found${status}. The ${resource} may have been deleted or the ID is incorrect.`;
|
|
50313
|
+
}
|
|
50291
50314
|
case "RATE_LIMITED":
|
|
50292
50315
|
return `Rate limit exceeded${status}. Please wait a moment and try again.`;
|
|
50293
50316
|
case "NETWORK_ERROR":
|
|
@@ -50304,8 +50327,10 @@ function classifyError(error48) {
|
|
|
50304
50327
|
switch (code) {
|
|
50305
50328
|
case "AUTH_ERROR":
|
|
50306
50329
|
return "Authentication failed. Please re-authenticate via OAuth.";
|
|
50307
|
-
case "NOT_FOUND":
|
|
50308
|
-
|
|
50330
|
+
case "NOT_FOUND": {
|
|
50331
|
+
const resource = inferResourceType(toolName);
|
|
50332
|
+
return `Not found. The ${resource} may have been deleted or the ID is incorrect.`;
|
|
50333
|
+
}
|
|
50309
50334
|
case "RATE_LIMITED":
|
|
50310
50335
|
return "Rate limit exceeded. Please wait a moment and try again.";
|
|
50311
50336
|
case "NETWORK_ERROR":
|
|
@@ -50348,7 +50373,7 @@ function registerTools(server, ctx) {
|
|
|
50348
50373
|
console.error(`[Tool Error] ${name}: session expired, user must re-authenticate`);
|
|
50349
50374
|
return errorResult("Your session has expired. Please reconnect the MCP server to re-authenticate.");
|
|
50350
50375
|
}
|
|
50351
|
-
let message = classifyError(error48);
|
|
50376
|
+
let message = classifyError(error48, name);
|
|
50352
50377
|
if (KadoaHttpException.isInstance(error48) && error48.httpStatus === 403) {
|
|
50353
50378
|
try {
|
|
50354
50379
|
const jwt2 = ctx.supabaseJwt;
|
|
@@ -50536,7 +50561,6 @@ function registerTools(server, ctx) {
|
|
|
50536
50561
|
let builder = ctx.client.extract({
|
|
50537
50562
|
urls,
|
|
50538
50563
|
name: args.name || "Untitled Workflow",
|
|
50539
|
-
navigationMode: "agentic-navigation",
|
|
50540
50564
|
userPrompt: args.prompt,
|
|
50541
50565
|
extraction: buildExtraction(args),
|
|
50542
50566
|
interval: args.updateInterval,
|
|
@@ -51251,7 +51275,7 @@ function registerTools(server, ctx) {
|
|
|
51251
51275
|
});
|
|
51252
51276
|
}));
|
|
51253
51277
|
server.registerTool("list_templates", {
|
|
51254
|
-
description: "List all templates in the current team. Templates define reusable configurations (prompt, schema, notifications)
|
|
51278
|
+
description: "List all templates in the current team. Templates define reusable configurations (prompt, schema, notifications).",
|
|
51255
51279
|
inputSchema: strictSchema({}),
|
|
51256
51280
|
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true }
|
|
51257
51281
|
}, withErrorHandling("list_templates", async () => {
|
|
@@ -51269,7 +51293,7 @@ function registerTools(server, ctx) {
|
|
|
51269
51293
|
return jsonResult({ template });
|
|
51270
51294
|
}));
|
|
51271
51295
|
server.registerTool("create_template", {
|
|
51272
|
-
description: "Create a new template.
|
|
51296
|
+
description: "Create a new template. After creation, use create_template_version to publish a version with prompt, schema, and notifications.",
|
|
51273
51297
|
inputSchema: strictSchema({
|
|
51274
51298
|
name: exports_external.string().describe("Template name (1-255 chars)"),
|
|
51275
51299
|
description: exports_external.string().optional().describe("Template description (max 2000 chars)")
|
|
@@ -51290,8 +51314,8 @@ function registerTools(server, ctx) {
|
|
|
51290
51314
|
description: "Update a template's name or description. At least one field must be provided.",
|
|
51291
51315
|
inputSchema: strictSchema({
|
|
51292
51316
|
templateId: exports_external.string().describe("The template ID to update"),
|
|
51293
|
-
name: exports_external.string().optional().describe("New template name"),
|
|
51294
|
-
description: exports_external.string().optional().describe("New template description")
|
|
51317
|
+
name: exports_external.preprocess(coerceNull(), exports_external.string().optional()).describe("New template name"),
|
|
51318
|
+
description: exports_external.preprocess(coerceNull(), exports_external.string().optional()).describe("New template description")
|
|
51295
51319
|
}),
|
|
51296
51320
|
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true }
|
|
51297
51321
|
}, withErrorHandling("update_template", async (args) => {
|
|
@@ -51304,7 +51328,7 @@ function registerTools(server, ctx) {
|
|
|
51304
51328
|
});
|
|
51305
51329
|
}));
|
|
51306
51330
|
server.registerTool("delete_template", {
|
|
51307
|
-
description: "Delete (archive) a template.
|
|
51331
|
+
description: "Delete (archive) a template. " + "You MUST first call this tool without confirmed=true to preview what will be deleted, " + "then show the user the template name and ask for confirmation, " + "then call again with confirmed=true only after the user explicitly agrees.",
|
|
51308
51332
|
inputSchema: strictSchema({
|
|
51309
51333
|
templateId: exports_external.string().describe("The template ID to delete"),
|
|
51310
51334
|
confirmed: exports_external.preprocess(coerceBoolean(), exports_external.boolean()).optional().describe("Set to true only after the user has explicitly confirmed deletion. Omit or set to false for the initial preview call.")
|
|
@@ -51321,7 +51345,7 @@ function registerTools(server, ctx) {
|
|
|
51321
51345
|
pending: true,
|
|
51322
51346
|
templateId: args.templateId,
|
|
51323
51347
|
templateName,
|
|
51324
|
-
message: `⚠️ You are about to delete template "${templateName}".
|
|
51348
|
+
message: `⚠️ You are about to delete template "${templateName}". Ask the user to confirm, then call delete_template again with confirmed=true.`
|
|
51325
51349
|
});
|
|
51326
51350
|
}
|
|
51327
51351
|
await ctx.client.template.delete(args.templateId);
|
|
@@ -51364,98 +51388,14 @@ function registerTools(server, ctx) {
|
|
|
51364
51388
|
message: `Version ${version2.version} published for template ${templateId}.`
|
|
51365
51389
|
});
|
|
51366
51390
|
}));
|
|
51367
|
-
server.registerTool("list_template_workflows", {
|
|
51368
|
-
description: "List all workflows linked to a template.",
|
|
51369
|
-
inputSchema: strictSchema({
|
|
51370
|
-
templateId: exports_external.string().describe("The template ID")
|
|
51371
|
-
}),
|
|
51372
|
-
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true }
|
|
51373
|
-
}, withErrorHandling("list_template_workflows", async (args) => {
|
|
51374
|
-
const workflows = await ctx.client.template.listWorkflows(args.templateId);
|
|
51375
|
-
return jsonResult({ workflows, count: workflows.length });
|
|
51376
|
-
}));
|
|
51377
|
-
server.registerTool("link_workflows_to_template", {
|
|
51378
|
-
description: "Link workflows to a template. Linking applies the template's latest version config to the workflows. " + "Without force, fails if any workflow is already linked to a different template. With force=true, relinks them. " + "You MUST first call without confirmed=true to preview, then ask the user for confirmation, " + "then call again with confirmed=true.",
|
|
51379
|
-
inputSchema: strictSchema({
|
|
51380
|
-
templateId: exports_external.string().describe("The template ID to link workflows to"),
|
|
51381
|
-
workflowIds: exports_external.preprocess(coerceArray(), exports_external.array(exports_external.string())).describe("Array of workflow IDs to link"),
|
|
51382
|
-
force: exports_external.preprocess(coerceBoolean(), exports_external.boolean()).optional().describe("If true, relink workflows already linked to another template"),
|
|
51383
|
-
confirmed: exports_external.preprocess(coerceBoolean(), exports_external.boolean()).optional().describe("Set to true only after user confirms. Omit for preview.")
|
|
51384
|
-
}),
|
|
51385
|
-
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false }
|
|
51386
|
-
}, withErrorHandling("link_workflows_to_template", async (args) => {
|
|
51387
|
-
if (!args.confirmed) {
|
|
51388
|
-
const forceNote = args.force ? " Workflows already linked to other templates will be relinked (force=true)." : " Will fail if any workflow is already linked to a different template.";
|
|
51389
|
-
return jsonResult({
|
|
51390
|
-
pending: true,
|
|
51391
|
-
templateId: args.templateId,
|
|
51392
|
-
workflowIds: args.workflowIds,
|
|
51393
|
-
force: !!args.force,
|
|
51394
|
-
message: `⚠️ You are about to link ${args.workflowIds.length} workflow(s) to template ${args.templateId}. This will apply the template's latest version config to these workflows.${forceNote} Ask the user to confirm, then call again with confirmed=true.`
|
|
51395
|
-
});
|
|
51396
|
-
}
|
|
51397
|
-
const result = await ctx.client.template.linkWorkflows(args.templateId, {
|
|
51398
|
-
workflowIds: args.workflowIds,
|
|
51399
|
-
...args.force != null && { force: args.force }
|
|
51400
|
-
});
|
|
51401
|
-
return jsonResult({
|
|
51402
|
-
success: true,
|
|
51403
|
-
result,
|
|
51404
|
-
message: `Linked ${args.workflowIds.length} workflow(s) to template ${args.templateId}.`
|
|
51405
|
-
});
|
|
51406
|
-
}));
|
|
51407
|
-
server.registerTool("unlink_workflows_from_template", {
|
|
51408
|
-
description: "Unlink workflows from a template. Workflows keep their current config but are no longer associated with the template. " + "You MUST first call without confirmed=true to preview, then ask the user for confirmation, " + "then call again with confirmed=true.",
|
|
51409
|
-
inputSchema: strictSchema({
|
|
51410
|
-
templateId: exports_external.string().describe("The template ID to unlink workflows from"),
|
|
51411
|
-
workflowIds: exports_external.preprocess(coerceArray(), exports_external.array(exports_external.string())).describe("Array of workflow IDs to unlink"),
|
|
51412
|
-
confirmed: exports_external.preprocess(coerceBoolean(), exports_external.boolean()).optional().describe("Set to true only after user confirms. Omit for preview.")
|
|
51413
|
-
}),
|
|
51414
|
-
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false }
|
|
51415
|
-
}, withErrorHandling("unlink_workflows_from_template", async (args) => {
|
|
51416
|
-
if (!args.confirmed) {
|
|
51417
|
-
return jsonResult({
|
|
51418
|
-
pending: true,
|
|
51419
|
-
templateId: args.templateId,
|
|
51420
|
-
workflowIds: args.workflowIds,
|
|
51421
|
-
message: `⚠️ You are about to unlink ${args.workflowIds.length} workflow(s) from template ${args.templateId}. Workflows will keep their current config. Ask the user to confirm, then call again with confirmed=true.`
|
|
51422
|
-
});
|
|
51423
|
-
}
|
|
51424
|
-
const result = await ctx.client.template.unlinkWorkflows(args.templateId, {
|
|
51425
|
-
workflowIds: args.workflowIds
|
|
51426
|
-
});
|
|
51427
|
-
return jsonResult({
|
|
51428
|
-
success: true,
|
|
51429
|
-
result,
|
|
51430
|
-
message: `Unlinked ${args.workflowIds.length} workflow(s) from template ${args.templateId}.`
|
|
51431
|
-
});
|
|
51432
|
-
}));
|
|
51433
|
-
server.registerTool("apply_template_update", {
|
|
51434
|
-
description: "Apply a specific template version to workflows. Updates the workflows' config (prompt, schema, notifications) to match the specified version.",
|
|
51435
|
-
inputSchema: strictSchema({
|
|
51436
|
-
templateId: exports_external.string().describe("The template ID"),
|
|
51437
|
-
targetVersion: exports_external.preprocess(coerceNumber(), exports_external.number().int().min(1)).describe("Version number to apply"),
|
|
51438
|
-
workflowIds: exports_external.preprocess(coerceArray(), exports_external.array(exports_external.string())).describe("Array of workflow IDs to update (max 100)")
|
|
51439
|
-
}),
|
|
51440
|
-
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false }
|
|
51441
|
-
}, withErrorHandling("apply_template_update", async (args) => {
|
|
51442
|
-
const result = await ctx.client.template.applyUpdate(args.templateId, {
|
|
51443
|
-
targetVersion: args.targetVersion,
|
|
51444
|
-
workflowIds: args.workflowIds
|
|
51445
|
-
});
|
|
51446
|
-
return jsonResult({
|
|
51447
|
-
success: true,
|
|
51448
|
-
result,
|
|
51449
|
-
message: `Applied version ${args.targetVersion} to ${args.workflowIds.length} workflow(s).`
|
|
51450
|
-
});
|
|
51451
|
-
}));
|
|
51452
51391
|
server.registerTool("save_workflow_as_template", {
|
|
51453
|
-
description: "Create a template from an existing workflow's configuration (prompt, schema, notifications). " + "Provide 'name' to create a new template, or 'templateId' to add a new version to an existing template.",
|
|
51392
|
+
description: "Create a template from an existing workflow's configuration (prompt, schema, notifications). " + "Provide 'name' to create a new template, or 'templateId' to add a new version to an existing template. " + "Use 'includeParts' to save only specific parts of the configuration.",
|
|
51454
51393
|
inputSchema: strictSchema({
|
|
51455
51394
|
workflowId: exports_external.string().describe("Source workflow ID to extract config from"),
|
|
51456
51395
|
name: exports_external.string().optional().describe("Name for the new template (required if templateId is not set)"),
|
|
51457
51396
|
description: exports_external.string().optional().describe("Description for the new template"),
|
|
51458
|
-
templateId: exports_external.string().optional().describe("Existing template ID to add a new version to (mutually exclusive with name)")
|
|
51397
|
+
templateId: exports_external.string().optional().describe("Existing template ID to add a new version to (mutually exclusive with name)"),
|
|
51398
|
+
includeParts: exports_external.preprocess(coerceArray(), exports_external.array(exports_external.enum(["prompt", "schema", "notifications"])).optional()).describe("Which parts of the workflow config to include. Omit to include all. At least 1 required if provided.")
|
|
51459
51399
|
}),
|
|
51460
51400
|
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false }
|
|
51461
51401
|
}, withErrorHandling("save_workflow_as_template", async (args) => {
|
|
@@ -51463,7 +51403,8 @@ function registerTools(server, ctx) {
|
|
|
51463
51403
|
workflowId: args.workflowId,
|
|
51464
51404
|
...args.name != null && { name: args.name },
|
|
51465
51405
|
...args.description != null && { description: args.description },
|
|
51466
|
-
...args.templateId != null && { templateId: args.templateId }
|
|
51406
|
+
...args.templateId != null && { templateId: args.templateId },
|
|
51407
|
+
...args.includeParts != null && { includeParts: args.includeParts }
|
|
51467
51408
|
});
|
|
51468
51409
|
return jsonResult({
|
|
51469
51410
|
success: true,
|
|
@@ -51503,7 +51444,7 @@ var package_default;
|
|
|
51503
51444
|
var init_package = __esm(() => {
|
|
51504
51445
|
package_default = {
|
|
51505
51446
|
name: "@kadoa/mcp",
|
|
51506
|
-
version: "0.4.3-rc.
|
|
51447
|
+
version: "0.4.3-rc.3",
|
|
51507
51448
|
description: "Kadoa MCP Server — manage workflows from Claude Desktop, Cursor, and other MCP clients",
|
|
51508
51449
|
type: "module",
|
|
51509
51450
|
main: "dist/index.js",
|
|
@@ -51527,7 +51468,7 @@ var init_package = __esm(() => {
|
|
|
51527
51468
|
prepublishOnly: "bun run check-types && bun run test:unit && bun run build"
|
|
51528
51469
|
},
|
|
51529
51470
|
dependencies: {
|
|
51530
|
-
"@kadoa/node-sdk": "^0.
|
|
51471
|
+
"@kadoa/node-sdk": "^0.28.0",
|
|
51531
51472
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
51532
51473
|
express: "^5.2.1",
|
|
51533
51474
|
ioredis: "^5.6.1",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kadoa/mcp",
|
|
3
|
-
"version": "0.4.3-rc.
|
|
3
|
+
"version": "0.4.3-rc.3",
|
|
4
4
|
"description": "Kadoa MCP Server — manage workflows from Claude Desktop, Cursor, and other MCP clients",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"prepublishOnly": "bun run check-types && bun run test:unit && bun run build"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@kadoa/node-sdk": "^0.
|
|
27
|
+
"@kadoa/node-sdk": "^0.28.0",
|
|
28
28
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
29
29
|
"express": "^5.2.1",
|
|
30
30
|
"ioredis": "^5.6.1",
|