@n8n/instance-ai 1.12.4 → 1.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/apply-agent-thinking.d.ts +2 -0
- package/dist/agent/apply-agent-thinking.js +41 -0
- package/dist/agent/apply-agent-thinking.js.map +1 -0
- package/dist/agent/instance-agent.js +10 -2
- package/dist/agent/instance-agent.js.map +1 -1
- package/dist/agent/sanitize-mcp-schemas.js +133 -125
- package/dist/agent/sanitize-mcp-schemas.js.map +1 -1
- package/dist/agent/shared-prompts.d.ts +0 -1
- package/dist/agent/shared-prompts.js +4 -11
- package/dist/agent/shared-prompts.js.map +1 -1
- package/dist/agent/sub-agent-debriefing.d.ts +4 -4
- package/dist/agent/system-prompt.js +3 -10
- package/dist/agent/system-prompt.js.map +1 -1
- package/dist/build.tsbuildinfo +1 -1
- package/dist/debug/run-debug-buffer.d.ts +63 -0
- package/dist/debug/run-debug-buffer.js +177 -0
- package/dist/debug/run-debug-buffer.js.map +1 -0
- package/dist/debug/sanitize-debug-snapshot.d.ts +2 -0
- package/dist/debug/sanitize-debug-snapshot.js +88 -0
- package/dist/debug/sanitize-debug-snapshot.js.map +1 -0
- package/dist/error-formatting.js +3 -5
- package/dist/error-formatting.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.js +8 -3
- package/dist/index.js.map +1 -1
- package/dist/knowledge-base/build-templates-index.d.ts +1 -0
- package/dist/knowledge-base/build-templates-index.js +18 -2
- package/dist/knowledge-base/build-templates-index.js.map +1 -1
- package/dist/knowledge-base/materialize-knowledge-base.d.ts +2 -3
- package/dist/knowledge-base/materialize-knowledge-base.js +10 -7
- package/dist/knowledge-base/materialize-knowledge-base.js.map +1 -1
- package/dist/mcp/mcp-client-manager.d.ts +1 -1
- package/dist/mcp/mcp-client-manager.js +13 -9
- package/dist/mcp/mcp-client-manager.js.map +1 -1
- package/dist/runtime/memory-task-registry.d.ts +8 -0
- package/dist/runtime/memory-task-registry.js +42 -0
- package/dist/runtime/memory-task-registry.js.map +1 -0
- package/dist/runtime/resumable-stream-executor.d.ts +3 -0
- package/dist/runtime/resumable-stream-executor.js +171 -90
- package/dist/runtime/resumable-stream-executor.js.map +1 -1
- package/dist/runtime/run-state-registry.d.ts +2 -0
- package/dist/runtime/run-state-registry.js +3 -0
- package/dist/runtime/run-state-registry.js.map +1 -1
- package/dist/runtime/stream-runner.d.ts +3 -0
- package/dist/runtime/stream-runner.js +3 -0
- package/dist/runtime/stream-runner.js.map +1 -1
- package/dist/skills/materialize-runtime-skills.d.ts +3 -3
- package/dist/skills/materialize-runtime-skills.js +1 -1
- package/dist/skills/materialize-runtime-skills.js.map +1 -1
- package/dist/source-map-filter.js +0 -1
- package/dist/source-map-filter.js.map +1 -1
- package/dist/storage/terminal-outcome-storage.d.ts +2 -2
- package/dist/storage/workflow-loop-storage.d.ts +75 -4
- package/dist/stream/map-chunk.js +198 -237
- package/dist/stream/map-chunk.js.map +1 -1
- package/dist/stream/output-redaction.js +2 -2
- package/dist/stream/output-redaction.js.map +1 -1
- package/dist/stream/usage-accumulator.d.ts +90 -0
- package/dist/stream/usage-accumulator.js +89 -0
- package/dist/stream/usage-accumulator.js.map +1 -0
- package/dist/stream/work-summary-accumulator.d.ts +6 -6
- package/dist/tools/attachments/parse-file.tool.js +1 -1
- package/dist/tools/attachments/parse-file.tool.js.map +1 -1
- package/dist/tools/credentials.tool.js +4 -1
- package/dist/tools/credentials.tool.js.map +1 -1
- package/dist/tools/data-tables.tool.js +5 -2
- package/dist/tools/data-tables.tool.js.map +1 -1
- package/dist/tools/evals/column-ref-utils.d.ts +1 -2
- package/dist/tools/evals/column-ref-utils.js +19 -18
- package/dist/tools/evals/column-ref-utils.js.map +1 -1
- package/dist/tools/evals/describe-metric-for-workflow.service.js +7 -25
- package/dist/tools/evals/describe-metric-for-workflow.service.js.map +1 -1
- package/dist/tools/evals/detect-tool-refs.service.js +2 -1
- package/dist/tools/evals/detect-tool-refs.service.js.map +1 -1
- package/dist/tools/evals/eval-data-requirements.service.js +10 -9
- package/dist/tools/evals/eval-data-requirements.service.js.map +1 -1
- package/dist/tools/evals/evals.tool.js +2 -2
- package/dist/tools/evals/evals.tool.js.map +1 -1
- package/dist/tools/evals/extract-rows-from-history.service.js +8 -8
- package/dist/tools/evals/extract-rows-from-history.service.js.map +1 -1
- package/dist/tools/evals/generate-sample-rows.service.d.ts +2 -2
- package/dist/tools/evals/generate-sample-rows.service.js +30 -49
- package/dist/tools/evals/generate-sample-rows.service.js.map +1 -1
- package/dist/tools/evals/generate-tool-ref-pin-data.service.js +10 -23
- package/dist/tools/evals/generate-tool-ref-pin-data.service.js.map +1 -1
- package/dist/tools/evals/metric-catalog.js +3 -3
- package/dist/tools/evals/metric-catalog.js.map +1 -1
- package/dist/tools/executions.tool.js +10 -2
- package/dist/tools/executions.tool.js.map +1 -1
- package/dist/tools/filesystem/create-tools-from-mcp-server.d.ts +1 -1
- package/dist/tools/filesystem/create-tools-from-mcp-server.js +8 -10
- package/dist/tools/filesystem/create-tools-from-mcp-server.js.map +1 -1
- package/dist/tools/index.js +1 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/nodes/node-search-engine.js +21 -42
- package/dist/tools/nodes/node-search-engine.js.map +1 -1
- package/dist/tools/nodes/node-search-engine.types.d.ts +2 -0
- package/dist/tools/nodes/preferred-chat-model.d.ts +1 -0
- package/dist/tools/nodes/preferred-chat-model.js +19 -0
- package/dist/tools/nodes/preferred-chat-model.js.map +1 -0
- package/dist/tools/nodes/suggested-nodes-data.js +13 -3
- package/dist/tools/nodes/suggested-nodes-data.js.map +1 -1
- package/dist/tools/nodes.tool.js +32 -7
- package/dist/tools/nodes.tool.js.map +1 -1
- package/dist/tools/orchestration/complete-checkpoint.tool.js +3 -5
- package/dist/tools/orchestration/complete-checkpoint.tool.js.map +1 -1
- package/dist/tools/orchestration/eval-data-agent.tool.js +2 -1
- package/dist/tools/orchestration/eval-data-agent.tool.js.map +1 -1
- package/dist/tools/orchestration/eval-setup-agent.prompt.d.ts +1 -1
- package/dist/tools/orchestration/eval-setup-agent.prompt.js +3 -3
- package/dist/tools/orchestration/report-verification-verdict.tool.d.ts +2 -2
- package/dist/tools/orchestration/report-verification-verdict.tool.js +1 -1
- package/dist/tools/orchestration/report-verification-verdict.tool.js.map +1 -1
- package/dist/tools/orchestration/verify-built-workflow.tool.js +328 -315
- package/dist/tools/orchestration/verify-built-workflow.tool.js.map +1 -1
- package/dist/tools/research.tool.js +1 -1
- package/dist/tools/research.tool.js.map +1 -1
- package/dist/tools/shared/ask-user.tool.d.ts +4 -4
- package/dist/tools/shared/ask-user.tool.js +6 -1
- package/dist/tools/shared/ask-user.tool.js.map +1 -1
- package/dist/tools/tool-ids.d.ts +0 -1
- package/dist/tools/tool-ids.js +0 -1
- package/dist/tools/tool-ids.js.map +1 -1
- package/dist/tools/workflows/build-workflow.tool.d.ts +4 -22
- package/dist/tools/workflows/build-workflow.tool.js +374 -328
- package/dist/tools/workflows/build-workflow.tool.js.map +1 -1
- package/dist/tools/workflows/classify-node-destructiveness.service.d.ts +7 -0
- package/dist/tools/workflows/classify-node-destructiveness.service.js +307 -0
- package/dist/tools/workflows/classify-node-destructiveness.service.js.map +1 -0
- package/dist/tools/workflows/generate-simulation-fixtures.service.d.ts +8 -0
- package/dist/tools/workflows/generate-simulation-fixtures.service.js +95 -0
- package/dist/tools/workflows/generate-simulation-fixtures.service.js.map +1 -0
- package/dist/tools/workflows/plan-verification-simulation.d.ts +16 -0
- package/dist/tools/workflows/plan-verification-simulation.js +76 -0
- package/dist/tools/workflows/plan-verification-simulation.js.map +1 -0
- package/dist/tools/workflows/resolve-credentials.d.ts +0 -2
- package/dist/tools/workflows/resolve-credentials.js +0 -13
- package/dist/tools/workflows/resolve-credentials.js.map +1 -1
- package/dist/tools/workflows/setup-workflow.service.js +259 -215
- package/dist/tools/workflows/setup-workflow.service.js.map +1 -1
- package/dist/tools/workflows/validate-workflow.service.js +81 -66
- package/dist/tools/workflows/validate-workflow.service.js.map +1 -1
- package/dist/tools/workflows/workflow-build-context.d.ts +33 -0
- package/dist/tools/workflows/workflow-build-context.js +80 -0
- package/dist/tools/workflows/workflow-build-context.js.map +1 -0
- package/dist/tools/workflows/workflow-build-remediation.d.ts +11 -0
- package/dist/tools/workflows/workflow-build-remediation.js +89 -0
- package/dist/tools/workflows/workflow-build-remediation.js.map +1 -0
- package/dist/tools/workflows/workflow-build-reporting.d.ts +19 -0
- package/dist/tools/workflows/workflow-build-reporting.js +78 -0
- package/dist/tools/workflows/workflow-build-reporting.js.map +1 -0
- package/dist/tools/workflows/workflow-build-routing.d.ts +2 -0
- package/dist/tools/workflows/workflow-build-routing.js +60 -0
- package/dist/tools/workflows/workflow-build-routing.js.map +1 -0
- package/dist/tools/workflows/workflow-build-telemetry.d.ts +18 -0
- package/dist/tools/workflows/workflow-build-telemetry.js +33 -0
- package/dist/tools/workflows/workflow-build-telemetry.js.map +1 -0
- package/dist/tools/workflows/workflow-file-bindings.d.ts +28 -0
- package/dist/tools/workflows/workflow-file-bindings.js +104 -0
- package/dist/tools/workflows/workflow-file-bindings.js.map +1 -0
- package/dist/tools/workflows/workflow-json-utils.d.ts +3 -0
- package/dist/tools/workflows/workflow-json-utils.js +54 -5
- package/dist/tools/workflows/workflow-json-utils.js.map +1 -1
- package/dist/tools/workflows/workflow-source-compiler.d.ts +20 -0
- package/dist/tools/workflows/workflow-source-compiler.js +236 -0
- package/dist/tools/workflows/workflow-source-compiler.js.map +1 -0
- package/dist/tools/workflows/workflow-validation-warnings.d.ts +14 -0
- package/dist/tools/workflows/workflow-validation-warnings.js +28 -0
- package/dist/tools/workflows/workflow-validation-warnings.js.map +1 -0
- package/dist/tools/workflows.tool.js +107 -99
- package/dist/tools/workflows.tool.js.map +1 -1
- package/dist/tracing/langsmith-tracing.js +7 -7
- package/dist/tracing/langsmith-tracing.js.map +1 -1
- package/dist/tracing/trace-payloads.d.ts +2 -1
- package/dist/tracing/trace-payloads.js +152 -114
- package/dist/tracing/trace-payloads.js.map +1 -1
- package/dist/types.d.ts +24 -4
- package/dist/types.js.map +1 -1
- package/dist/utils/eval-agents.d.ts +0 -3
- package/dist/utils/eval-agents.js +3 -11
- package/dist/utils/eval-agents.js.map +1 -1
- package/dist/utils/generate-validated-json.d.ts +16 -0
- package/dist/utils/generate-validated-json.js +38 -0
- package/dist/utils/generate-validated-json.js.map +1 -0
- package/dist/utils/stream-helpers.d.ts +0 -1
- package/dist/utils/stream-helpers.js +5 -8
- package/dist/utils/stream-helpers.js.map +1 -1
- package/dist/workflow-builder/build-failure-tracker.js +25 -1
- package/dist/workflow-builder/build-failure-tracker.js.map +1 -1
- package/dist/workflow-builder/index.d.ts +0 -4
- package/dist/workflow-builder/index.js +1 -11
- package/dist/workflow-builder/index.js.map +1 -1
- package/dist/workflow-loop/guidance.js +14 -15
- package/dist/workflow-loop/guidance.js.map +1 -1
- package/dist/workflow-loop/runtime.js +1 -0
- package/dist/workflow-loop/runtime.js.map +1 -1
- package/dist/workflow-loop/setup-verification-policy.d.ts +8 -0
- package/dist/workflow-loop/setup-verification-policy.js +25 -0
- package/dist/workflow-loop/setup-verification-policy.js.map +1 -0
- package/dist/workflow-loop/verification-obligation.js +13 -8
- package/dist/workflow-loop/verification-obligation.js.map +1 -1
- package/dist/workflow-loop/workflow-loop-controller.js +26 -7
- package/dist/workflow-loop/workflow-loop-controller.js.map +1 -1
- package/dist/workflow-loop/workflow-loop-state.d.ts +90 -6
- package/dist/workflow-loop/workflow-loop-state.js +13 -1
- package/dist/workflow-loop/workflow-loop-state.js.map +1 -1
- package/dist/workspace/builder-templates-service.d.ts +5 -5
- package/dist/workspace/builder-templates-service.js +17 -14
- package/dist/workspace/builder-templates-service.js.map +1 -1
- package/dist/workspace/create-workspace.js +8 -1
- package/dist/workspace/create-workspace.js.map +1 -1
- package/dist/workspace/prebaked-workspace-bundle.d.ts +2 -2
- package/dist/workspace/prebaked-workspace-bundle.js +5 -5
- package/dist/workspace/prebaked-workspace-bundle.js.map +1 -1
- package/dist/workspace/sandbox-setup.d.ts +2 -2
- package/dist/workspace/sandbox-setup.js +15 -38
- package/dist/workspace/sandbox-setup.js.map +1 -1
- package/dist/workspace/snapshot-manager.d.ts +1 -1
- package/dist/workspace/template-telemetry.js +2 -5
- package/dist/workspace/template-telemetry.js.map +1 -1
- package/dist/workspace/workspace-files.d.ts +1 -1
- package/dist/workspace/workspace-files.js +3 -3
- package/dist/workspace/workspace-files.js.map +1 -1
- package/dist/workspace/workspace-manifest.js +2 -2
- package/dist/workspace/workspace-manifest.js.map +1 -1
- package/dist/workspace/workspace-paths.d.ts +4 -0
- package/dist/workspace/workspace-paths.js +25 -0
- package/dist/workspace/workspace-paths.js.map +1 -0
- package/knowledge-base/reference/open-ai-output-shape.md +79 -0
- package/knowledge-base/reference/workflow-builder-guardrails.md +15 -0
- package/package.json +13 -12
- package/skills/planned-task-runtime/SKILL.md +3 -2
- package/skills/planning/SKILL.md +5 -0
- package/skills/post-build-flow/SKILL.md +25 -9
- package/skills/workflow-builder/SKILL.md +96 -134
- package/dist/tools/workflows/submit-workflow-identity.d.ts +0 -39
- package/dist/tools/workflows/submit-workflow-identity.js +0 -181
- package/dist/tools/workflows/submit-workflow-identity.js.map +0 -1
- package/dist/tools/workflows/submit-workflow.tool.d.ts +0 -223
- package/dist/tools/workflows/submit-workflow.tool.js +0 -491
- package/dist/tools/workflows/submit-workflow.tool.js.map +0 -1
- package/dist/workflow-builder/extract-code.d.ts +0 -5
- package/dist/workflow-builder/extract-code.js +0 -105
- package/dist/workflow-builder/extract-code.js.map +0 -1
- package/dist/workflow-builder/parse-validate.d.ts +0 -10
- package/dist/workflow-builder/parse-validate.js +0 -50
- package/dist/workflow-builder/parse-validate.js.map +0 -1
- package/dist/workflow-builder/patch-code.d.ts +0 -14
- package/dist/workflow-builder/patch-code.js +0 -117
- package/dist/workflow-builder/patch-code.js.map +0 -1
- package/dist/workflow-builder/types.d.ts +0 -11
- package/dist/workflow-builder/types.js +0 -3
- package/dist/workflow-builder/types.js.map +0 -1
|
@@ -5,22 +5,23 @@ exports.createBuildWorkflowTool = createBuildWorkflowTool;
|
|
|
5
5
|
const agents_1 = require("@n8n/agents");
|
|
6
6
|
const api_types_1 = require("@n8n/api-types");
|
|
7
7
|
const utils_1 = require("@n8n/utils");
|
|
8
|
-
const workflow_sdk_1 = require("@n8n/workflow-sdk");
|
|
9
8
|
const nanoid_1 = require("nanoid");
|
|
10
9
|
const zod_1 = require("zod");
|
|
10
|
+
const plan_verification_simulation_1 = require("./plan-verification-simulation");
|
|
11
11
|
const resolve_credentials_1 = require("./resolve-credentials");
|
|
12
12
|
const setup_workflow_service_1 = require("./setup-workflow.service");
|
|
13
|
-
const
|
|
13
|
+
const workflow_build_context_1 = require("./workflow-build-context");
|
|
14
|
+
const workflow_build_remediation_1 = require("./workflow-build-remediation");
|
|
15
|
+
const workflow_build_reporting_1 = require("./workflow-build-reporting");
|
|
16
|
+
const workflow_build_routing_1 = require("./workflow-build-routing");
|
|
17
|
+
const workflow_build_telemetry_1 = require("./workflow-build-telemetry");
|
|
18
|
+
const workflow_file_bindings_1 = require("./workflow-file-bindings");
|
|
14
19
|
const workflow_json_utils_1 = require("./workflow-json-utils");
|
|
15
|
-
const
|
|
20
|
+
const workflow_source_compiler_1 = require("./workflow-source-compiler");
|
|
21
|
+
const workflow_validation_warnings_1 = require("./workflow-validation-warnings");
|
|
16
22
|
const build_failure_tracker_1 = require("../../workflow-builder/build-failure-tracker");
|
|
17
|
-
const extract_code_1 = require("../../workflow-builder/extract-code");
|
|
18
|
-
const patch_code_1 = require("../../workflow-builder/patch-code");
|
|
19
23
|
const remediation_1 = require("../../workflow-loop/remediation");
|
|
20
|
-
const
|
|
21
|
-
old_str: zod_1.z.string().describe('Exact string to find in the code'),
|
|
22
|
-
new_str: zod_1.z.string().describe('Replacement string'),
|
|
23
|
-
});
|
|
24
|
+
const workflow_loop_state_1 = require("../../workflow-loop/workflow-loop-state");
|
|
24
25
|
const confirmationSuspendSchema = zod_1.z.object({
|
|
25
26
|
requestId: zod_1.z.string(),
|
|
26
27
|
message: zod_1.z.string(),
|
|
@@ -29,27 +30,25 @@ const confirmationSuspendSchema = zod_1.z.object({
|
|
|
29
30
|
const confirmationResumeSchema = zod_1.z.object({
|
|
30
31
|
approved: zod_1.z.boolean(),
|
|
31
32
|
});
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
33
|
+
exports.buildWorkflowInputSchema = zod_1.z
|
|
34
|
+
.object({
|
|
35
|
+
filePath: zod_1.z
|
|
36
|
+
.string()
|
|
37
|
+
.min(1)
|
|
38
|
+
.refine((value) => {
|
|
39
|
+
try {
|
|
40
|
+
(0, workflow_file_bindings_1.normalizeWorkflowSourceFilePath)(value);
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}, { message: 'Workflow source file path must stay within the workspace root.' })
|
|
47
|
+
.describe('Workspace path to the workflow source file to build. Supports TypeScript SDK files and WorkflowJSON .json files.'),
|
|
48
|
+
workflowId: zod_1.z
|
|
44
49
|
.string()
|
|
45
50
|
.optional()
|
|
46
|
-
.describe('
|
|
47
|
-
patches: zod_1.z
|
|
48
|
-
.preprocess(coercePatches, zod_1.z.array(patchSchema))
|
|
49
|
-
.optional()
|
|
50
|
-
.describe('Array of {old_str, new_str} replacements to apply to existing workflow code. ' +
|
|
51
|
-
'Requires workflowId. More efficient than resending full code for small fixes.'),
|
|
52
|
-
workflowId: zod_1.z.string().optional().describe('Existing workflow ID to update (omit to create new)'),
|
|
51
|
+
.describe('Existing workflow ID to bind this file to on the first update. Once bound, omit this on retries.'),
|
|
53
52
|
projectId: zod_1.z
|
|
54
53
|
.string()
|
|
55
54
|
.optional()
|
|
@@ -58,13 +57,14 @@ exports.buildWorkflowInputSchema = zod_1.z.object({
|
|
|
58
57
|
workItemId: zod_1.z
|
|
59
58
|
.string()
|
|
60
59
|
.optional()
|
|
61
|
-
.describe('
|
|
60
|
+
.describe('Optional workflow-loop work item ID when repairing a workflow.'),
|
|
62
61
|
isSupportingWorkflow: zod_1.z
|
|
63
62
|
.boolean()
|
|
64
63
|
.optional()
|
|
65
64
|
.describe('Set true when saving a supporting sub-workflow that will be referenced by the main workflow. ' +
|
|
66
65
|
'In a planned build task, this completes the task only when the task itself is marked isSupportingWorkflow; otherwise save the main workflow later.'),
|
|
67
|
-
})
|
|
66
|
+
})
|
|
67
|
+
.strict();
|
|
68
68
|
const triggerNodeOutputSchema = zod_1.z.object({
|
|
69
69
|
nodeName: zod_1.z.string(),
|
|
70
70
|
nodeType: zod_1.z.string(),
|
|
@@ -95,165 +95,17 @@ const setupRequirementOutputSchema = zod_1.z.discriminatedUnion('status', [
|
|
|
95
95
|
guidance: zod_1.z.string(),
|
|
96
96
|
}),
|
|
97
97
|
]);
|
|
98
|
-
function hasMockedCredentials(outcome) {
|
|
99
|
-
return ((outcome.mockedCredentialTypes?.length ?? 0) > 0 ||
|
|
100
|
-
Object.keys(outcome.mockedCredentialsByNode ?? {}).length > 0);
|
|
101
|
-
}
|
|
102
|
-
function hasCredentialVerificationData(outcome) {
|
|
103
|
-
return (Object.keys(outcome.verificationPinData ?? {}).length > 0 ||
|
|
104
|
-
outcome.usesWorkflowPinDataForVerification === true);
|
|
105
|
-
}
|
|
106
|
-
function getBuildFailureTrackingKey({ workItemId, workflowId, workflowName, isAuxiliarySupportingWorkflow, buildContext, runId, }) {
|
|
107
|
-
if (workItemId)
|
|
108
|
-
return workItemId;
|
|
109
|
-
if (isAuxiliarySupportingWorkflow) {
|
|
110
|
-
return [
|
|
111
|
-
'supporting-workflow',
|
|
112
|
-
buildContext?.taskId ?? (runId ? `run:${runId}` : 'unknown-run'),
|
|
113
|
-
workflowId ?? workflowName ?? 'new',
|
|
114
|
-
].join(':');
|
|
115
|
-
}
|
|
116
|
-
return (buildContext?.workItemId ??
|
|
117
|
-
buildContext?.taskId ??
|
|
118
|
-
workflowId ??
|
|
119
|
-
workflowName ??
|
|
120
|
-
`run:${runId ?? 'unknown'}`);
|
|
121
|
-
}
|
|
122
|
-
function determineVerificationReadiness(outcome) {
|
|
123
|
-
if (!outcome.submitted) {
|
|
124
|
-
return {
|
|
125
|
-
status: 'not_verifiable',
|
|
126
|
-
reason: 'not-submitted',
|
|
127
|
-
guidance: 'The build did not submit a workflow, so there is nothing to verify.',
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
if (!outcome.workflowId) {
|
|
131
|
-
return {
|
|
132
|
-
status: 'not_verifiable',
|
|
133
|
-
reason: 'missing-workflow-id',
|
|
134
|
-
guidance: 'The build outcome does not include a workflow ID.',
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
if (outcome.hasUnresolvedPlaceholders) {
|
|
138
|
-
return {
|
|
139
|
-
status: 'needs_setup',
|
|
140
|
-
reason: 'unresolved-placeholders',
|
|
141
|
-
guidance: 'Route the workflow through setup before verification.',
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
if (hasMockedCredentials(outcome) && !hasCredentialVerificationData(outcome)) {
|
|
145
|
-
return {
|
|
146
|
-
status: 'needs_setup',
|
|
147
|
-
reason: 'missing-mocked-credential-pin-data',
|
|
148
|
-
guidance: 'Route the workflow through setup because mocked credentials cannot be verified.',
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
if (!outcome.triggerNodes?.some((node) => (0, workflow_json_utils_1.isMockableTriggerNodeType)(node.nodeType))) {
|
|
152
|
-
return {
|
|
153
|
-
status: 'not_verifiable',
|
|
154
|
-
reason: 'non-mockable-trigger',
|
|
155
|
-
guidance: 'The workflow does not have a trigger the post-build verifier can exercise.',
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
return { status: 'ready' };
|
|
159
|
-
}
|
|
160
|
-
function determineSetupRequirement(outcome) {
|
|
161
|
-
if (!outcome.submitted || !outcome.workflowId) {
|
|
162
|
-
return { status: 'not_required' };
|
|
163
|
-
}
|
|
164
|
-
if (outcome.hasUnresolvedPlaceholders) {
|
|
165
|
-
return {
|
|
166
|
-
status: 'required',
|
|
167
|
-
reason: 'unresolved-placeholders',
|
|
168
|
-
guidance: 'Route the workflow through setup so the user can fill unresolved values.',
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
if (hasMockedCredentials(outcome)) {
|
|
172
|
-
return {
|
|
173
|
-
status: 'required',
|
|
174
|
-
reason: 'mocked-credentials',
|
|
175
|
-
guidance: 'Route the workflow through setup so the user can add real credentials.',
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
return { status: 'not_required' };
|
|
179
|
-
}
|
|
180
|
-
function withDeterministicRouting(outcome) {
|
|
181
|
-
return {
|
|
182
|
-
...outcome,
|
|
183
|
-
verificationReadiness: determineVerificationReadiness(outcome),
|
|
184
|
-
setupRequirement: determineSetupRequirement(outcome),
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
function isApprovedBuildContext(context) {
|
|
188
|
-
const buildContext = context.workflowBuildContext;
|
|
189
|
-
return Boolean(buildContext?.plannedTaskService ?? buildContext?.allowPostPlanWorkflowCreate);
|
|
190
|
-
}
|
|
191
|
-
async function resolveWorkflowName(context, workflowId) {
|
|
192
|
-
try {
|
|
193
|
-
return (await context.workflowService.getAsWorkflowJSON(workflowId)).name || 'workflow';
|
|
194
|
-
}
|
|
195
|
-
catch {
|
|
196
|
-
return 'workflow';
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
async function reportWorkflowBuildOutcome(context, outcome, options = {}) {
|
|
200
|
-
const buildContext = context.workflowBuildContext;
|
|
201
|
-
if (!buildContext)
|
|
202
|
-
return;
|
|
203
|
-
if (options.storeOnRunContext !== false) {
|
|
204
|
-
try {
|
|
205
|
-
await buildContext.onBuildOutcome?.(outcome);
|
|
206
|
-
}
|
|
207
|
-
catch (error) {
|
|
208
|
-
context.logger?.warn('Failed to store workflow build outcome on run context', {
|
|
209
|
-
error: error instanceof Error ? error.message : String(error),
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
try {
|
|
214
|
-
await buildContext.workflowTaskService?.reportBuildOutcome(outcome);
|
|
215
|
-
}
|
|
216
|
-
catch (error) {
|
|
217
|
-
context.logger?.warn('Failed to report workflow build outcome to workflow loop', {
|
|
218
|
-
workItemId: outcome.workItemId,
|
|
219
|
-
error: error instanceof Error ? error.message : String(error),
|
|
220
|
-
});
|
|
221
|
-
}
|
|
222
|
-
if (options.markPlannedTaskSucceeded === false)
|
|
223
|
-
return;
|
|
224
|
-
try {
|
|
225
|
-
await buildContext.plannedTaskService?.markSucceeded(buildContext.threadId, buildContext.taskId, {
|
|
226
|
-
result: outcome.summary,
|
|
227
|
-
outcome,
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
catch (error) {
|
|
231
|
-
context.logger?.warn('Failed to mark planned workflow build task succeeded', {
|
|
232
|
-
taskId: buildContext.taskId,
|
|
233
|
-
error: error instanceof Error ? error.message : String(error),
|
|
234
|
-
});
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
async function promoteMainWorkflow(context, workflowId) {
|
|
238
|
-
try {
|
|
239
|
-
await context.workflowService.clearAiTemporary(workflowId);
|
|
240
|
-
}
|
|
241
|
-
catch (error) {
|
|
242
|
-
context.logger?.warn(`Failed to clear AI-builder temporary marker on main workflow ${workflowId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
98
|
function createBuildWorkflowTool(context) {
|
|
246
|
-
let lastCode = null;
|
|
247
|
-
let lastCodeVersionId = null;
|
|
248
99
|
const failureTracker = new build_failure_tracker_1.BuildFailureTracker();
|
|
249
100
|
return new agents_1.Tool('build-workflow')
|
|
250
|
-
.description('Build a workflow from
|
|
251
|
-
'
|
|
252
|
-
'
|
|
253
|
-
'Patches apply to last submitted code, or auto-fetch from saved workflow if workflowId given.')
|
|
101
|
+
.description('Build and save a workflow from a workspace source file. ' +
|
|
102
|
+
'Use TypeScript SDK source for new workflows, or WorkflowJSON .json source for existing workflow edits. ' +
|
|
103
|
+
'Write or edit the file with workspace file tools, then pass its filePath here.')
|
|
254
104
|
.input(exports.buildWorkflowInputSchema)
|
|
255
105
|
.output(zod_1.z.object({
|
|
256
106
|
success: zod_1.z.boolean(),
|
|
107
|
+
filePath: zod_1.z.string(),
|
|
108
|
+
sourceHash: zod_1.z.string().optional(),
|
|
257
109
|
workflowId: zod_1.z.string().optional(),
|
|
258
110
|
workflowName: zod_1.z.string().optional(),
|
|
259
111
|
workItemId: zod_1.z.string().optional(),
|
|
@@ -264,53 +116,189 @@ function createBuildWorkflowTool(context) {
|
|
|
264
116
|
mockedNodeNames: zod_1.z.array(zod_1.z.string()).optional(),
|
|
265
117
|
mockedCredentialTypes: zod_1.z.array(zod_1.z.string()).optional(),
|
|
266
118
|
mockedCredentialsByNode: zod_1.z.record(zod_1.z.array(zod_1.z.string())).optional(),
|
|
267
|
-
verificationPinData: zod_1.z.record(zod_1.z.array(zod_1.z.record(zod_1.z.unknown()))).optional(),
|
|
268
|
-
usesWorkflowPinDataForVerification: zod_1.z.boolean().optional(),
|
|
269
119
|
referencedWorkflowIds: zod_1.z.array(zod_1.z.string()).optional(),
|
|
270
120
|
hasUnresolvedPlaceholders: zod_1.z.boolean().optional(),
|
|
271
121
|
denied: zod_1.z.boolean().optional(),
|
|
272
122
|
reason: zod_1.z.string().optional(),
|
|
123
|
+
remediation: workflow_loop_state_1.remediationMetadataSchema.optional(),
|
|
273
124
|
errors: zod_1.z.array(zod_1.z.string()).optional(),
|
|
274
125
|
warnings: zod_1.z.array(zod_1.z.string()).optional(),
|
|
275
126
|
}))
|
|
276
127
|
.suspend(confirmationSuspendSchema)
|
|
277
128
|
.resume(confirmationResumeSchema)
|
|
278
129
|
.handler(async (input, ctx) => {
|
|
279
|
-
const
|
|
130
|
+
const filePath = (0, workflow_file_bindings_1.normalizeWorkflowSourceFilePath)(input.filePath);
|
|
131
|
+
let binding = (await (0, workflow_file_bindings_1.getWorkflowSourceFileBinding)(context, filePath)) ?? { filePath };
|
|
132
|
+
if (input.workflowId && binding.workflowId && input.workflowId !== binding.workflowId) {
|
|
133
|
+
const remediation = (0, remediation_1.createRemediation)({
|
|
134
|
+
category: 'blocked',
|
|
135
|
+
shouldEdit: false,
|
|
136
|
+
reason: 'source_file_workflow_mismatch',
|
|
137
|
+
guidance: 'This source file is already bound to a different workflow. Use the bound workflow or start from a different filePath.',
|
|
138
|
+
});
|
|
139
|
+
(0, workflow_build_telemetry_1.trackWorkflowSourceBuild)(context, {
|
|
140
|
+
result: 'blocked',
|
|
141
|
+
stage: 'permission',
|
|
142
|
+
binding,
|
|
143
|
+
targetWorkflowId: binding.workflowId,
|
|
144
|
+
remediation,
|
|
145
|
+
errorCount: 1,
|
|
146
|
+
});
|
|
147
|
+
return {
|
|
148
|
+
success: false,
|
|
149
|
+
...(0, workflow_build_context_1.sourceResponseBase)(binding),
|
|
150
|
+
workflowId: binding.workflowId,
|
|
151
|
+
errors: [
|
|
152
|
+
`Source file ${filePath} is already bound to workflow ${binding.workflowId}; cannot bind it to ${input.workflowId}.`,
|
|
153
|
+
],
|
|
154
|
+
remediation,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
if (input.workflowId && !binding.workflowId) {
|
|
158
|
+
binding = await (0, workflow_file_bindings_1.saveWorkflowSourceFileBinding)(context, {
|
|
159
|
+
...binding,
|
|
160
|
+
workflowId: input.workflowId,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
const targetWorkflowId = binding.workflowId;
|
|
164
|
+
const permKey = targetWorkflowId ? 'updateWorkflow' : 'createWorkflow';
|
|
280
165
|
if (context.permissions?.[permKey] === 'blocked') {
|
|
281
|
-
|
|
166
|
+
const remediation = (0, remediation_1.createRemediation)({
|
|
167
|
+
category: 'blocked',
|
|
168
|
+
shouldEdit: false,
|
|
169
|
+
reason: 'permission_blocked',
|
|
170
|
+
guidance: 'The requested workflow save action is blocked by admin policy.',
|
|
171
|
+
});
|
|
172
|
+
(0, workflow_build_telemetry_1.trackWorkflowSourceBuild)(context, {
|
|
173
|
+
result: 'blocked',
|
|
174
|
+
stage: 'permission',
|
|
175
|
+
binding,
|
|
176
|
+
targetWorkflowId,
|
|
177
|
+
isSupportingWorkflow: input.isSupportingWorkflow,
|
|
178
|
+
remediation,
|
|
179
|
+
errorCount: 1,
|
|
180
|
+
});
|
|
181
|
+
return {
|
|
182
|
+
success: false,
|
|
183
|
+
...(0, workflow_build_context_1.sourceResponseBase)(binding),
|
|
184
|
+
workflowId: targetWorkflowId,
|
|
185
|
+
errors: ['Action blocked by admin'],
|
|
186
|
+
remediation,
|
|
187
|
+
};
|
|
282
188
|
}
|
|
283
|
-
if (
|
|
284
|
-
!isApprovedBuildContext(context) &&
|
|
189
|
+
if (targetWorkflowId &&
|
|
190
|
+
!(0, workflow_build_context_1.isApprovedBuildContext)(context) &&
|
|
285
191
|
context.permissions?.updateWorkflow !== 'always_allow') {
|
|
286
192
|
if (ctx.resumeData && !ctx.resumeData.approved) {
|
|
193
|
+
const remediation = (0, remediation_1.createRemediation)({
|
|
194
|
+
category: 'blocked',
|
|
195
|
+
shouldEdit: false,
|
|
196
|
+
reason: 'user_denied',
|
|
197
|
+
guidance: 'The user denied permission to edit this workflow.',
|
|
198
|
+
});
|
|
199
|
+
(0, workflow_build_telemetry_1.trackWorkflowSourceBuild)(context, {
|
|
200
|
+
result: 'denied',
|
|
201
|
+
stage: 'hitl',
|
|
202
|
+
binding,
|
|
203
|
+
targetWorkflowId,
|
|
204
|
+
isSupportingWorkflow: input.isSupportingWorkflow,
|
|
205
|
+
remediation,
|
|
206
|
+
errorCount: 1,
|
|
207
|
+
});
|
|
287
208
|
return {
|
|
288
209
|
success: false,
|
|
210
|
+
...(0, workflow_build_context_1.sourceResponseBase)(binding),
|
|
211
|
+
workflowId: targetWorkflowId,
|
|
289
212
|
denied: true,
|
|
290
213
|
reason: 'User denied the action',
|
|
291
214
|
errors: ['User denied the action'],
|
|
215
|
+
remediation,
|
|
292
216
|
};
|
|
293
217
|
}
|
|
294
218
|
if (!ctx.resumeData) {
|
|
295
219
|
if (!ctx.suspend) {
|
|
296
|
-
|
|
220
|
+
const remediation = (0, remediation_1.createRemediation)({
|
|
221
|
+
category: 'blocked',
|
|
222
|
+
shouldEdit: false,
|
|
223
|
+
reason: 'approval_required',
|
|
224
|
+
guidance: 'Workflow edit approval is required before saving this source file.',
|
|
225
|
+
});
|
|
226
|
+
(0, workflow_build_telemetry_1.trackWorkflowSourceBuild)(context, {
|
|
227
|
+
result: 'blocked',
|
|
228
|
+
stage: 'hitl',
|
|
229
|
+
binding,
|
|
230
|
+
targetWorkflowId,
|
|
231
|
+
isSupportingWorkflow: input.isSupportingWorkflow,
|
|
232
|
+
remediation,
|
|
233
|
+
errorCount: 1,
|
|
234
|
+
});
|
|
235
|
+
return {
|
|
236
|
+
success: false,
|
|
237
|
+
...(0, workflow_build_context_1.sourceResponseBase)(binding),
|
|
238
|
+
workflowId: targetWorkflowId,
|
|
239
|
+
errors: ['Workflow edit approval is required.'],
|
|
240
|
+
remediation,
|
|
241
|
+
};
|
|
297
242
|
}
|
|
298
|
-
const workflowName = await resolveWorkflowName(context,
|
|
243
|
+
const workflowName = await (0, workflow_build_context_1.resolveWorkflowName)(context, targetWorkflowId);
|
|
244
|
+
(0, workflow_build_telemetry_1.trackWorkflowSourceBuild)(context, {
|
|
245
|
+
result: 'suspended',
|
|
246
|
+
stage: 'hitl',
|
|
247
|
+
binding,
|
|
248
|
+
targetWorkflowId,
|
|
249
|
+
isSupportingWorkflow: input.isSupportingWorkflow,
|
|
250
|
+
});
|
|
299
251
|
return await ctx.suspend({
|
|
300
252
|
requestId: (0, nanoid_1.nanoid)(),
|
|
301
|
-
message: `Edit ${workflowName} (ID: ${
|
|
253
|
+
message: `Edit ${workflowName} (ID: ${targetWorkflowId})?`,
|
|
302
254
|
severity: 'warning',
|
|
303
255
|
});
|
|
304
256
|
}
|
|
305
257
|
}
|
|
306
|
-
|
|
258
|
+
let sourceCode;
|
|
259
|
+
let sourceHash;
|
|
260
|
+
try {
|
|
261
|
+
({ source: sourceCode, sourceHash } = await (0, workflow_file_bindings_1.readWorkflowSourceFile)(context, filePath));
|
|
262
|
+
}
|
|
263
|
+
catch (error) {
|
|
264
|
+
const remediation = (0, workflow_build_remediation_1.createCodeFixableRemediation)({
|
|
265
|
+
reason: 'workflow_source_read_failed',
|
|
266
|
+
guidance: 'The workflow source file could not be read. Recreate or edit the returned filePath, then call build-workflow again with the same filePath.',
|
|
267
|
+
});
|
|
268
|
+
(0, workflow_build_telemetry_1.trackWorkflowSourceBuild)(context, {
|
|
269
|
+
result: 'failure',
|
|
270
|
+
stage: 'source_read',
|
|
271
|
+
binding,
|
|
272
|
+
targetWorkflowId,
|
|
273
|
+
isSupportingWorkflow: input.isSupportingWorkflow,
|
|
274
|
+
remediation,
|
|
275
|
+
errorCount: 1,
|
|
276
|
+
});
|
|
277
|
+
return {
|
|
278
|
+
success: false,
|
|
279
|
+
...(0, workflow_build_context_1.sourceResponseBase)(binding),
|
|
280
|
+
workflowId: targetWorkflowId,
|
|
281
|
+
errors: [error instanceof Error ? error.message : String(error)],
|
|
282
|
+
remediation,
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
if (sourceHash !== binding.sourceHash) {
|
|
286
|
+
binding = await (0, workflow_file_bindings_1.saveWorkflowSourceFileBinding)(context, { ...binding, sourceHash });
|
|
287
|
+
}
|
|
288
|
+
const { projectId, name } = input;
|
|
307
289
|
const isSupportingWorkflow = input.isSupportingWorkflow === true;
|
|
308
290
|
const buildContext = context.workflowBuildContext;
|
|
309
|
-
const isAuxiliarySupportingWorkflow
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
291
|
+
const { isAuxiliarySupportingWorkflow, plannedTaskId, owner, resolvedWorkItemId, resolvedTaskId, } = (0, workflow_build_context_1.resolveBuildIdentifiers)({
|
|
292
|
+
context,
|
|
293
|
+
filePath,
|
|
294
|
+
inputWorkItemId: input.workItemId,
|
|
295
|
+
isSupportingWorkflow,
|
|
296
|
+
});
|
|
297
|
+
const workItemKey = (0, workflow_build_context_1.getBuildFailureTrackingKey)({
|
|
298
|
+
workItemId: resolvedWorkItemId,
|
|
299
|
+
workflowId: targetWorkflowId,
|
|
313
300
|
workflowName: name,
|
|
301
|
+
filePath,
|
|
314
302
|
isAuxiliarySupportingWorkflow,
|
|
315
303
|
buildContext,
|
|
316
304
|
runId: context.runId,
|
|
@@ -319,101 +307,139 @@ function createBuildWorkflowTool(context) {
|
|
|
319
307
|
const escalation = failureTracker.record(workItemKey, errors, options);
|
|
320
308
|
return escalation ? [...errors, escalation] : errors;
|
|
321
309
|
};
|
|
322
|
-
let
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
if (!baseCode) {
|
|
353
|
-
return {
|
|
354
|
-
success: false,
|
|
355
|
-
errors: [
|
|
356
|
-
'Patch mode requires either a previous build-workflow call or a workflowId to fetch from.',
|
|
357
|
-
],
|
|
358
|
-
};
|
|
359
|
-
}
|
|
360
|
-
const patchResult = (0, patch_code_1.applyPatches)(baseCode, patches);
|
|
361
|
-
if (!patchResult.success) {
|
|
362
|
-
return { success: false, errors: [patchResult.error] };
|
|
363
|
-
}
|
|
364
|
-
finalCode = patchResult.code;
|
|
365
|
-
}
|
|
366
|
-
else if (code) {
|
|
367
|
-
finalCode = (0, extract_code_1.extractWorkflowCode)(code);
|
|
368
|
-
}
|
|
369
|
-
else {
|
|
370
|
-
return {
|
|
371
|
-
success: false,
|
|
372
|
-
errors: ['Either `code` (full code) or `patches` (to fix previous code) is required.'],
|
|
373
|
-
};
|
|
374
|
-
}
|
|
375
|
-
lastCode = finalCode;
|
|
376
|
-
let result;
|
|
377
|
-
try {
|
|
378
|
-
result = (0, workflow_builder_1.parseAndValidate)(finalCode, {
|
|
379
|
-
nodeTypesProvider: context.nodeTypesProvider,
|
|
310
|
+
let informational = [];
|
|
311
|
+
const compiled = await (0, workflow_source_compiler_1.compileWorkflowSource)(context, filePath, sourceCode);
|
|
312
|
+
if (!compiled.success) {
|
|
313
|
+
const errors = compiled.editable ? withEscalation(compiled.errors) : compiled.errors;
|
|
314
|
+
const remediation = (0, workflow_build_remediation_1.createSourceCompileRemediation)({
|
|
315
|
+
reason: compiled.reason,
|
|
316
|
+
editable: compiled.editable,
|
|
317
|
+
});
|
|
318
|
+
binding = await (0, workflow_build_context_1.markSourceBuildFailed)(context, binding, sourceHash);
|
|
319
|
+
await (0, workflow_build_reporting_1.reportFailedWorkflowBuildOutcome)(context, {
|
|
320
|
+
targetWorkflowId,
|
|
321
|
+
sourceFilePath: filePath,
|
|
322
|
+
workItemId: resolvedWorkItemId,
|
|
323
|
+
taskId: resolvedTaskId,
|
|
324
|
+
plannedTaskId,
|
|
325
|
+
owner,
|
|
326
|
+
remediation,
|
|
327
|
+
errors,
|
|
328
|
+
summary: compiled.summary,
|
|
329
|
+
storeOnRunContext: !isAuxiliarySupportingWorkflow,
|
|
330
|
+
});
|
|
331
|
+
(0, workflow_build_telemetry_1.trackWorkflowSourceBuild)(context, {
|
|
332
|
+
result: remediation.category === 'blocked' ? 'blocked' : 'failure',
|
|
333
|
+
stage: 'parse',
|
|
334
|
+
binding,
|
|
335
|
+
targetWorkflowId,
|
|
336
|
+
isSupportingWorkflow,
|
|
337
|
+
isAuxiliarySupportingWorkflow,
|
|
338
|
+
remediation,
|
|
339
|
+
errorCount: errors.length,
|
|
380
340
|
});
|
|
381
|
-
}
|
|
382
|
-
catch (error) {
|
|
383
341
|
return {
|
|
384
342
|
success: false,
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
343
|
+
...(0, workflow_build_context_1.sourceResponseBase)(binding),
|
|
344
|
+
workflowId: targetWorkflowId,
|
|
345
|
+
workItemId: resolvedWorkItemId,
|
|
346
|
+
errors,
|
|
347
|
+
remediation,
|
|
388
348
|
};
|
|
389
349
|
}
|
|
390
|
-
const
|
|
391
|
-
|
|
350
|
+
const partitionedWarnings = (0, workflow_validation_warnings_1.partitionWarnings)(compiled.warnings);
|
|
351
|
+
informational = partitionedWarnings.informational;
|
|
352
|
+
if (partitionedWarnings.errors.length > 0) {
|
|
353
|
+
const formattedErrors = withEscalation(partitionedWarnings.errors.map((e) => `[${e.code}]${e.nodeName ? ` (${e.nodeName})` : ''}: ${e.message}`));
|
|
354
|
+
const remediation = (0, workflow_build_remediation_1.createCodeFixableRemediation)({
|
|
355
|
+
reason: 'workflow_source_validation_failed',
|
|
356
|
+
guidance: 'Edit the workspace source file using the validation diagnostics, then call build-workflow again with the same filePath.',
|
|
357
|
+
});
|
|
358
|
+
binding = await (0, workflow_build_context_1.markSourceBuildFailed)(context, binding, sourceHash);
|
|
359
|
+
await (0, workflow_build_reporting_1.reportFailedWorkflowBuildOutcome)(context, {
|
|
360
|
+
targetWorkflowId,
|
|
361
|
+
sourceFilePath: filePath,
|
|
362
|
+
workItemId: resolvedWorkItemId,
|
|
363
|
+
taskId: resolvedTaskId,
|
|
364
|
+
plannedTaskId,
|
|
365
|
+
owner,
|
|
366
|
+
remediation,
|
|
367
|
+
errors: formattedErrors,
|
|
368
|
+
summary: 'Workflow source failed validation.',
|
|
369
|
+
storeOnRunContext: !isAuxiliarySupportingWorkflow,
|
|
370
|
+
});
|
|
371
|
+
(0, workflow_build_telemetry_1.trackWorkflowSourceBuild)(context, {
|
|
372
|
+
result: 'failure',
|
|
373
|
+
stage: 'validation',
|
|
374
|
+
binding,
|
|
375
|
+
targetWorkflowId,
|
|
376
|
+
isSupportingWorkflow,
|
|
377
|
+
isAuxiliarySupportingWorkflow,
|
|
378
|
+
remediation,
|
|
379
|
+
errorCount: formattedErrors.length,
|
|
380
|
+
warningCount: informational.length,
|
|
381
|
+
});
|
|
392
382
|
return {
|
|
393
383
|
success: false,
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
384
|
+
...(0, workflow_build_context_1.sourceResponseBase)(binding),
|
|
385
|
+
workflowId: targetWorkflowId,
|
|
386
|
+
workItemId: resolvedWorkItemId,
|
|
387
|
+
errors: formattedErrors,
|
|
388
|
+
remediation,
|
|
389
|
+
warnings: (0, workflow_build_context_1.combineWarnings)(informational.map((w) => (0, workflow_build_context_1.formatWarning)(w.code, w.message))),
|
|
398
390
|
};
|
|
399
391
|
}
|
|
400
|
-
const json =
|
|
392
|
+
const json = compiled.workflow;
|
|
401
393
|
if (name) {
|
|
402
394
|
json.name = name;
|
|
403
395
|
}
|
|
404
|
-
else if (!json.name && !
|
|
396
|
+
else if (!json.name && !targetWorkflowId) {
|
|
397
|
+
const remediation = (0, workflow_build_remediation_1.createCodeFixableRemediation)({
|
|
398
|
+
reason: 'workflow_name_missing',
|
|
399
|
+
guidance: 'Add a workflow name in the workspace source file or pass the name parameter, then call build-workflow again with the same filePath.',
|
|
400
|
+
});
|
|
401
|
+
binding = await (0, workflow_build_context_1.markSourceBuildFailed)(context, binding, sourceHash);
|
|
402
|
+
await (0, workflow_build_reporting_1.reportFailedWorkflowBuildOutcome)(context, {
|
|
403
|
+
targetWorkflowId,
|
|
404
|
+
sourceFilePath: filePath,
|
|
405
|
+
workItemId: resolvedWorkItemId,
|
|
406
|
+
taskId: resolvedTaskId,
|
|
407
|
+
plannedTaskId,
|
|
408
|
+
owner,
|
|
409
|
+
remediation,
|
|
410
|
+
errors: [
|
|
411
|
+
'Workflow name is required for new workflows. Provide a name parameter or set it in the SDK code.',
|
|
412
|
+
],
|
|
413
|
+
summary: 'Workflow source is missing a workflow name.',
|
|
414
|
+
storeOnRunContext: !isAuxiliarySupportingWorkflow,
|
|
415
|
+
});
|
|
416
|
+
(0, workflow_build_telemetry_1.trackWorkflowSourceBuild)(context, {
|
|
417
|
+
result: 'failure',
|
|
418
|
+
stage: 'name',
|
|
419
|
+
binding,
|
|
420
|
+
targetWorkflowId,
|
|
421
|
+
isSupportingWorkflow,
|
|
422
|
+
isAuxiliarySupportingWorkflow,
|
|
423
|
+
remediation,
|
|
424
|
+
errorCount: 1,
|
|
425
|
+
});
|
|
405
426
|
return {
|
|
406
427
|
success: false,
|
|
428
|
+
...(0, workflow_build_context_1.sourceResponseBase)(binding),
|
|
429
|
+
workflowId: targetWorkflowId,
|
|
430
|
+
workItemId: resolvedWorkItemId,
|
|
407
431
|
errors: [
|
|
408
432
|
'Workflow name is required for new workflows. Provide a name parameter or set it in the SDK code.',
|
|
409
433
|
],
|
|
434
|
+
remediation,
|
|
410
435
|
};
|
|
411
436
|
}
|
|
412
437
|
const credentialMap = await (0, resolve_credentials_1.buildCredentialMap)(context.credentialService);
|
|
413
|
-
const mockResult = await (0, resolve_credentials_1.resolveCredentials)(json,
|
|
438
|
+
const mockResult = await (0, resolve_credentials_1.resolveCredentials)(json, targetWorkflowId, context, credentialMap);
|
|
414
439
|
await (0, setup_workflow_service_1.stripStaleCredentialsFromWorkflow)(context, json);
|
|
415
|
-
await (0, submit_workflow_tool_1.ensureWebhookIds)(json, workflowId, context);
|
|
416
440
|
try {
|
|
441
|
+
await (0, workflow_json_utils_1.ensureWebhookIds)(json, targetWorkflowId, context);
|
|
442
|
+
await (0, workflow_json_utils_1.preserveExistingNodeGroupIds)(json, targetWorkflowId, context);
|
|
417
443
|
const hasMockedCredentialNodes = mockResult.mockedNodeNames.length > 0;
|
|
418
444
|
const referencedWorkflowIds = (0, workflow_json_utils_1.getReferencedWorkflowIds)(json);
|
|
419
445
|
const triggerNodes = (json.nodes ?? [])
|
|
@@ -421,43 +447,35 @@ function createBuildWorkflowTool(context) {
|
|
|
421
447
|
.map((n) => ({ nodeName: n.name, nodeType: n.type }))
|
|
422
448
|
.filter((t) => Boolean(t.nodeName) && Boolean(t.nodeType));
|
|
423
449
|
const hasPlaceholders = (json.nodes ?? []).some((n) => (0, utils_1.hasPlaceholderDeep)(n.parameters));
|
|
424
|
-
const
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
`wi_${(0, nanoid_1.nanoid)(8)}`;
|
|
433
|
-
const resolvedTaskId = isAuxiliarySupportingWorkflow
|
|
434
|
-
? `${buildContext?.taskId ?? (context.runId ? `build-${context.runId}` : 'build')}:supporting-${(0, nanoid_1.nanoid)(6)}`
|
|
435
|
-
: (buildContext?.taskId ??
|
|
436
|
-
(context.runId ? `build-${context.runId}` : `build-${(0, nanoid_1.nanoid)(8)}`));
|
|
437
|
-
const createSuccessResponse = async (savedId) => {
|
|
450
|
+
const createSuccessResponse = async (saved, operation) => {
|
|
451
|
+
const { nodeSimulationPlan, simulationFixtures } = await (0, plan_verification_simulation_1.planVerificationSimulation)({
|
|
452
|
+
workflow: json,
|
|
453
|
+
mockedNodeNames: mockResult.mockedNodeNames,
|
|
454
|
+
declaredOutputFixtures: compiled.declaredOutputFixtures,
|
|
455
|
+
workflowId: saved.id,
|
|
456
|
+
logger: context.logger,
|
|
457
|
+
});
|
|
438
458
|
const runId = buildContext?.runId ?? context.runId;
|
|
439
459
|
const workflowName = json.name || 'workflow';
|
|
440
|
-
const summary = `${
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
: undefined;
|
|
449
|
-
const outcome = withDeterministicRouting({
|
|
460
|
+
const summary = `${operation === 'update' ? 'Updated' : 'Created'} ${isSupportingWorkflow ? 'supporting ' : ''}workflow "${workflowName}" (${saved.id}).`;
|
|
461
|
+
binding = await (0, workflow_file_bindings_1.saveWorkflowSourceFileBinding)(context, {
|
|
462
|
+
...binding,
|
|
463
|
+
workflowId: saved.id,
|
|
464
|
+
workflowVersionId: saved.versionId,
|
|
465
|
+
sourceHash,
|
|
466
|
+
});
|
|
467
|
+
const outcome = (0, workflow_build_routing_1.withDeterministicRouting)({
|
|
450
468
|
workItemId: resolvedWorkItemId,
|
|
451
469
|
...(runId ? { runId } : {}),
|
|
452
470
|
taskId: resolvedTaskId,
|
|
453
471
|
owner,
|
|
454
472
|
plannedTaskId,
|
|
455
|
-
workflowId:
|
|
473
|
+
workflowId: saved.id,
|
|
474
|
+
sourceFilePath: filePath,
|
|
456
475
|
submitted: true,
|
|
457
476
|
triggerType: 'manual_or_testable',
|
|
458
477
|
triggerNodes,
|
|
459
|
-
needsUserInput:
|
|
460
|
-
blockingReason: placeholderRemediation?.guidance,
|
|
478
|
+
needsUserInput: false,
|
|
461
479
|
mockedNodeNames: hasMockedCredentialNodes ? mockResult.mockedNodeNames : undefined,
|
|
462
480
|
mockedCredentialTypes: hasMockedCredentialNodes
|
|
463
481
|
? mockResult.mockedCredentialTypes
|
|
@@ -465,24 +483,33 @@ function createBuildWorkflowTool(context) {
|
|
|
465
483
|
mockedCredentialsByNode: hasMockedCredentialNodes
|
|
466
484
|
? mockResult.mockedCredentialsByNode
|
|
467
485
|
: undefined,
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
: undefined,
|
|
471
|
-
usesWorkflowPinDataForVerification: mockResult.usesWorkflowPinDataForVerification || undefined,
|
|
486
|
+
nodeSimulationPlan,
|
|
487
|
+
simulationFixtures,
|
|
472
488
|
supportingWorkflowIds: referencedWorkflowIds.length > 0 ? referencedWorkflowIds : undefined,
|
|
473
489
|
hasUnresolvedPlaceholders: hasPlaceholders || undefined,
|
|
474
|
-
remediation: placeholderRemediation,
|
|
475
490
|
summary,
|
|
476
491
|
});
|
|
477
|
-
await promoteMainWorkflow(context,
|
|
478
|
-
await reportWorkflowBuildOutcome(context, outcome, {
|
|
492
|
+
await (0, workflow_build_reporting_1.promoteMainWorkflow)(context, saved.id);
|
|
493
|
+
await (0, workflow_build_reporting_1.reportWorkflowBuildOutcome)(context, outcome, {
|
|
479
494
|
storeOnRunContext: !isAuxiliarySupportingWorkflow,
|
|
480
495
|
markPlannedTaskSucceeded: !isAuxiliarySupportingWorkflow,
|
|
481
496
|
});
|
|
482
497
|
failureTracker.clear(workItemKey);
|
|
498
|
+
(0, workflow_build_telemetry_1.trackWorkflowSourceBuild)(context, {
|
|
499
|
+
result: 'success',
|
|
500
|
+
stage: 'save',
|
|
501
|
+
binding,
|
|
502
|
+
targetWorkflowId,
|
|
503
|
+
savedWorkflowId: saved.id,
|
|
504
|
+
saveOperation: operation,
|
|
505
|
+
isSupportingWorkflow,
|
|
506
|
+
isAuxiliarySupportingWorkflow,
|
|
507
|
+
warningCount: informational.length,
|
|
508
|
+
});
|
|
483
509
|
return {
|
|
484
510
|
success: true,
|
|
485
|
-
|
|
511
|
+
...(0, workflow_build_context_1.sourceResponseBase)(binding),
|
|
512
|
+
workflowId: saved.id,
|
|
486
513
|
workflowName: json.name || undefined,
|
|
487
514
|
workItemId: resolvedWorkItemId,
|
|
488
515
|
isSupportingWorkflow: isSupportingWorkflow || undefined,
|
|
@@ -496,38 +523,57 @@ function createBuildWorkflowTool(context) {
|
|
|
496
523
|
mockedCredentialsByNode: hasMockedCredentialNodes
|
|
497
524
|
? mockResult.mockedCredentialsByNode
|
|
498
525
|
: undefined,
|
|
499
|
-
verificationPinData: hasMockedCredentialNodes && Object.keys(mockResult.verificationPinData).length > 0
|
|
500
|
-
? mockResult.verificationPinData
|
|
501
|
-
: undefined,
|
|
502
|
-
usesWorkflowPinDataForVerification: mockResult.usesWorkflowPinDataForVerification || undefined,
|
|
503
526
|
referencedWorkflowIds: referencedWorkflowIds.length > 0 ? referencedWorkflowIds : undefined,
|
|
504
527
|
hasUnresolvedPlaceholders: hasPlaceholders || undefined,
|
|
505
|
-
warnings: informational.
|
|
506
|
-
? informational.map((w) => `[${w.code}]: ${w.message}`)
|
|
507
|
-
: undefined,
|
|
528
|
+
warnings: (0, workflow_build_context_1.combineWarnings)(informational.map((w) => (0, workflow_build_context_1.formatWarning)(w.code, w.message))),
|
|
508
529
|
};
|
|
509
530
|
};
|
|
510
|
-
if (
|
|
511
|
-
const updated = await context.workflowService.updateFromWorkflowJSON(
|
|
512
|
-
|
|
513
|
-
return await createSuccessResponse(updated.id);
|
|
514
|
-
}
|
|
515
|
-
else {
|
|
516
|
-
const created = await context.workflowService.createFromWorkflowJSON(json, {
|
|
517
|
-
...(projectId ? { projectId } : {}),
|
|
518
|
-
markAsAiTemporary: true,
|
|
519
|
-
});
|
|
520
|
-
(context.aiCreatedWorkflowIds ??= new Set()).add(created.id);
|
|
521
|
-
lastCodeVersionId = created.versionId;
|
|
522
|
-
return await createSuccessResponse(created.id);
|
|
531
|
+
if (targetWorkflowId) {
|
|
532
|
+
const updated = await context.workflowService.updateFromWorkflowJSON(targetWorkflowId, json, projectId ? { projectId } : undefined);
|
|
533
|
+
return await createSuccessResponse(updated, 'update');
|
|
523
534
|
}
|
|
535
|
+
const created = await context.workflowService.createFromWorkflowJSON(json, {
|
|
536
|
+
...(projectId ? { projectId } : {}),
|
|
537
|
+
markAsAiTemporary: true,
|
|
538
|
+
});
|
|
539
|
+
(context.aiCreatedWorkflowIds ??= new Set()).add(created.id);
|
|
540
|
+
return await createSuccessResponse(created, 'create');
|
|
524
541
|
}
|
|
525
542
|
catch (error) {
|
|
543
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
544
|
+
const remediation = (0, workflow_build_remediation_1.createSaveFailureRemediation)(error, Boolean(binding.workflowId));
|
|
545
|
+
binding = await (0, workflow_build_context_1.markSourceBuildFailed)(context, binding, sourceHash);
|
|
546
|
+
await (0, workflow_build_reporting_1.reportFailedWorkflowBuildOutcome)(context, {
|
|
547
|
+
targetWorkflowId,
|
|
548
|
+
sourceFilePath: filePath,
|
|
549
|
+
workItemId: resolvedWorkItemId,
|
|
550
|
+
taskId: resolvedTaskId,
|
|
551
|
+
plannedTaskId,
|
|
552
|
+
owner,
|
|
553
|
+
remediation,
|
|
554
|
+
errors: [`Workflow save failed: ${message}`],
|
|
555
|
+
summary: 'Workflow source parsed but did not save.',
|
|
556
|
+
storeOnRunContext: !isAuxiliarySupportingWorkflow,
|
|
557
|
+
});
|
|
558
|
+
(0, workflow_build_telemetry_1.trackWorkflowSourceBuild)(context, {
|
|
559
|
+
result: remediation.category === 'blocked' ? 'blocked' : 'failure',
|
|
560
|
+
stage: 'save',
|
|
561
|
+
binding,
|
|
562
|
+
targetWorkflowId,
|
|
563
|
+
saveOperation: targetWorkflowId ? 'update' : 'create',
|
|
564
|
+
isSupportingWorkflow,
|
|
565
|
+
isAuxiliarySupportingWorkflow,
|
|
566
|
+
remediation,
|
|
567
|
+
errorCount: 1,
|
|
568
|
+
});
|
|
526
569
|
return {
|
|
527
570
|
success: false,
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
571
|
+
...(0, workflow_build_context_1.sourceResponseBase)(binding),
|
|
572
|
+
workflowId: targetWorkflowId,
|
|
573
|
+
workflowName: json.name || undefined,
|
|
574
|
+
workItemId: resolvedWorkItemId,
|
|
575
|
+
errors: [`Workflow save failed: ${message}`],
|
|
576
|
+
remediation,
|
|
531
577
|
};
|
|
532
578
|
}
|
|
533
579
|
})
|