@dypai-ai/mcp 1.7.3 → 1.7.4
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/package.json +1 -1
- package/src/lib/cloudBackendCompiler.js +4 -1
- package/src/tools/proxy.js +16 -6
- package/src/tools/sync/planner.js +8 -10
- package/src/tools/sync/push.js +66 -1
package/package.json
CHANGED
|
@@ -23,7 +23,10 @@ async function compileSnapshot(projectId, command, files, endpoint = undefined)
|
|
|
23
23
|
files,
|
|
24
24
|
}
|
|
25
25
|
if (endpoint) args.endpoint = endpoint
|
|
26
|
-
|
|
26
|
+
// Compiler `ok:false` is a domain validation result, not a transport/tool
|
|
27
|
+
// failure. It intentionally carries valid payloads plus diagnostics so the
|
|
28
|
+
// push pipeline can skip only broken flows instead of dropping all source.
|
|
29
|
+
return proxyToolCall("backend_compile_snapshot", args, { allowFailureResult: true })
|
|
27
30
|
}
|
|
28
31
|
|
|
29
32
|
export async function buildSnapshotPayload(dypaiRootDir, projectRoot = null) {
|
package/src/tools/proxy.js
CHANGED
|
@@ -209,7 +209,15 @@ async function ensureInitialized() {
|
|
|
209
209
|
return initPromise
|
|
210
210
|
}
|
|
211
211
|
|
|
212
|
-
|
|
212
|
+
function shouldPromoteRemoteFailure(parsed, allowFailureResult = false) {
|
|
213
|
+
return !allowFailureResult
|
|
214
|
+
&& parsed
|
|
215
|
+
&& typeof parsed === "object"
|
|
216
|
+
&& !Array.isArray(parsed)
|
|
217
|
+
&& (parsed.success === false || parsed.ok === false)
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export async function proxyToolCall(toolName, args, { allowFailureResult = false } = {}) {
|
|
213
221
|
async function callOnce() {
|
|
214
222
|
await ensureInitialized()
|
|
215
223
|
|
|
@@ -242,11 +250,9 @@ export async function proxyToolCall(toolName, args) {
|
|
|
242
250
|
// Other remote errors come as a JSON object with success:false but no isError
|
|
243
251
|
// flag. The push pipeline was treating these as successes — promote them to
|
|
244
252
|
// throws here so the caller's try/catch sees them.
|
|
245
|
-
if (parsed
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
throw new Error(typeof msg === "string" ? msg : JSON.stringify(msg))
|
|
249
|
-
}
|
|
253
|
+
if (shouldPromoteRemoteFailure(parsed, allowFailureResult)) {
|
|
254
|
+
const msg = parsed.error || parsed.message || parsed.detail || JSON.stringify(parsed).slice(0, 300)
|
|
255
|
+
throw new Error(typeof msg === "string" ? msg : JSON.stringify(msg))
|
|
250
256
|
}
|
|
251
257
|
return parsed
|
|
252
258
|
}
|
|
@@ -270,3 +276,7 @@ export async function proxyToolCall(toolName, args) {
|
|
|
270
276
|
throw error
|
|
271
277
|
}
|
|
272
278
|
}
|
|
279
|
+
|
|
280
|
+
export const __testing = {
|
|
281
|
+
shouldPromoteRemoteFailure,
|
|
282
|
+
}
|
|
@@ -539,15 +539,6 @@ export async function readLocalEffectiveState(rootDir, projectId = null, deps =
|
|
|
539
539
|
if (shadowedMeta) shadowed.push({ name: payload.name, shadowed: shadowedMeta })
|
|
540
540
|
}
|
|
541
541
|
|
|
542
|
-
for (const diagnostic of diagnostics) {
|
|
543
|
-
if (diagnostic?.severity !== "error") continue
|
|
544
|
-
yamlState.errors.push({
|
|
545
|
-
file: diagnostic.file || diagnostic.endpoint,
|
|
546
|
-
error: diagnostic.message || "Failed to build flow push payload",
|
|
547
|
-
rule: diagnostic.rule || "flow_push_payload_failed",
|
|
548
|
-
})
|
|
549
|
-
}
|
|
550
|
-
|
|
551
542
|
for (const item of rejected) {
|
|
552
543
|
if (!isBackendSourcePath(item?.path)) continue
|
|
553
544
|
yamlState.errors.push({
|
|
@@ -562,7 +553,14 @@ export async function readLocalEffectiveState(rootDir, projectId = null, deps =
|
|
|
562
553
|
byName[name] = { ...entry, source: "legacy-yaml" }
|
|
563
554
|
}
|
|
564
555
|
|
|
565
|
-
return {
|
|
556
|
+
return {
|
|
557
|
+
byName,
|
|
558
|
+
errors: yamlState.errors,
|
|
559
|
+
shadowed,
|
|
560
|
+
runnerWarning: null,
|
|
561
|
+
compilerDiagnostics: diagnostics,
|
|
562
|
+
automations: bulkResult.data?.automations ?? null,
|
|
563
|
+
}
|
|
566
564
|
}
|
|
567
565
|
|
|
568
566
|
// ─── Normalization + diff ──────────────────────────────────────────────────
|
package/src/tools/sync/push.js
CHANGED
|
@@ -310,6 +310,41 @@ function dropErroringFromPlan(plan, erroringEndpoints, skippedDiagnostics) {
|
|
|
310
310
|
: undefined
|
|
311
311
|
}
|
|
312
312
|
|
|
313
|
+
function skippedEndpointsFromDiagnostics(diagnostics) {
|
|
314
|
+
const names = [...new Set(
|
|
315
|
+
(diagnostics || [])
|
|
316
|
+
.filter((item) => item?.severity === "error" && item.endpoint)
|
|
317
|
+
.map((item) => item.endpoint),
|
|
318
|
+
)]
|
|
319
|
+
return names.length
|
|
320
|
+
? names.map((name) => ({
|
|
321
|
+
endpoint: name,
|
|
322
|
+
errors: diagnostics
|
|
323
|
+
.filter((item) => item.endpoint === name && item.severity === "error")
|
|
324
|
+
.slice(0, 5)
|
|
325
|
+
.map((item) => ({
|
|
326
|
+
rule: item.rule,
|
|
327
|
+
message: item.message,
|
|
328
|
+
file: item.file,
|
|
329
|
+
loc: item.loc,
|
|
330
|
+
})),
|
|
331
|
+
}))
|
|
332
|
+
: undefined
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
function mergeSkippedEndpointSummaries(...groups) {
|
|
336
|
+
const merged = new Map()
|
|
337
|
+
for (const group of groups) {
|
|
338
|
+
for (const item of group || []) {
|
|
339
|
+
const current = merged.get(item.endpoint)
|
|
340
|
+
merged.set(item.endpoint, current
|
|
341
|
+
? { ...current, errors: [...(current.errors || []), ...(item.errors || [])].slice(0, 5) }
|
|
342
|
+
: item)
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
return merged.size ? [...merged.values()] : undefined
|
|
346
|
+
}
|
|
347
|
+
|
|
313
348
|
function splitBlockingConflicts(plan, conflicts) {
|
|
314
349
|
const touched = new Set([
|
|
315
350
|
...(plan.update || []).map((item) => item.name),
|
|
@@ -741,6 +776,20 @@ export const dypaiPushTool = {
|
|
|
741
776
|
error: e.message,
|
|
742
777
|
}
|
|
743
778
|
}
|
|
779
|
+
const compilerValidation = partitionValidationErrors(local.compilerDiagnostics)
|
|
780
|
+
if (compilerValidation.projectLevel.length) {
|
|
781
|
+
return {
|
|
782
|
+
success: false,
|
|
783
|
+
applied: false,
|
|
784
|
+
reason: "compiler_validation_failed",
|
|
785
|
+
diagnostics: compilerValidation.projectLevel.slice(0, 20),
|
|
786
|
+
hint: "The compiler reported project-level errors that cannot be isolated to one endpoint.",
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
for (const endpoint of compilerValidation.erroringEndpoints) {
|
|
790
|
+
erroringEndpoints.add(endpoint)
|
|
791
|
+
}
|
|
792
|
+
skippedDiagnostics.push(...compilerValidation.errorDiags)
|
|
744
793
|
try {
|
|
745
794
|
remote = await fetchRemoteState(targetProjectId)
|
|
746
795
|
} catch (e) {
|
|
@@ -817,7 +866,10 @@ export const dypaiPushTool = {
|
|
|
817
866
|
// they aren't pushed (they keep their live version). Deletes stay — a broken
|
|
818
867
|
// local flow shouldn't block removing endpoints. skip_validation leaves
|
|
819
868
|
// erroringEndpoints empty, so nothing is dropped.
|
|
820
|
-
const skipped_endpoints =
|
|
869
|
+
const skipped_endpoints = mergeSkippedEndpointSummaries(
|
|
870
|
+
dropErroringFromPlan(plan, erroringEndpoints, skippedDiagnostics),
|
|
871
|
+
skippedEndpointsFromDiagnostics(compilerValidation.errorDiags),
|
|
872
|
+
)
|
|
821
873
|
|
|
822
874
|
const groupChanges = (plan.groups?.create?.length || 0) + (plan.groups?.delete?.length || 0)
|
|
823
875
|
const totalChanges = plan.create.length + plan.update.length + plan.delete.length + groupChanges
|
|
@@ -830,8 +882,13 @@ export const dypaiPushTool = {
|
|
|
830
882
|
success: false,
|
|
831
883
|
applied: false,
|
|
832
884
|
reason: "conflicts_detected",
|
|
885
|
+
summary: summaryFromPlan(plan),
|
|
833
886
|
conflicts: conflictSplit.blocking,
|
|
834
887
|
non_blocking_conflicts: conflictSplit.non_blocking.length ? conflictSplit.non_blocking : undefined,
|
|
888
|
+
skipped_endpoints,
|
|
889
|
+
compiler_diagnostics: local.compilerDiagnostics?.length
|
|
890
|
+
? local.compilerDiagnostics.slice(0, 50)
|
|
891
|
+
: undefined,
|
|
835
892
|
hint: "Remote changes overlap endpoints this push would update/delete. Run dypai_pull to refresh local state, resolve the overlap, then push again. To override, pass force=true.",
|
|
836
893
|
}
|
|
837
894
|
}
|
|
@@ -861,6 +918,9 @@ export const dypaiPushTool = {
|
|
|
861
918
|
: totalChanges === 0 ? "no_changes" : "dry_run",
|
|
862
919
|
summary: summaryFromPlan(plan),
|
|
863
920
|
skipped_endpoints,
|
|
921
|
+
compiler_diagnostics: local.compilerDiagnostics?.length
|
|
922
|
+
? local.compilerDiagnostics.slice(0, 50)
|
|
923
|
+
: undefined,
|
|
864
924
|
plan,
|
|
865
925
|
non_blocking_conflicts: conflictSplit.non_blocking.length ? conflictSplit.non_blocking : undefined,
|
|
866
926
|
types: typesGenerated,
|
|
@@ -1073,6 +1133,9 @@ export const dypaiPushTool = {
|
|
|
1073
1133
|
details: applied,
|
|
1074
1134
|
endpoint_results,
|
|
1075
1135
|
skipped_endpoints,
|
|
1136
|
+
compiler_diagnostics: local.compilerDiagnostics?.length
|
|
1137
|
+
? local.compilerDiagnostics.slice(0, 50)
|
|
1138
|
+
: undefined,
|
|
1076
1139
|
non_blocking_conflicts: conflictSplit.non_blocking.length ? conflictSplit.non_blocking : undefined,
|
|
1077
1140
|
errors: errors.length ? errors : undefined,
|
|
1078
1141
|
types: typesGenerated,
|
|
@@ -1131,6 +1194,8 @@ export const __testing = {
|
|
|
1131
1194
|
syncAutomationMetadata,
|
|
1132
1195
|
partitionValidationErrors,
|
|
1133
1196
|
dropErroringFromPlan,
|
|
1197
|
+
skippedEndpointsFromDiagnostics,
|
|
1198
|
+
mergeSkippedEndpointSummaries,
|
|
1134
1199
|
normalizeEndpointSelection,
|
|
1135
1200
|
scopePlanToEndpoints,
|
|
1136
1201
|
backendSourcePathsForEndpointSelection,
|