@kadoa/mcp 0.5.17 → 0.5.18
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/README.md +53 -2
- package/dist/index.js +727 -22
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -64,7 +64,14 @@ Point your client to `https://mcp.kadoa.com/mcp` with OAuth authentication.
|
|
|
64
64
|
| `scrape` | Immediately fetch one URL as markdown or raw HTML (shown only for enabled workspaces) |
|
|
65
65
|
| `create_workflow` | Create an agentic navigation workflow from a prompt |
|
|
66
66
|
| `list_workflows` | List all workflows with status |
|
|
67
|
-
| `get_workflow` | Get
|
|
67
|
+
| `get_workflow` | Get canonical intent, Assistant/session, template ownership, run health, schedule, location, monitoring, and validation details |
|
|
68
|
+
| `request_workflow_update` | Ask the workflow Assistant to change extraction intent, navigation, sourcing, pagination, or generated behavior without changing the workflow ID |
|
|
69
|
+
| `get_workflow_assistant` | Get the workflow Assistant's current activity and any pending clarification question |
|
|
70
|
+
| `answer_workflow_assistant_question` | Answer the workflow Assistant's current clarification question and resume it |
|
|
71
|
+
| `interrupt_workflow_assistant` | Safely interrupt active Assistant work without pausing the workflow schedule |
|
|
72
|
+
| `resume_workflow_assistant` | Resume an idle/interrupted Lighthouse or Julie session with its persisted persona |
|
|
73
|
+
| `stop_workflow_assistant` | Stop active Assistant work without deleting or replacing the workflow |
|
|
74
|
+
| `get_workflow_strategy` | Get the current customer-safe extraction/build strategy for an Assistant or custom-script workflow |
|
|
68
75
|
| `get_workflow_history` | Get the workflow's configuration revision history (audit log) — who changed it, when, from which channel, and a `changedFields` summary per revision |
|
|
69
76
|
| `list_workflow_runs` | List a workflow's execution run history (status, start/finish, record count, errors); filter by outcome and paginate |
|
|
70
77
|
| `run_workflow` | Execute a workflow |
|
|
@@ -72,7 +79,7 @@ Point your client to `https://mcp.kadoa.com/mcp` with OAuth authentication.
|
|
|
72
79
|
| `delete_workflow` | Delete a workflow |
|
|
73
80
|
| `approve_workflow` | Approve and activate a workflow |
|
|
74
81
|
| `pause_workflow` | Pause an active workflow |
|
|
75
|
-
| `update_workflow` | Update
|
|
82
|
+
| `update_workflow` | Update deterministic configuration, including location, schedule timezone, monitoring conditions, and unlimited rows |
|
|
76
83
|
| `whoami` | Show current user details, auth method, and team memberships |
|
|
77
84
|
| `team_list` | List all teams you belong to and see which is active |
|
|
78
85
|
| `team_switch` | Switch the active team by name or ID |
|
|
@@ -144,6 +151,50 @@ Claude calls run_workflow and waits for completion, then fetches
|
|
|
144
151
|
the latest data with fetch_data so you can verify the changes.
|
|
145
152
|
```
|
|
146
153
|
|
|
154
|
+
### Update deterministic workflow settings
|
|
155
|
+
|
|
156
|
+
```
|
|
157
|
+
> You: Run wf_abc123 from the US at 8 AM New York time on weekdays,
|
|
158
|
+
alert when price changes above 100, and remove its row limit.
|
|
159
|
+
|
|
160
|
+
Claude calls get_workflow first because monitoring is a replacement setting,
|
|
161
|
+
then calls update_workflow with a manual US location, a weekday cron schedule
|
|
162
|
+
in `America/New_York`, monitoring fields/conditions, and `limit: null` for all
|
|
163
|
+
rows.
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Update an Assistant-built workflow without replacing it
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
> You: Update workflow wf_abc123 to follow pagination and extract the detail-page URL.
|
|
170
|
+
|
|
171
|
+
Claude calls request_workflow_update. Kadoa keeps wf_abc123 and returns the
|
|
172
|
+
Assistant session, thread, and job identifiers.
|
|
173
|
+
|
|
174
|
+
> You: Does Kadoa need anything from me?
|
|
175
|
+
|
|
176
|
+
Claude calls get_workflow_assistant. If a clarification is pending, Claude
|
|
177
|
+
shows the question and calls answer_workflow_assistant_question with your
|
|
178
|
+
answer. It does not poll or sleep-wait for the Assistant.
|
|
179
|
+
|
|
180
|
+
> You: How does this workflow extract the data now?
|
|
181
|
+
|
|
182
|
+
Claude calls get_workflow_strategy and shows the customer-safe sourcing,
|
|
183
|
+
navigation, and extraction approach.
|
|
184
|
+
|
|
185
|
+
> You: Interrupt the Assistant for now, then resume it later.
|
|
186
|
+
|
|
187
|
+
Claude calls interrupt_workflow_assistant. When asked later, it calls
|
|
188
|
+
resume_workflow_assistant, which preserves whether the session is Lighthouse
|
|
189
|
+
or Julie. stop_workflow_assistant cancels active Assistant work without
|
|
190
|
+
pausing or deleting the workflow itself.
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Use `update_workflow` for deterministic metadata such as name, schedule, tags,
|
|
194
|
+
and limits. Use template version/apply tools for template-controlled parts.
|
|
195
|
+
Never delete and recreate a workflow to work around an Assistant update—the
|
|
196
|
+
workflow ID is part of downstream integrations and history.
|
|
197
|
+
|
|
147
198
|
### Monitor and clean up
|
|
148
199
|
|
|
149
200
|
```
|
package/dist/index.js
CHANGED
|
@@ -45666,6 +45666,7 @@ function createAxiosInstance(params) {
|
|
|
45666
45666
|
}
|
|
45667
45667
|
function createClientDomains(params) {
|
|
45668
45668
|
const { client } = params;
|
|
45669
|
+
const assistantService = new AssistantService(client.apis.agent);
|
|
45669
45670
|
const changesService = new ChangesService(client);
|
|
45670
45671
|
const userService = new UserService(client);
|
|
45671
45672
|
const dataFetcherService = new DataFetcherService(client.apis.workflows);
|
|
@@ -45690,6 +45691,7 @@ function createClientDomains(params) {
|
|
|
45690
45691
|
const validation = createValidationDomain(coreService, rulesService);
|
|
45691
45692
|
const crawler = createCrawlerDomain(client);
|
|
45692
45693
|
return {
|
|
45694
|
+
assistant: assistantService,
|
|
45693
45695
|
changes: changesService,
|
|
45694
45696
|
extractionBuilderService,
|
|
45695
45697
|
extraction: extractionService,
|
|
@@ -45741,7 +45743,59 @@ function createNotificationDomain(params) {
|
|
|
45741
45743
|
}
|
|
45742
45744
|
};
|
|
45743
45745
|
}
|
|
45744
|
-
var import_debug, __require2,
|
|
45746
|
+
var import_debug, __require2, FREEFORM_ASSISTANT_ANSWER_KEY = "_freeform", KadoaErrorCode, _KadoaSdkException, KadoaSdkException, ERROR_MESSAGES, KadoaHttpException, AssistantService = class {
|
|
45747
|
+
constructor(agentApi) {
|
|
45748
|
+
this.agentApi = agentApi;
|
|
45749
|
+
}
|
|
45750
|
+
async requestWorkflowUpdate(workflowId, input) {
|
|
45751
|
+
const response = await this.agentApi.v5AgentWorkflowAssistantMessage({
|
|
45752
|
+
workflowId,
|
|
45753
|
+
workflowAssistantMessageRequest: {
|
|
45754
|
+
prompt: input.instructions,
|
|
45755
|
+
...input.threadId != null && { threadId: input.threadId }
|
|
45756
|
+
}
|
|
45757
|
+
});
|
|
45758
|
+
const data = response.data?.data;
|
|
45759
|
+
if (!data?.workflowId || !data.sessionId || !data.threadId) {
|
|
45760
|
+
throw new KadoaSdkException("Workflow Assistant update response is missing required identifiers", {
|
|
45761
|
+
code: "INTERNAL_ERROR",
|
|
45762
|
+
details: { workflowId, response: response.data }
|
|
45763
|
+
});
|
|
45764
|
+
}
|
|
45765
|
+
return data;
|
|
45766
|
+
}
|
|
45767
|
+
async getPauseState(sessionId) {
|
|
45768
|
+
const response = await this.agentApi.v5AgentPauseState({ sessionId });
|
|
45769
|
+
return response.data.data;
|
|
45770
|
+
}
|
|
45771
|
+
async answerQuestion(input) {
|
|
45772
|
+
const response = await this.agentApi.v5AgentAnswer({
|
|
45773
|
+
assistantAnswerRequest: {
|
|
45774
|
+
sessionId: input.sessionId,
|
|
45775
|
+
questionId: input.questionId,
|
|
45776
|
+
answers: input.answers,
|
|
45777
|
+
...input.threadId != null && { threadId: input.threadId }
|
|
45778
|
+
}
|
|
45779
|
+
});
|
|
45780
|
+
return response.data.data;
|
|
45781
|
+
}
|
|
45782
|
+
async getStrategy(sessionId) {
|
|
45783
|
+
const response = await this.agentApi.v5AgentStrategy({ sessionId });
|
|
45784
|
+
return response.data.data.strategy;
|
|
45785
|
+
}
|
|
45786
|
+
async interrupt(sessionId) {
|
|
45787
|
+
const response = await this.agentApi.v5AgentInterrupt({ sessionId });
|
|
45788
|
+
return response.data.data;
|
|
45789
|
+
}
|
|
45790
|
+
async resume(sessionId) {
|
|
45791
|
+
const response = await this.agentApi.v5AgentResume({ sessionId });
|
|
45792
|
+
return response.data.data;
|
|
45793
|
+
}
|
|
45794
|
+
async stop(sessionId) {
|
|
45795
|
+
const response = await this.agentApi.v5AgentStop({ sessionId });
|
|
45796
|
+
return response.data.data;
|
|
45797
|
+
}
|
|
45798
|
+
}, ChangeDifferenceType, createLogger = (namespace) => import_debug.default(`kadoa:${namespace}`), logger, debug, ChangesService = class {
|
|
45745
45799
|
constructor(client) {
|
|
45746
45800
|
this.client = client;
|
|
45747
45801
|
}
|
|
@@ -45804,12 +45858,206 @@ var import_debug, __require2, ChangeDifferenceType, KadoaErrorCode, _KadoaSdkExc
|
|
|
45804
45858
|
return needsSerialization ? JSON.stringify(value !== undefined ? value : {}, replaceWithSerializableTypeIfNeeded) : value || "";
|
|
45805
45859
|
}, toPathString = function(url3) {
|
|
45806
45860
|
return url3.pathname + url3.search + url3.hash;
|
|
45807
|
-
}, createRequestFunction = function(axiosArgs,
|
|
45808
|
-
return (axios2 =
|
|
45861
|
+
}, createRequestFunction = function(axiosArgs, globalAxios12, BASE_PATH2, configuration) {
|
|
45862
|
+
return (axios2 = globalAxios12, basePath = BASE_PATH2) => {
|
|
45809
45863
|
const axiosRequestArgs = { ...axiosArgs.options, url: (axios2.defaults.baseURL ? "" : configuration?.basePath ?? basePath) + axiosArgs.url };
|
|
45810
45864
|
return axios2.request(axiosRequestArgs);
|
|
45811
45865
|
};
|
|
45812
|
-
},
|
|
45866
|
+
}, AgentApiAxiosParamCreator = function(configuration) {
|
|
45867
|
+
return {
|
|
45868
|
+
v5AgentAnswer: async (assistantAnswerRequest, options = {}) => {
|
|
45869
|
+
assertParamExists("v5AgentAnswer", "assistantAnswerRequest", assistantAnswerRequest);
|
|
45870
|
+
const localVarPath = `/v5/agent/answer`;
|
|
45871
|
+
const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
|
|
45872
|
+
let baseOptions;
|
|
45873
|
+
if (configuration) {
|
|
45874
|
+
baseOptions = configuration.baseOptions;
|
|
45875
|
+
}
|
|
45876
|
+
const localVarRequestOptions = { method: "POST", ...baseOptions, ...options };
|
|
45877
|
+
const localVarHeaderParameter = {};
|
|
45878
|
+
const localVarQueryParameter = {};
|
|
45879
|
+
localVarHeaderParameter["Content-Type"] = "application/json";
|
|
45880
|
+
localVarHeaderParameter["Accept"] = "application/json";
|
|
45881
|
+
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
|
45882
|
+
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
|
45883
|
+
localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers };
|
|
45884
|
+
localVarRequestOptions.data = serializeDataIfNeeded(assistantAnswerRequest, localVarRequestOptions, configuration);
|
|
45885
|
+
return {
|
|
45886
|
+
url: toPathString(localVarUrlObj),
|
|
45887
|
+
options: localVarRequestOptions
|
|
45888
|
+
};
|
|
45889
|
+
},
|
|
45890
|
+
v5AgentInterrupt: async (sessionId, options = {}) => {
|
|
45891
|
+
assertParamExists("v5AgentInterrupt", "sessionId", sessionId);
|
|
45892
|
+
const localVarPath = `/v5/agent/{sessionId}/interrupt`.replace(`{${"sessionId"}}`, encodeURIComponent(String(sessionId)));
|
|
45893
|
+
const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
|
|
45894
|
+
let baseOptions;
|
|
45895
|
+
if (configuration) {
|
|
45896
|
+
baseOptions = configuration.baseOptions;
|
|
45897
|
+
}
|
|
45898
|
+
const localVarRequestOptions = { method: "POST", ...baseOptions, ...options };
|
|
45899
|
+
const localVarHeaderParameter = {};
|
|
45900
|
+
const localVarQueryParameter = {};
|
|
45901
|
+
localVarHeaderParameter["Accept"] = "application/json";
|
|
45902
|
+
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
|
45903
|
+
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
|
45904
|
+
localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers };
|
|
45905
|
+
return {
|
|
45906
|
+
url: toPathString(localVarUrlObj),
|
|
45907
|
+
options: localVarRequestOptions
|
|
45908
|
+
};
|
|
45909
|
+
},
|
|
45910
|
+
v5AgentPauseState: async (sessionId, options = {}) => {
|
|
45911
|
+
assertParamExists("v5AgentPauseState", "sessionId", sessionId);
|
|
45912
|
+
const localVarPath = `/v5/agent/{sessionId}/pause-state`.replace(`{${"sessionId"}}`, encodeURIComponent(String(sessionId)));
|
|
45913
|
+
const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
|
|
45914
|
+
let baseOptions;
|
|
45915
|
+
if (configuration) {
|
|
45916
|
+
baseOptions = configuration.baseOptions;
|
|
45917
|
+
}
|
|
45918
|
+
const localVarRequestOptions = { method: "GET", ...baseOptions, ...options };
|
|
45919
|
+
const localVarHeaderParameter = {};
|
|
45920
|
+
const localVarQueryParameter = {};
|
|
45921
|
+
localVarHeaderParameter["Accept"] = "application/json";
|
|
45922
|
+
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
|
45923
|
+
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
|
45924
|
+
localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers };
|
|
45925
|
+
return {
|
|
45926
|
+
url: toPathString(localVarUrlObj),
|
|
45927
|
+
options: localVarRequestOptions
|
|
45928
|
+
};
|
|
45929
|
+
},
|
|
45930
|
+
v5AgentResume: async (sessionId, options = {}) => {
|
|
45931
|
+
assertParamExists("v5AgentResume", "sessionId", sessionId);
|
|
45932
|
+
const localVarPath = `/v5/agent/{sessionId}/resume`.replace(`{${"sessionId"}}`, encodeURIComponent(String(sessionId)));
|
|
45933
|
+
const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
|
|
45934
|
+
let baseOptions;
|
|
45935
|
+
if (configuration) {
|
|
45936
|
+
baseOptions = configuration.baseOptions;
|
|
45937
|
+
}
|
|
45938
|
+
const localVarRequestOptions = { method: "POST", ...baseOptions, ...options };
|
|
45939
|
+
const localVarHeaderParameter = {};
|
|
45940
|
+
const localVarQueryParameter = {};
|
|
45941
|
+
localVarHeaderParameter["Accept"] = "application/json";
|
|
45942
|
+
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
|
45943
|
+
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
|
45944
|
+
localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers };
|
|
45945
|
+
return {
|
|
45946
|
+
url: toPathString(localVarUrlObj),
|
|
45947
|
+
options: localVarRequestOptions
|
|
45948
|
+
};
|
|
45949
|
+
},
|
|
45950
|
+
v5AgentStop: async (sessionId, options = {}) => {
|
|
45951
|
+
assertParamExists("v5AgentStop", "sessionId", sessionId);
|
|
45952
|
+
const localVarPath = `/v5/agent/{sessionId}/stop`.replace(`{${"sessionId"}}`, encodeURIComponent(String(sessionId)));
|
|
45953
|
+
const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
|
|
45954
|
+
let baseOptions;
|
|
45955
|
+
if (configuration) {
|
|
45956
|
+
baseOptions = configuration.baseOptions;
|
|
45957
|
+
}
|
|
45958
|
+
const localVarRequestOptions = { method: "POST", ...baseOptions, ...options };
|
|
45959
|
+
const localVarHeaderParameter = {};
|
|
45960
|
+
const localVarQueryParameter = {};
|
|
45961
|
+
localVarHeaderParameter["Accept"] = "application/json";
|
|
45962
|
+
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
|
45963
|
+
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
|
45964
|
+
localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers };
|
|
45965
|
+
return {
|
|
45966
|
+
url: toPathString(localVarUrlObj),
|
|
45967
|
+
options: localVarRequestOptions
|
|
45968
|
+
};
|
|
45969
|
+
},
|
|
45970
|
+
v5AgentStrategy: async (sessionId, options = {}) => {
|
|
45971
|
+
assertParamExists("v5AgentStrategy", "sessionId", sessionId);
|
|
45972
|
+
const localVarPath = `/v5/agent/data/{sessionId}/strategy`.replace(`{${"sessionId"}}`, encodeURIComponent(String(sessionId)));
|
|
45973
|
+
const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
|
|
45974
|
+
let baseOptions;
|
|
45975
|
+
if (configuration) {
|
|
45976
|
+
baseOptions = configuration.baseOptions;
|
|
45977
|
+
}
|
|
45978
|
+
const localVarRequestOptions = { method: "GET", ...baseOptions, ...options };
|
|
45979
|
+
const localVarHeaderParameter = {};
|
|
45980
|
+
const localVarQueryParameter = {};
|
|
45981
|
+
localVarHeaderParameter["Accept"] = "application/json";
|
|
45982
|
+
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
|
45983
|
+
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
|
45984
|
+
localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers };
|
|
45985
|
+
return {
|
|
45986
|
+
url: toPathString(localVarUrlObj),
|
|
45987
|
+
options: localVarRequestOptions
|
|
45988
|
+
};
|
|
45989
|
+
},
|
|
45990
|
+
v5AgentWorkflowAssistantMessage: async (workflowId, workflowAssistantMessageRequest, options = {}) => {
|
|
45991
|
+
assertParamExists("v5AgentWorkflowAssistantMessage", "workflowId", workflowId);
|
|
45992
|
+
assertParamExists("v5AgentWorkflowAssistantMessage", "workflowAssistantMessageRequest", workflowAssistantMessageRequest);
|
|
45993
|
+
const localVarPath = `/v5/agent/workflows/{workflowId}/assistant/messages`.replace(`{${"workflowId"}}`, encodeURIComponent(String(workflowId)));
|
|
45994
|
+
const localVarUrlObj = new URL$1(localVarPath, DUMMY_BASE_URL);
|
|
45995
|
+
let baseOptions;
|
|
45996
|
+
if (configuration) {
|
|
45997
|
+
baseOptions = configuration.baseOptions;
|
|
45998
|
+
}
|
|
45999
|
+
const localVarRequestOptions = { method: "POST", ...baseOptions, ...options };
|
|
46000
|
+
const localVarHeaderParameter = {};
|
|
46001
|
+
const localVarQueryParameter = {};
|
|
46002
|
+
localVarHeaderParameter["Content-Type"] = "application/json";
|
|
46003
|
+
localVarHeaderParameter["Accept"] = "application/json";
|
|
46004
|
+
setSearchParams(localVarUrlObj, localVarQueryParameter);
|
|
46005
|
+
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
|
46006
|
+
localVarRequestOptions.headers = { ...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers };
|
|
46007
|
+
localVarRequestOptions.data = serializeDataIfNeeded(workflowAssistantMessageRequest, localVarRequestOptions, configuration);
|
|
46008
|
+
return {
|
|
46009
|
+
url: toPathString(localVarUrlObj),
|
|
46010
|
+
options: localVarRequestOptions
|
|
46011
|
+
};
|
|
46012
|
+
}
|
|
46013
|
+
};
|
|
46014
|
+
}, AgentApiFp = function(configuration) {
|
|
46015
|
+
const localVarAxiosParamCreator = AgentApiAxiosParamCreator(configuration);
|
|
46016
|
+
return {
|
|
46017
|
+
async v5AgentAnswer(assistantAnswerRequest, options) {
|
|
46018
|
+
const localVarAxiosArgs = await localVarAxiosParamCreator.v5AgentAnswer(assistantAnswerRequest, options);
|
|
46019
|
+
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
|
|
46020
|
+
const localVarOperationServerBasePath = operationServerMap["AgentApi.v5AgentAnswer"]?.[localVarOperationServerIndex]?.url;
|
|
46021
|
+
return (axios2, basePath) => createRequestFunction(localVarAxiosArgs, axios_default, BASE_PATH, configuration)(axios2, localVarOperationServerBasePath || basePath);
|
|
46022
|
+
},
|
|
46023
|
+
async v5AgentInterrupt(sessionId, options) {
|
|
46024
|
+
const localVarAxiosArgs = await localVarAxiosParamCreator.v5AgentInterrupt(sessionId, options);
|
|
46025
|
+
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
|
|
46026
|
+
const localVarOperationServerBasePath = operationServerMap["AgentApi.v5AgentInterrupt"]?.[localVarOperationServerIndex]?.url;
|
|
46027
|
+
return (axios2, basePath) => createRequestFunction(localVarAxiosArgs, axios_default, BASE_PATH, configuration)(axios2, localVarOperationServerBasePath || basePath);
|
|
46028
|
+
},
|
|
46029
|
+
async v5AgentPauseState(sessionId, options) {
|
|
46030
|
+
const localVarAxiosArgs = await localVarAxiosParamCreator.v5AgentPauseState(sessionId, options);
|
|
46031
|
+
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
|
|
46032
|
+
const localVarOperationServerBasePath = operationServerMap["AgentApi.v5AgentPauseState"]?.[localVarOperationServerIndex]?.url;
|
|
46033
|
+
return (axios2, basePath) => createRequestFunction(localVarAxiosArgs, axios_default, BASE_PATH, configuration)(axios2, localVarOperationServerBasePath || basePath);
|
|
46034
|
+
},
|
|
46035
|
+
async v5AgentResume(sessionId, options) {
|
|
46036
|
+
const localVarAxiosArgs = await localVarAxiosParamCreator.v5AgentResume(sessionId, options);
|
|
46037
|
+
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
|
|
46038
|
+
const localVarOperationServerBasePath = operationServerMap["AgentApi.v5AgentResume"]?.[localVarOperationServerIndex]?.url;
|
|
46039
|
+
return (axios2, basePath) => createRequestFunction(localVarAxiosArgs, axios_default, BASE_PATH, configuration)(axios2, localVarOperationServerBasePath || basePath);
|
|
46040
|
+
},
|
|
46041
|
+
async v5AgentStop(sessionId, options) {
|
|
46042
|
+
const localVarAxiosArgs = await localVarAxiosParamCreator.v5AgentStop(sessionId, options);
|
|
46043
|
+
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
|
|
46044
|
+
const localVarOperationServerBasePath = operationServerMap["AgentApi.v5AgentStop"]?.[localVarOperationServerIndex]?.url;
|
|
46045
|
+
return (axios2, basePath) => createRequestFunction(localVarAxiosArgs, axios_default, BASE_PATH, configuration)(axios2, localVarOperationServerBasePath || basePath);
|
|
46046
|
+
},
|
|
46047
|
+
async v5AgentStrategy(sessionId, options) {
|
|
46048
|
+
const localVarAxiosArgs = await localVarAxiosParamCreator.v5AgentStrategy(sessionId, options);
|
|
46049
|
+
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
|
|
46050
|
+
const localVarOperationServerBasePath = operationServerMap["AgentApi.v5AgentStrategy"]?.[localVarOperationServerIndex]?.url;
|
|
46051
|
+
return (axios2, basePath) => createRequestFunction(localVarAxiosArgs, axios_default, BASE_PATH, configuration)(axios2, localVarOperationServerBasePath || basePath);
|
|
46052
|
+
},
|
|
46053
|
+
async v5AgentWorkflowAssistantMessage(workflowId, workflowAssistantMessageRequest, options) {
|
|
46054
|
+
const localVarAxiosArgs = await localVarAxiosParamCreator.v5AgentWorkflowAssistantMessage(workflowId, workflowAssistantMessageRequest, options);
|
|
46055
|
+
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
|
|
46056
|
+
const localVarOperationServerBasePath = operationServerMap["AgentApi.v5AgentWorkflowAssistantMessage"]?.[localVarOperationServerIndex]?.url;
|
|
46057
|
+
return (axios2, basePath) => createRequestFunction(localVarAxiosArgs, axios_default, BASE_PATH, configuration)(axios2, localVarOperationServerBasePath || basePath);
|
|
46058
|
+
}
|
|
46059
|
+
};
|
|
46060
|
+
}, AgentApi, CrawlerApiAxiosParamCreator = function(configuration) {
|
|
45813
46061
|
return {
|
|
45814
46062
|
v4CrawlBucketDataFilenameb64Get: async (filenameb64, contentType, cacheControl, options = {}) => {
|
|
45815
46063
|
assertParamExists("v4CrawlBucketDataFilenameb64Get", "filenameb64", filenameb64);
|
|
@@ -50028,7 +50276,7 @@ var import_debug, __require2, ChangeDifferenceType, KadoaErrorCode, _KadoaSdkExc
|
|
|
50028
50276
|
}));
|
|
50029
50277
|
return channels;
|
|
50030
50278
|
}
|
|
50031
|
-
}, PUBLIC_API_URI, WSS_API_URI, REALTIME_API_URI, SDK_VERSION = "0.
|
|
50279
|
+
}, PUBLIC_API_URI, WSS_API_URI, REALTIME_API_URI, SDK_VERSION = "0.37.1", 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 {
|
|
50032
50280
|
constructor(config2) {
|
|
50033
50281
|
this.drainingSockets = /* @__PURE__ */ new Set;
|
|
50034
50282
|
this.lastHeartbeat = Date.now();
|
|
@@ -51061,6 +51309,9 @@ var import_debug, __require2, ChangeDifferenceType, KadoaErrorCode, _KadoaSdkExc
|
|
|
51061
51309
|
}
|
|
51062
51310
|
return this.cache.get(ApiClass);
|
|
51063
51311
|
}
|
|
51312
|
+
get agent() {
|
|
51313
|
+
return this.get(AgentApi);
|
|
51314
|
+
}
|
|
51064
51315
|
get schemas() {
|
|
51065
51316
|
return this.get(SchemasApi);
|
|
51066
51317
|
}
|
|
@@ -51113,6 +51364,7 @@ var import_debug, __require2, ChangeDifferenceType, KadoaErrorCode, _KadoaSdkExc
|
|
|
51113
51364
|
});
|
|
51114
51365
|
this.apis = new ApiRegistry(this._apiKey, this._baseUrl, this._axiosInstance, headers);
|
|
51115
51366
|
const domains = createClientDomains({ client: this });
|
|
51367
|
+
this.assistant = domains.assistant;
|
|
51116
51368
|
this.changes = domains.changes;
|
|
51117
51369
|
this.user = domains.user;
|
|
51118
51370
|
this.extraction = domains.extraction;
|
|
@@ -51206,11 +51458,6 @@ var init_dist2 = __esm(() => {
|
|
|
51206
51458
|
return __require.apply(this, arguments);
|
|
51207
51459
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
51208
51460
|
});
|
|
51209
|
-
ChangeDifferenceType = {
|
|
51210
|
-
Added: "added",
|
|
51211
|
-
Removed: "removed",
|
|
51212
|
-
Changed: "changed"
|
|
51213
|
-
};
|
|
51214
51461
|
KadoaErrorCode = {
|
|
51215
51462
|
VALIDATION_ERROR: "VALIDATION_ERROR",
|
|
51216
51463
|
BAD_REQUEST: "BAD_REQUEST",
|
|
@@ -51407,6 +51654,11 @@ var init_dist2 = __esm(() => {
|
|
|
51407
51654
|
return "UNKNOWN";
|
|
51408
51655
|
}
|
|
51409
51656
|
};
|
|
51657
|
+
ChangeDifferenceType = {
|
|
51658
|
+
Added: "added",
|
|
51659
|
+
Removed: "removed",
|
|
51660
|
+
Changed: "changed"
|
|
51661
|
+
};
|
|
51410
51662
|
logger = {
|
|
51411
51663
|
changes: createLogger("changes"),
|
|
51412
51664
|
client: createLogger("client"),
|
|
@@ -51431,6 +51683,29 @@ var init_dist2 = __esm(() => {
|
|
|
51431
51683
|
}
|
|
51432
51684
|
};
|
|
51433
51685
|
operationServerMap = {};
|
|
51686
|
+
AgentApi = class extends BaseAPI {
|
|
51687
|
+
v5AgentAnswer(requestParameters, options) {
|
|
51688
|
+
return AgentApiFp(this.configuration).v5AgentAnswer(requestParameters.assistantAnswerRequest, options).then((request) => request(this.axios, this.basePath));
|
|
51689
|
+
}
|
|
51690
|
+
v5AgentInterrupt(requestParameters, options) {
|
|
51691
|
+
return AgentApiFp(this.configuration).v5AgentInterrupt(requestParameters.sessionId, options).then((request) => request(this.axios, this.basePath));
|
|
51692
|
+
}
|
|
51693
|
+
v5AgentPauseState(requestParameters, options) {
|
|
51694
|
+
return AgentApiFp(this.configuration).v5AgentPauseState(requestParameters.sessionId, options).then((request) => request(this.axios, this.basePath));
|
|
51695
|
+
}
|
|
51696
|
+
v5AgentResume(requestParameters, options) {
|
|
51697
|
+
return AgentApiFp(this.configuration).v5AgentResume(requestParameters.sessionId, options).then((request) => request(this.axios, this.basePath));
|
|
51698
|
+
}
|
|
51699
|
+
v5AgentStop(requestParameters, options) {
|
|
51700
|
+
return AgentApiFp(this.configuration).v5AgentStop(requestParameters.sessionId, options).then((request) => request(this.axios, this.basePath));
|
|
51701
|
+
}
|
|
51702
|
+
v5AgentStrategy(requestParameters, options) {
|
|
51703
|
+
return AgentApiFp(this.configuration).v5AgentStrategy(requestParameters.sessionId, options).then((request) => request(this.axios, this.basePath));
|
|
51704
|
+
}
|
|
51705
|
+
v5AgentWorkflowAssistantMessage(requestParameters, options) {
|
|
51706
|
+
return AgentApiFp(this.configuration).v5AgentWorkflowAssistantMessage(requestParameters.workflowId, requestParameters.workflowAssistantMessageRequest, options).then((request) => request(this.axios, this.basePath));
|
|
51707
|
+
}
|
|
51708
|
+
};
|
|
51434
51709
|
CrawlerApi = class extends BaseAPI {
|
|
51435
51710
|
v4CrawlBucketDataFilenameb64Get(requestParameters, options) {
|
|
51436
51711
|
return CrawlerApiFp(this.configuration).v4CrawlBucketDataFilenameb64Get(requestParameters.filenameb64, requestParameters.contentType, requestParameters.cacheControl, options).then((request) => request(this.axios, this.basePath));
|
|
@@ -52175,6 +52450,67 @@ function mapRunStatus(state) {
|
|
|
52175
52450
|
return state ?? "unknown";
|
|
52176
52451
|
}
|
|
52177
52452
|
}
|
|
52453
|
+
function isAssistantSessionResumable(status) {
|
|
52454
|
+
return status != null && RESUMABLE_ASSISTANT_STATUSES.has(status);
|
|
52455
|
+
}
|
|
52456
|
+
function deriveAssistantActivity(input) {
|
|
52457
|
+
const { pauseState } = input;
|
|
52458
|
+
if (pauseState?.pendingQuestion && pauseState.pause?.status === "active")
|
|
52459
|
+
return "waiting_for_input";
|
|
52460
|
+
if (pauseState?.pause?.status === "resuming")
|
|
52461
|
+
return "working";
|
|
52462
|
+
if (pauseState?.pause?.reason === "interrupt" && pauseState.pause.status === "active")
|
|
52463
|
+
return "interrupted";
|
|
52464
|
+
if (!input.hasSession)
|
|
52465
|
+
return input.assistantEligible ? "not_started" : "unsupported";
|
|
52466
|
+
switch (input.sessionStatus) {
|
|
52467
|
+
case "pending":
|
|
52468
|
+
case "created":
|
|
52469
|
+
case "active":
|
|
52470
|
+
return "working";
|
|
52471
|
+
case "idle":
|
|
52472
|
+
case "inactive":
|
|
52473
|
+
return "idle";
|
|
52474
|
+
case "interrupted":
|
|
52475
|
+
return "interrupted";
|
|
52476
|
+
case "failed":
|
|
52477
|
+
case "errored":
|
|
52478
|
+
return "failed";
|
|
52479
|
+
case "aborted":
|
|
52480
|
+
case "timed_out":
|
|
52481
|
+
return "closed";
|
|
52482
|
+
default:
|
|
52483
|
+
return "unknown";
|
|
52484
|
+
}
|
|
52485
|
+
}
|
|
52486
|
+
function assistantControlTransitionError(input) {
|
|
52487
|
+
const { action, sessionStatus, pauseState } = input;
|
|
52488
|
+
const pause = pauseState.pause;
|
|
52489
|
+
if (CLOSED_ASSISTANT_STATUSES.has(sessionStatus ?? "")) {
|
|
52490
|
+
const verb = action === "resume" ? "resumed" : action === "interrupt" ? "interrupted" : "stopped";
|
|
52491
|
+
return `The Assistant session is closed (${sessionStatus}) and cannot be ${verb}. Request a new workflow update to start a resumable session.`;
|
|
52492
|
+
}
|
|
52493
|
+
if (action === "resume") {
|
|
52494
|
+
if (pause?.status === "resuming")
|
|
52495
|
+
return "The Assistant session is already resuming.";
|
|
52496
|
+
if (pause?.status === "active" && pause.reason === "question") {
|
|
52497
|
+
return "The Assistant is waiting for a clarification answer. Use answer_workflow_assistant_question instead of resume.";
|
|
52498
|
+
}
|
|
52499
|
+
if (pause?.status === "active" && pause.reason === "interrupt")
|
|
52500
|
+
return null;
|
|
52501
|
+
if (IDLE_ASSISTANT_STATUSES.has(sessionStatus ?? ""))
|
|
52502
|
+
return null;
|
|
52503
|
+
return `The Assistant cannot be resumed while its session status is '${sessionStatus ?? "unknown"}'.`;
|
|
52504
|
+
}
|
|
52505
|
+
if (pause?.status === "active") {
|
|
52506
|
+
if (action === "stop")
|
|
52507
|
+
return null;
|
|
52508
|
+
return pause.reason === "question" ? "The Assistant is already paused for a clarification question. Answer it or stop the session." : "The Assistant session is already interrupted.";
|
|
52509
|
+
}
|
|
52510
|
+
if (pause?.status === "resuming" || ACTIVE_ASSISTANT_STATUSES.has(sessionStatus ?? ""))
|
|
52511
|
+
return null;
|
|
52512
|
+
return `The Assistant cannot be ${action}ed while its session status is '${sessionStatus ?? "unknown"}'.`;
|
|
52513
|
+
}
|
|
52178
52514
|
function workflowDashboardUrl(workflowId) {
|
|
52179
52515
|
return `${DASHBOARD_BASE_URL}/workflow/${workflowId}`;
|
|
52180
52516
|
}
|
|
@@ -52704,7 +53040,7 @@ function registerTools(server, ctx, capabilities) {
|
|
|
52704
53040
|
});
|
|
52705
53041
|
}));
|
|
52706
53042
|
server.registerTool("get_workflow", {
|
|
52707
|
-
description: "Get
|
|
53043
|
+
description: "Get canonical workflow details, including Assistant/session linkage, extraction intent, template-controlled parts, stale-data state, job/run state, schedule timezone, location, monitoring, validation, and realtime health. For Assistant-built workflows, extractionSpec—not the legacy prompt—is authoritative.",
|
|
52708
53044
|
inputSchema: {
|
|
52709
53045
|
workflowId: exports_external.string().describe("The workflow ID")
|
|
52710
53046
|
},
|
|
@@ -52712,28 +53048,317 @@ function registerTools(server, ctx, capabilities) {
|
|
|
52712
53048
|
}, withErrorHandling("get_workflow", async (args) => {
|
|
52713
53049
|
const workflow = await ctx.client.workflow.get(args.workflowId);
|
|
52714
53050
|
const additionalData = workflow.additionalData;
|
|
53051
|
+
const extractionSpec = workflow.extractionSpec ?? null;
|
|
53052
|
+
const legacyPrompt = typeof additionalData?.userPrompt === "string" ? additionalData.userPrompt : null;
|
|
53053
|
+
const controlledParts = [
|
|
53054
|
+
workflow.templateHasPrompt && "prompt",
|
|
53055
|
+
workflow.templateHasSchema && "schema",
|
|
53056
|
+
workflow.templateHasSchemaValidationRules && "schemaValidationRules",
|
|
53057
|
+
workflow.templateHasNotifications && "notifications",
|
|
53058
|
+
workflow.templateHasFrequency && "frequency"
|
|
53059
|
+
].filter((part) => typeof part === "string");
|
|
53060
|
+
const hasTemplate = workflow.templateId != null || workflow.templateVersion != null;
|
|
53061
|
+
const isRealtime = workflow.isRealTime === true || isRealTimeInterval(workflow.updateInterval);
|
|
52715
53062
|
return jsonResult({
|
|
52716
53063
|
id: workflow.id,
|
|
52717
53064
|
name: workflow.name,
|
|
52718
53065
|
dashboardUrl: workflowDashboardUrl(workflow.id),
|
|
52719
53066
|
description: workflow.description,
|
|
52720
53067
|
status: deriveStatusLabel(workflow),
|
|
53068
|
+
state: workflow.state ?? null,
|
|
53069
|
+
displayState: workflow.displayState ?? null,
|
|
53070
|
+
runState: workflow.runState ?? null,
|
|
52721
53071
|
urls: workflow.urls,
|
|
52722
|
-
prompt:
|
|
53072
|
+
prompt: extractionSpec ? null : legacyPrompt,
|
|
53073
|
+
intentSource: extractionSpec ? "extraction_spec" : legacyPrompt ? "legacy_prompt" : null,
|
|
53074
|
+
extractionSpec,
|
|
52723
53075
|
entity: workflow.entity,
|
|
52724
53076
|
schema: workflow.schema,
|
|
52725
53077
|
navigationMode: workflow.navigationMode,
|
|
53078
|
+
dataStale: workflow.dataStale ?? false,
|
|
53079
|
+
assistantEligible: workflow.assistantEligible === true,
|
|
53080
|
+
assistantSessionId: workflow.assistantSessionId ?? null,
|
|
53081
|
+
assistantThreadId: workflow.assistantThreadId ?? null,
|
|
53082
|
+
assistantSessionStatus: workflow.sessionStatus ?? null,
|
|
53083
|
+
assistant: {
|
|
53084
|
+
eligible: workflow.assistantEligible === true,
|
|
53085
|
+
sessionId: workflow.assistantSessionId ?? null,
|
|
53086
|
+
threadId: workflow.assistantThreadId ?? null,
|
|
53087
|
+
sessionStatus: workflow.sessionStatus ?? null
|
|
53088
|
+
},
|
|
53089
|
+
template: hasTemplate ? {
|
|
53090
|
+
id: workflow.templateId ?? null,
|
|
53091
|
+
name: workflow.templateName ?? null,
|
|
53092
|
+
version: workflow.templateVersion ?? null,
|
|
53093
|
+
controlledParts,
|
|
53094
|
+
hasSchemaValidationRules: workflow.hasSchemaValidationRules ?? false
|
|
53095
|
+
} : null,
|
|
52726
53096
|
updateInterval: workflow.updateInterval,
|
|
52727
53097
|
schedules: workflow.schedules,
|
|
53098
|
+
scheduleTimezone: workflow.scheduleTimezone ?? null,
|
|
52728
53099
|
nextInvocation: workflow.nextInvocation,
|
|
52729
|
-
|
|
53100
|
+
location: workflow.location ?? null,
|
|
53101
|
+
limit: workflow.limit ?? null,
|
|
52730
53102
|
tags: workflow.tags,
|
|
52731
53103
|
totalRecords: workflow.totalRecords,
|
|
53104
|
+
job: workflow.jobId ? {
|
|
53105
|
+
id: workflow.jobId,
|
|
53106
|
+
state: workflow.runState ?? null,
|
|
53107
|
+
isFirstRun: workflow.isFirstRun ?? null,
|
|
53108
|
+
startedAt: workflow.startedAt ?? null,
|
|
53109
|
+
finishedAt: workflow.finishedAt ?? null,
|
|
53110
|
+
estimatedFinishedAtUtc: workflow.estimatedFinishedAtUtc ?? null,
|
|
53111
|
+
dataQualityIssues: workflow.dataQualityIssues ?? null,
|
|
53112
|
+
errors: workflow.errors ?? []
|
|
53113
|
+
} : null,
|
|
52732
53114
|
startedAt: workflow.startedAt,
|
|
52733
53115
|
finishedAt: workflow.finishedAt,
|
|
53116
|
+
estimatedFinishedAtUtc: workflow.estimatedFinishedAtUtc ?? null,
|
|
52734
53117
|
errors: workflow.errors,
|
|
52735
53118
|
createdAt: workflow.createdAt,
|
|
52736
|
-
notificationConfig: workflow.notificationConfig
|
|
53119
|
+
notificationConfig: workflow.notificationConfig,
|
|
53120
|
+
channelCounts: workflow.channelCounts ?? {},
|
|
53121
|
+
dataValidation: workflow.dataValidation ?? null,
|
|
53122
|
+
validationStatistics: workflow.validationStatistics ?? null,
|
|
53123
|
+
realtime: isRealtime ? {
|
|
53124
|
+
lastDataChangedAt: workflow.lastDataChangedAt ?? null,
|
|
53125
|
+
observerHealth: workflow.observerHealth ?? null
|
|
53126
|
+
} : null
|
|
53127
|
+
});
|
|
53128
|
+
}));
|
|
53129
|
+
server.registerTool("request_workflow_update", {
|
|
53130
|
+
description: "Request an Assistant-driven change to an existing workflow while preserving its workflowId. " + "Use for extraction intent, navigation, pagination, data sourcing, generated-script changes, and repair after a site redesign. " + "Use update_workflow instead for deterministic metadata such as name, schedule, location, tags, and limits. " + "For template-controlled prompt or schema changes, create and apply a template version instead. " + "The update is asynchronous: do not poll or sleep-wait; use get_workflow_assistant later. Never delete and recreate the workflow as a workaround.",
|
|
53131
|
+
inputSchema: strictSchema({
|
|
53132
|
+
workflowId: exports_external.string().min(1).describe("The existing workflow ID; it will not change"),
|
|
53133
|
+
instructions: exports_external.string().min(1).describe("Natural-language instructions for the workflow Assistant"),
|
|
53134
|
+
threadId: exports_external.string().optional().describe("Optional Assistant thread ID to continue")
|
|
53135
|
+
}),
|
|
53136
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false }
|
|
53137
|
+
}, withErrorHandling("request_workflow_update", async (args) => {
|
|
53138
|
+
const result = await ctx.client.assistant.requestWorkflowUpdate(args.workflowId, {
|
|
53139
|
+
instructions: args.instructions,
|
|
53140
|
+
threadId: args.threadId
|
|
53141
|
+
});
|
|
53142
|
+
if (result.workflowId !== args.workflowId) {
|
|
53143
|
+
return errorResult(`The Assistant returned a different workflow ID (${result.workflowId}) than requested (${args.workflowId}). ` + "The update was not reported as successful because workflow identity must be preserved.");
|
|
53144
|
+
}
|
|
53145
|
+
return jsonResult({
|
|
53146
|
+
success: true,
|
|
53147
|
+
status: "accepted",
|
|
53148
|
+
workflowId: result.workflowId,
|
|
53149
|
+
sessionId: result.sessionId,
|
|
53150
|
+
threadId: result.threadId,
|
|
53151
|
+
jobId: result.jobId,
|
|
53152
|
+
inputEventId: result.inputEventId,
|
|
53153
|
+
dashboardUrl: workflowDashboardUrl(result.workflowId),
|
|
53154
|
+
message: "Workflow update accepted. Use get_workflow_assistant later to check whether the Assistant is working or needs input; do not poll or sleep-wait."
|
|
53155
|
+
});
|
|
53156
|
+
}));
|
|
53157
|
+
server.registerTool("get_workflow_assistant", {
|
|
53158
|
+
description: "Get the current Assistant lifecycle for a workflow, including whether it is working, waiting for input, idle, interrupted, or closed and any pending customer question. Works for both Shelly/Lighthouse and Julie workflows.",
|
|
53159
|
+
inputSchema: strictSchema({
|
|
53160
|
+
workflowId: exports_external.string().min(1).describe("The workflow ID")
|
|
53161
|
+
}),
|
|
53162
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true }
|
|
53163
|
+
}, withErrorHandling("get_workflow_assistant", async (args) => {
|
|
53164
|
+
const workflow = await ctx.client.workflow.get(args.workflowId);
|
|
53165
|
+
const sessionId = workflow.assistantSessionId ?? null;
|
|
53166
|
+
const assistantEligible = workflow.assistantEligible === true;
|
|
53167
|
+
const pauseState = sessionId ? await ctx.client.assistant.getPauseState(sessionId) : null;
|
|
53168
|
+
const activity = deriveAssistantActivity({
|
|
53169
|
+
assistantEligible,
|
|
53170
|
+
hasSession: sessionId != null,
|
|
53171
|
+
sessionStatus: workflow.sessionStatus,
|
|
53172
|
+
pauseState
|
|
53173
|
+
});
|
|
53174
|
+
const canAcceptUpdate = ![
|
|
53175
|
+
"unsupported",
|
|
53176
|
+
"waiting_for_input",
|
|
53177
|
+
"failed",
|
|
53178
|
+
"closed",
|
|
53179
|
+
"unknown"
|
|
53180
|
+
].includes(activity);
|
|
53181
|
+
return jsonResult({
|
|
53182
|
+
workflowId: workflow.id ?? args.workflowId,
|
|
53183
|
+
assistantEligible,
|
|
53184
|
+
sessionId,
|
|
53185
|
+
threadId: workflow.assistantThreadId ?? null,
|
|
53186
|
+
sessionStatus: workflow.sessionStatus ?? null,
|
|
53187
|
+
activity,
|
|
53188
|
+
canAcceptUpdate,
|
|
53189
|
+
isTerminal: activity === "failed" || activity === "closed",
|
|
53190
|
+
paused: pauseState?.paused ?? false,
|
|
53191
|
+
pause: pauseState?.pause ?? null,
|
|
53192
|
+
pendingQuestion: pauseState?.pendingQuestion ?? null
|
|
53193
|
+
});
|
|
53194
|
+
}));
|
|
53195
|
+
server.registerTool("answer_workflow_assistant_question", {
|
|
53196
|
+
description: "Answer the workflow Assistant's currently pending clarification question and resume it. " + "Use `answer` for a freeform response, or `answers` for the structured key/value response described by get_workflow_assistant. Provide exactly one. The question ID must still be current.",
|
|
53197
|
+
inputSchema: strictSchema({
|
|
53198
|
+
workflowId: exports_external.string().min(1).describe("The workflow ID"),
|
|
53199
|
+
questionId: exports_external.string().min(1).describe("The pending question ID returned by get_workflow_assistant"),
|
|
53200
|
+
answer: exports_external.string().min(1).optional().describe("Freeform answer"),
|
|
53201
|
+
answers: exports_external.preprocess(coerceJson(), exports_external.record(exports_external.string(), exports_external.string())).optional().describe("Structured answer map; keys identify questions and values contain the selected/freeform answers")
|
|
53202
|
+
}),
|
|
53203
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false }
|
|
53204
|
+
}, withErrorHandling("answer_workflow_assistant_question", async (args) => {
|
|
53205
|
+
const hasFreeform = args.answer != null;
|
|
53206
|
+
const hasStructured = args.answers != null;
|
|
53207
|
+
if (hasFreeform === hasStructured) {
|
|
53208
|
+
return errorResult("Provide exactly one of 'answer' (freeform) or 'answers' (structured).");
|
|
53209
|
+
}
|
|
53210
|
+
const workflow = await ctx.client.workflow.get(args.workflowId);
|
|
53211
|
+
const sessionId = workflow.assistantSessionId;
|
|
53212
|
+
if (!sessionId) {
|
|
53213
|
+
return errorResult("This workflow does not have an Assistant session with a pending question.");
|
|
53214
|
+
}
|
|
53215
|
+
const pauseState = await ctx.client.assistant.getPauseState(sessionId);
|
|
53216
|
+
const pendingQuestion = pauseState.pendingQuestion;
|
|
53217
|
+
if (!pendingQuestion) {
|
|
53218
|
+
return errorResult("The workflow Assistant does not currently have a pending question.");
|
|
53219
|
+
}
|
|
53220
|
+
if (pendingQuestion.questionId !== args.questionId) {
|
|
53221
|
+
return errorResult(`Question '${args.questionId}' is stale. The current pending question ID is '${pendingQuestion.questionId}'. ` + "Call get_workflow_assistant to review it before answering.");
|
|
53222
|
+
}
|
|
53223
|
+
const answers = hasFreeform ? { [FREEFORM_ASSISTANT_ANSWER_KEY]: args.answer } : args.answers;
|
|
53224
|
+
const threadId = pendingQuestion.threadId ?? workflow.assistantThreadId ?? undefined;
|
|
53225
|
+
await ctx.client.assistant.answerQuestion({
|
|
53226
|
+
sessionId,
|
|
53227
|
+
questionId: args.questionId,
|
|
53228
|
+
threadId,
|
|
53229
|
+
answers
|
|
53230
|
+
});
|
|
53231
|
+
return jsonResult({
|
|
53232
|
+
success: true,
|
|
53233
|
+
workflowId: workflow.id ?? args.workflowId,
|
|
53234
|
+
sessionId,
|
|
53235
|
+
threadId: threadId ?? null,
|
|
53236
|
+
questionId: args.questionId,
|
|
53237
|
+
message: "Answer submitted. The workflow Assistant has been asked to resume."
|
|
53238
|
+
});
|
|
53239
|
+
}));
|
|
53240
|
+
server.registerTool("interrupt_workflow_assistant", {
|
|
53241
|
+
description: "Safely interrupt the active Assistant working on a workflow. This pauses Assistant reasoning/update work; it does not pause the workflow's extraction schedule. Use pause_workflow for scheduling instead.",
|
|
53242
|
+
inputSchema: strictSchema({
|
|
53243
|
+
workflowId: exports_external.string().min(1).describe("Workflow whose Assistant session should be interrupted")
|
|
53244
|
+
}),
|
|
53245
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false }
|
|
53246
|
+
}, withErrorHandling("interrupt_workflow_assistant", async (args) => {
|
|
53247
|
+
const workflow = await ctx.client.workflow.get(args.workflowId);
|
|
53248
|
+
const sessionId = workflow.assistantSessionId;
|
|
53249
|
+
if (!sessionId)
|
|
53250
|
+
return errorResult("This workflow does not have an Assistant session to interrupt.");
|
|
53251
|
+
const pauseState = await ctx.client.assistant.getPauseState(sessionId);
|
|
53252
|
+
const transitionError = assistantControlTransitionError({
|
|
53253
|
+
action: "interrupt",
|
|
53254
|
+
sessionStatus: workflow.sessionStatus,
|
|
53255
|
+
pauseState
|
|
53256
|
+
});
|
|
53257
|
+
if (transitionError)
|
|
53258
|
+
return errorResult(transitionError);
|
|
53259
|
+
const result = await ctx.client.assistant.interrupt(sessionId);
|
|
53260
|
+
return jsonResult({
|
|
53261
|
+
success: result.success,
|
|
53262
|
+
status: "accepted",
|
|
53263
|
+
action: "interrupt",
|
|
53264
|
+
workflowId: workflow.id ?? args.workflowId,
|
|
53265
|
+
sessionId,
|
|
53266
|
+
delivery: result.delivery ?? null,
|
|
53267
|
+
message: "Assistant interrupt accepted. Check get_workflow_assistant later; do not poll or sleep-wait."
|
|
53268
|
+
});
|
|
53269
|
+
}));
|
|
53270
|
+
server.registerTool("resume_workflow_assistant", {
|
|
53271
|
+
description: "Resume an idle or interrupted workflow Assistant using the persona and conversation persisted on its session. Works for both Lighthouse and Julie. This does not resume a paused workflow schedule; use approve_workflow for that.",
|
|
53272
|
+
inputSchema: strictSchema({
|
|
53273
|
+
workflowId: exports_external.string().min(1).describe("Workflow whose Assistant session should resume")
|
|
53274
|
+
}),
|
|
53275
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false }
|
|
53276
|
+
}, withErrorHandling("resume_workflow_assistant", async (args) => {
|
|
53277
|
+
const workflow = await ctx.client.workflow.get(args.workflowId);
|
|
53278
|
+
const sessionId = workflow.assistantSessionId;
|
|
53279
|
+
if (!sessionId)
|
|
53280
|
+
return errorResult("This workflow does not have an Assistant session to resume.");
|
|
53281
|
+
const pauseState = await ctx.client.assistant.getPauseState(sessionId);
|
|
53282
|
+
const transitionError = assistantControlTransitionError({
|
|
53283
|
+
action: "resume",
|
|
53284
|
+
sessionStatus: workflow.sessionStatus,
|
|
53285
|
+
pauseState
|
|
53286
|
+
});
|
|
53287
|
+
if (transitionError)
|
|
53288
|
+
return errorResult(transitionError);
|
|
53289
|
+
const result = await ctx.client.assistant.resume(sessionId);
|
|
53290
|
+
if (result.sessionId !== sessionId) {
|
|
53291
|
+
return errorResult(`The resume response returned session '${result.sessionId}' instead of '${sessionId}'. The action was not reported as successful because Assistant session identity must be preserved.`);
|
|
53292
|
+
}
|
|
53293
|
+
return jsonResult({
|
|
53294
|
+
success: true,
|
|
53295
|
+
status: "accepted",
|
|
53296
|
+
action: "resume",
|
|
53297
|
+
workflowId: workflow.id ?? args.workflowId,
|
|
53298
|
+
sessionId,
|
|
53299
|
+
jobId: result.jobId,
|
|
53300
|
+
message: "Assistant resume accepted. Check get_workflow_assistant later; do not poll or sleep-wait."
|
|
53301
|
+
});
|
|
53302
|
+
}));
|
|
53303
|
+
server.registerTool("stop_workflow_assistant", {
|
|
53304
|
+
description: "Stop the active Assistant update for a workflow. This cancels Assistant work but does not delete, pause, or replace the workflow and does not change workflowId. Use pause_workflow separately to stop scheduled extraction runs.",
|
|
53305
|
+
inputSchema: strictSchema({
|
|
53306
|
+
workflowId: exports_external.string().min(1).describe("Workflow whose active Assistant session should stop")
|
|
53307
|
+
}),
|
|
53308
|
+
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false }
|
|
53309
|
+
}, withErrorHandling("stop_workflow_assistant", async (args) => {
|
|
53310
|
+
const workflow = await ctx.client.workflow.get(args.workflowId);
|
|
53311
|
+
const sessionId = workflow.assistantSessionId;
|
|
53312
|
+
if (!sessionId)
|
|
53313
|
+
return errorResult("This workflow does not have an Assistant session to stop.");
|
|
53314
|
+
const pauseState = await ctx.client.assistant.getPauseState(sessionId);
|
|
53315
|
+
const transitionError = assistantControlTransitionError({
|
|
53316
|
+
action: "stop",
|
|
53317
|
+
sessionStatus: workflow.sessionStatus,
|
|
53318
|
+
pauseState
|
|
53319
|
+
});
|
|
53320
|
+
if (transitionError)
|
|
53321
|
+
return errorResult(transitionError);
|
|
53322
|
+
const result = await ctx.client.assistant.stop(sessionId);
|
|
53323
|
+
return jsonResult({
|
|
53324
|
+
success: result.success,
|
|
53325
|
+
status: "accepted",
|
|
53326
|
+
action: "stop",
|
|
53327
|
+
workflowId: workflow.id ?? args.workflowId,
|
|
53328
|
+
sessionId,
|
|
53329
|
+
message: "Assistant stop accepted. The workflow itself was left unchanged."
|
|
53330
|
+
});
|
|
53331
|
+
}));
|
|
53332
|
+
server.registerTool("get_workflow_strategy", {
|
|
53333
|
+
description: "Get the current customer-safe extraction/build strategy for a workflow: source approach, endpoints, interaction style, selectors, and realtime interval when applicable. Returns building rather than an error when an Assistant session has no build strategy yet.",
|
|
53334
|
+
inputSchema: strictSchema({
|
|
53335
|
+
workflowId: exports_external.string().min(1).describe("The workflow ID")
|
|
53336
|
+
}),
|
|
53337
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true }
|
|
53338
|
+
}, withErrorHandling("get_workflow_strategy", async (args) => {
|
|
53339
|
+
const workflow = await ctx.client.workflow.get(args.workflowId);
|
|
53340
|
+
const sessionId = workflow.assistantSessionId;
|
|
53341
|
+
if (sessionId) {
|
|
53342
|
+
const strategy2 = await ctx.client.assistant.getStrategy(sessionId);
|
|
53343
|
+
const status = strategy2 ? "ready" : isAssistantSessionResumable(workflow.sessionStatus) ? "building" : "unavailable";
|
|
53344
|
+
return jsonResult({
|
|
53345
|
+
workflowId: workflow.id ?? args.workflowId,
|
|
53346
|
+
sessionId,
|
|
53347
|
+
source: "assistant_build",
|
|
53348
|
+
status,
|
|
53349
|
+
strategy: strategy2,
|
|
53350
|
+
...status === "building" && {
|
|
53351
|
+
message: "The Assistant session exists, but its build strategy is not ready yet. Check again later; do not poll."
|
|
53352
|
+
}
|
|
53353
|
+
});
|
|
53354
|
+
}
|
|
53355
|
+
const strategy = workflow.extractionStrategySummary ?? null;
|
|
53356
|
+
return jsonResult({
|
|
53357
|
+
workflowId: workflow.id ?? args.workflowId,
|
|
53358
|
+
sessionId: null,
|
|
53359
|
+
source: strategy ? "workflow_metadata" : null,
|
|
53360
|
+
status: strategy ? "ready" : "unavailable",
|
|
53361
|
+
strategy
|
|
52737
53362
|
});
|
|
52738
53363
|
}));
|
|
52739
53364
|
server.registerTool("get_workflow_history", {
|
|
@@ -53002,9 +53627,9 @@ function registerTools(server, ctx, capabilities) {
|
|
|
53002
53627
|
server.registerTool("update_workflow", {
|
|
53003
53628
|
description: `Update a workflow's configuration. All fields are optional — only provided fields will be updated. Use this to change the name, URLs, extraction schema, entity, prompt, schedule, or other metadata.
|
|
53004
53629
|
|
|
53005
|
-
` + `IMPORTANT: You cannot change a workflow's interval to or from REAL_TIME. Real-time workflows are architecturally different
|
|
53630
|
+
` + `IMPORTANT: You cannot change a workflow's interval to or from REAL_TIME. Real-time workflows are architecturally different from scheduled workflows and must be created with create_realtime_monitor from the start. Existing workflows cannot be converted between these modes in place; do not delete and recreate a workflow as an update workaround.
|
|
53006
53631
|
|
|
53007
|
-
` + "
|
|
53632
|
+
` + "ASSISTANT-OWNED INTENT: Use request_workflow_update—not `userPrompt`—for agent-built workflow changes to extraction intent, navigation, pagination, data sourcing, repair, or generated scripts. `userPrompt` may be rejected with `SHELLY_INTENT_REQUIRES_EXTRACTION_SPEC` because those workflows' canonical intent is owned by the Assistant. " + "Call get_workflow first. If its template.controlledParts contains the setting, create and apply a template version instead of overriding the workflow directly. NEVER delete and recreate a workflow to work around an update limitation—that changes workflowId, breaks downstream tables/connectors, and discards history.",
|
|
53008
53633
|
inputSchema: strictSchema({
|
|
53009
53634
|
workflowId: exports_external.string().describe("The workflow ID to update"),
|
|
53010
53635
|
name: exports_external.string().optional().describe("New name for the workflow"),
|
|
@@ -53034,7 +53659,10 @@ function registerTools(server, ctx, capabilities) {
|
|
|
53034
53659
|
"CUSTOM"
|
|
53035
53660
|
]).optional().describe("How often the workflow should run. CUSTOM requires schedules. Note: REAL_TIME is NOT allowed here — real-time workflows must be created via create_workflow."),
|
|
53036
53661
|
schedules: exports_external.preprocess(coerceArray(true), exports_external.array(exports_external.string())).optional().describe("Cron expressions for CUSTOM update interval"),
|
|
53037
|
-
|
|
53662
|
+
timezone: exports_external.string().min(1).optional().describe("IANA timezone for cron schedules, for example America/New_York. A timezone-only update preserves existing cron expressions."),
|
|
53663
|
+
location: exports_external.preprocess(coerceJson(), LocationSchema).optional().describe("Scraping location: {type:'auto'} or {type:'manual', isoCode:'US'}"),
|
|
53664
|
+
monitoring: exports_external.preprocess(coerceJson(), MonitoringSchema).optional().describe("Complete monitoring replacement: fields to monitor and optional AND/OR conditions. Call get_workflow first because this replaces the existing monitoring configuration."),
|
|
53665
|
+
limit: exports_external.preprocess(coerceNumber(), exports_external.number().positive().nullable()).optional().describe("Maximum records per run. Pass null to clear the limit and extract all rows.")
|
|
53038
53666
|
}),
|
|
53039
53667
|
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true }
|
|
53040
53668
|
}, withErrorHandling("update_workflow", async (args) => {
|
|
@@ -53044,15 +53672,22 @@ function registerTools(server, ctx, capabilities) {
|
|
|
53044
53672
|
const isCurrentlyRealTime = isRealTimeInterval(workflow.updateInterval);
|
|
53045
53673
|
const isRequestingRealTime = isRealTimeInterval(updates.updateInterval);
|
|
53046
53674
|
if (isRequestingRealTime && !isCurrentlyRealTime) {
|
|
53047
|
-
return errorResult("Cannot change a regular workflow's interval to REAL_TIME. " + "Real-time workflows use a different service
|
|
53675
|
+
return errorResult("Cannot change a regular workflow's interval to REAL_TIME. " + "Real-time workflows use a different service and cannot replace this workflow in place. " + "The existing workflow was left unchanged.");
|
|
53048
53676
|
}
|
|
53049
53677
|
if (!isRequestingRealTime && isCurrentlyRealTime) {
|
|
53050
|
-
return errorResult("Cannot change a real-time workflow's interval to a scheduled interval. " + "Real-time workflows are architecturally different and cannot be converted
|
|
53678
|
+
return errorResult("Cannot change a real-time workflow's interval to a scheduled interval. " + "Real-time workflows are architecturally different and cannot be converted in place. " + "The existing workflow was left unchanged.");
|
|
53051
53679
|
}
|
|
53052
53680
|
}
|
|
53053
53681
|
if (updates.updateInterval === "CUSTOM" && (!updates.schedules || updates.schedules.length === 0)) {
|
|
53054
53682
|
return errorResult("updateInterval='CUSTOM' requires at least one cron expression in the 'schedules' field (e.g. '0 8 * * 2' for Tuesdays at 8am UTC).");
|
|
53055
53683
|
}
|
|
53684
|
+
if (updates.monitoring?.conditions) {
|
|
53685
|
+
const monitoredFields = new Set(updates.monitoring.fields.map((field) => field.fieldName));
|
|
53686
|
+
const unknownField = updates.monitoring.conditions.conditions.find((condition) => condition.type === "SINGLE" && condition.field && !monitoredFields.has(condition.field))?.field;
|
|
53687
|
+
if (unknownField) {
|
|
53688
|
+
return errorResult(`Monitoring condition field '${unknownField}' is not present in monitoring.fields. Include it in the replacement monitoring configuration.`);
|
|
53689
|
+
}
|
|
53690
|
+
}
|
|
53056
53691
|
const result = await ctx.client.workflow.update(workflowId, updates);
|
|
53057
53692
|
return jsonResult({
|
|
53058
53693
|
success: true,
|
|
@@ -53702,7 +54337,7 @@ function registerTools(server, ctx, capabilities) {
|
|
|
53702
54337
|
});
|
|
53703
54338
|
}));
|
|
53704
54339
|
}
|
|
53705
|
-
var SchemaFieldShape, DASHBOARD_BASE_URL = "https://www.kadoa.com", WORKFLOW_AUDIT_WATCHED_KEYS;
|
|
54340
|
+
var SchemaFieldShape, LocationSchema, MonitoringValueOperators, MonitoringValuelessOperators, MonitoringConditionOperatorSchema, MonitoringConditionSchema, MonitoringSchema, RESUMABLE_ASSISTANT_STATUSES, ACTIVE_ASSISTANT_STATUSES, IDLE_ASSISTANT_STATUSES, CLOSED_ASSISTANT_STATUSES, DASHBOARD_BASE_URL = "https://www.kadoa.com", WORKFLOW_AUDIT_WATCHED_KEYS;
|
|
53706
54341
|
var init_tools = __esm(() => {
|
|
53707
54342
|
init_dist2();
|
|
53708
54343
|
init_zod();
|
|
@@ -53714,6 +54349,76 @@ var init_tools = __esm(() => {
|
|
|
53714
54349
|
dataType: exports_external.enum(["STRING", "NUMBER", "BOOLEAN", "DATE", "DATETIME", "MONEY", "IMAGE", "LINK", "OBJECT", "ARRAY"]).optional().describe("Data type for the field"),
|
|
53715
54350
|
isKey: exports_external.preprocess(coerceBoolean(), exports_external.boolean()).optional().describe("Marks this field as a key field — the stable identity used to match records across runs. Change detection diffs records by their key fields, so a monitored or real-time workflow without one cannot tell an updated record from a new one. Set it on whatever uniquely identifies a row (a detail URL, an ID, a ticker).")
|
|
53716
54351
|
};
|
|
54352
|
+
LocationSchema = exports_external.object({
|
|
54353
|
+
type: exports_external.enum(["auto", "manual"]),
|
|
54354
|
+
isoCode: exports_external.string().trim().min(2).optional()
|
|
54355
|
+
}).strict().superRefine((location, ctx) => {
|
|
54356
|
+
if (location.type === "manual" && !location.isoCode) {
|
|
54357
|
+
ctx.addIssue({ code: exports_external.ZodIssueCode.custom, path: ["isoCode"], message: "isoCode is required for manual location" });
|
|
54358
|
+
}
|
|
54359
|
+
if (location.type === "auto" && location.isoCode) {
|
|
54360
|
+
ctx.addIssue({ code: exports_external.ZodIssueCode.custom, path: ["isoCode"], message: "omit isoCode for auto location" });
|
|
54361
|
+
}
|
|
54362
|
+
});
|
|
54363
|
+
MonitoringValueOperators = [
|
|
54364
|
+
"MATCHES_REGEX",
|
|
54365
|
+
"EQUALS",
|
|
54366
|
+
"NOT_EQUALS",
|
|
54367
|
+
"CONTAINS",
|
|
54368
|
+
"NOT_CONTAINS",
|
|
54369
|
+
"STARTS_WITH",
|
|
54370
|
+
"ENDS_WITH",
|
|
54371
|
+
"GREATER_THAN",
|
|
54372
|
+
"LESS_THAN",
|
|
54373
|
+
"GREATER_THAN_OR_EQUAL",
|
|
54374
|
+
"LESS_THAN_OR_EQUAL",
|
|
54375
|
+
"IN",
|
|
54376
|
+
"NOT_IN",
|
|
54377
|
+
"BEFORE",
|
|
54378
|
+
"AFTER",
|
|
54379
|
+
"WITHIN_LAST_DAYS"
|
|
54380
|
+
];
|
|
54381
|
+
MonitoringValuelessOperators = ["IS_NULL", "IS_NOT_NULL", "IS_EMPTY", "IS_NOT_EMPTY"];
|
|
54382
|
+
MonitoringConditionOperatorSchema = exports_external.enum([
|
|
54383
|
+
...MonitoringValueOperators,
|
|
54384
|
+
...MonitoringValuelessOperators
|
|
54385
|
+
]);
|
|
54386
|
+
MonitoringConditionSchema = exports_external.object({
|
|
54387
|
+
type: exports_external.enum(["SINGLE", "ANY"]),
|
|
54388
|
+
field: exports_external.string().trim().min(1).optional(),
|
|
54389
|
+
operator: MonitoringConditionOperatorSchema,
|
|
54390
|
+
value: exports_external.union([exports_external.string(), exports_external.number(), exports_external.boolean()]).optional()
|
|
54391
|
+
}).strict().superRefine((condition, ctx) => {
|
|
54392
|
+
if (condition.type === "SINGLE" && !condition.field) {
|
|
54393
|
+
ctx.addIssue({ code: exports_external.ZodIssueCode.custom, path: ["field"], message: "field is required for SINGLE conditions" });
|
|
54394
|
+
}
|
|
54395
|
+
const needsValue = MonitoringValueOperators.includes(condition.operator);
|
|
54396
|
+
if (needsValue && condition.value === undefined) {
|
|
54397
|
+
ctx.addIssue({ code: exports_external.ZodIssueCode.custom, path: ["value"], message: `${condition.operator} requires a value` });
|
|
54398
|
+
}
|
|
54399
|
+
if (!needsValue && condition.value !== undefined) {
|
|
54400
|
+
ctx.addIssue({
|
|
54401
|
+
code: exports_external.ZodIssueCode.custom,
|
|
54402
|
+
path: ["value"],
|
|
54403
|
+
message: `${condition.operator} does not accept a value`
|
|
54404
|
+
});
|
|
54405
|
+
}
|
|
54406
|
+
});
|
|
54407
|
+
MonitoringSchema = exports_external.object({
|
|
54408
|
+
fields: exports_external.preprocess(coerceArray(), exports_external.array(exports_external.object({
|
|
54409
|
+
fieldName: exports_external.string().trim().min(1),
|
|
54410
|
+
operator: exports_external.enum(["changed", "added", "removed"]),
|
|
54411
|
+
isKeyField: exports_external.preprocess(coerceBoolean(), exports_external.boolean()).optional()
|
|
54412
|
+
}).strict()).min(1)),
|
|
54413
|
+
conditions: exports_external.object({
|
|
54414
|
+
logicalOperator: exports_external.enum(["AND", "OR"]),
|
|
54415
|
+
conditions: exports_external.preprocess(coerceArray(), exports_external.array(MonitoringConditionSchema).min(1))
|
|
54416
|
+
}).strict().optional()
|
|
54417
|
+
}).strict();
|
|
54418
|
+
RESUMABLE_ASSISTANT_STATUSES = new Set(["pending", "created", "active", "idle", "inactive", "interrupted"]);
|
|
54419
|
+
ACTIVE_ASSISTANT_STATUSES = new Set(["pending", "created", "active"]);
|
|
54420
|
+
IDLE_ASSISTANT_STATUSES = new Set(["idle", "inactive", "interrupted"]);
|
|
54421
|
+
CLOSED_ASSISTANT_STATUSES = new Set(["failed", "errored", "aborted", "timed_out"]);
|
|
53717
54422
|
WORKFLOW_AUDIT_WATCHED_KEYS = [
|
|
53718
54423
|
"name",
|
|
53719
54424
|
"tags",
|
|
@@ -53732,7 +54437,7 @@ var package_default;
|
|
|
53732
54437
|
var init_package = __esm(() => {
|
|
53733
54438
|
package_default = {
|
|
53734
54439
|
name: "@kadoa/mcp",
|
|
53735
|
-
version: "0.5.
|
|
54440
|
+
version: "0.5.18",
|
|
53736
54441
|
description: "Kadoa MCP Server — manage workflows from Claude Desktop, Cursor, and other MCP clients",
|
|
53737
54442
|
type: "module",
|
|
53738
54443
|
main: "dist/index.js",
|
|
@@ -53756,7 +54461,7 @@ var init_package = __esm(() => {
|
|
|
53756
54461
|
prepublishOnly: "bun run check-types && bun run test:unit && bun run build"
|
|
53757
54462
|
},
|
|
53758
54463
|
dependencies: {
|
|
53759
|
-
"@kadoa/node-sdk": "^0.
|
|
54464
|
+
"@kadoa/node-sdk": "^0.37.1",
|
|
53760
54465
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
53761
54466
|
express: "^5.2.1",
|
|
53762
54467
|
"express-rate-limit": "^8.2.1",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kadoa/mcp",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.18",
|
|
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.37.1",
|
|
28
28
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
29
29
|
"express": "^5.2.1",
|
|
30
30
|
"express-rate-limit": "^8.2.1",
|