@wootsup/mcp 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -5
- package/dist/catalog/build-catalog.d.ts +31 -0
- package/dist/catalog/build-catalog.js +68 -0
- package/dist/catalog/build-catalog.js.map +1 -0
- package/dist/index.js +37 -5
- package/dist/index.js.map +1 -1
- package/dist/modules/apimapper/auto-layout.d.ts +21 -0
- package/dist/modules/apimapper/auto-layout.js +54 -0
- package/dist/modules/apimapper/auto-layout.js.map +1 -0
- package/dist/modules/apimapper/client.d.ts +54 -4
- package/dist/modules/apimapper/client.js +145 -14
- package/dist/modules/apimapper/client.js.map +1 -1
- package/dist/modules/apimapper/connections-format.d.ts +31 -1
- package/dist/modules/apimapper/connections-format.js +97 -5
- package/dist/modules/apimapper/connections-format.js.map +1 -1
- package/dist/modules/apimapper/connections.d.ts +9 -7
- package/dist/modules/apimapper/connections.js +225 -58
- package/dist/modules/apimapper/connections.js.map +1 -1
- package/dist/modules/apimapper/credentials.js +86 -14
- package/dist/modules/apimapper/credentials.js.map +1 -1
- package/dist/modules/apimapper/elicitation.d.ts +29 -0
- package/dist/modules/apimapper/elicitation.js +62 -0
- package/dist/modules/apimapper/elicitation.js.map +1 -1
- package/dist/modules/apimapper/example-extract.d.ts +13 -0
- package/dist/modules/apimapper/example-extract.js +111 -0
- package/dist/modules/apimapper/example-extract.js.map +1 -0
- package/dist/modules/apimapper/filter-operators.d.ts +24 -0
- package/dist/modules/apimapper/filter-operators.js +103 -0
- package/dist/modules/apimapper/filter-operators.js.map +1 -0
- package/dist/modules/apimapper/flows-format.js +92 -22
- package/dist/modules/apimapper/flows-format.js.map +1 -1
- package/dist/modules/apimapper/flows.d.ts +8 -7
- package/dist/modules/apimapper/flows.js +216 -44
- package/dist/modules/apimapper/flows.js.map +1 -1
- package/dist/modules/apimapper/gateway/advanced-read-tool.d.ts +9 -0
- package/dist/modules/apimapper/gateway/advanced-read-tool.js +172 -0
- package/dist/modules/apimapper/gateway/advanced-read-tool.js.map +1 -0
- package/dist/modules/apimapper/gateway/advanced-tool.js +39 -130
- package/dist/modules/apimapper/gateway/advanced-tool.js.map +1 -1
- package/dist/modules/apimapper/gateway/collect-module-tools.d.ts +17 -0
- package/dist/modules/apimapper/gateway/collect-module-tools.js +44 -0
- package/dist/modules/apimapper/gateway/collect-module-tools.js.map +1 -0
- package/dist/modules/apimapper/gateway/essentials.d.ts +1 -1
- package/dist/modules/apimapper/gateway/essentials.js +19 -7
- package/dist/modules/apimapper/gateway/essentials.js.map +1 -1
- package/dist/modules/apimapper/gateway/gateway-shared.d.ts +21 -0
- package/dist/modules/apimapper/gateway/gateway-shared.js +124 -0
- package/dist/modules/apimapper/gateway/gateway-shared.js.map +1 -0
- package/dist/modules/apimapper/gateway/test-support.d.ts +1 -17
- package/dist/modules/apimapper/gateway/test-support.js +4 -33
- package/dist/modules/apimapper/gateway/test-support.js.map +1 -1
- package/dist/modules/apimapper/get-skill-cores.d.ts +4 -0
- package/dist/modules/apimapper/get-skill-cores.js +220 -0
- package/dist/modules/apimapper/get-skill-cores.js.map +1 -0
- package/dist/modules/apimapper/get-skill.d.ts +1 -1
- package/dist/modules/apimapper/get-skill.js +30 -3
- package/dist/modules/apimapper/get-skill.js.map +1 -1
- package/dist/modules/apimapper/graph-builder.d.ts +85 -2
- package/dist/modules/apimapper/graph-builder.js +151 -15
- package/dist/modules/apimapper/graph-builder.js.map +1 -1
- package/dist/modules/apimapper/graph.js +115 -15
- package/dist/modules/apimapper/graph.js.map +1 -1
- package/dist/modules/apimapper/index.js +25 -13
- package/dist/modules/apimapper/index.js.map +1 -1
- package/dist/modules/apimapper/jmespath-test.d.ts +4 -0
- package/dist/modules/apimapper/jmespath-test.js +152 -0
- package/dist/modules/apimapper/jmespath-test.js.map +1 -0
- package/dist/modules/apimapper/library.js +131 -8
- package/dist/modules/apimapper/library.js.map +1 -1
- package/dist/modules/apimapper/list-footer.d.ts +27 -0
- package/dist/modules/apimapper/list-footer.js +57 -0
- package/dist/modules/apimapper/list-footer.js.map +1 -0
- package/dist/modules/apimapper/local-sources.js +88 -31
- package/dist/modules/apimapper/local-sources.js.map +1 -1
- package/dist/modules/apimapper/mcp-client-identity.d.ts +32 -0
- package/dist/modules/apimapper/mcp-client-identity.js +70 -0
- package/dist/modules/apimapper/mcp-client-identity.js.map +1 -0
- package/dist/modules/apimapper/merge-constants.d.ts +6 -0
- package/dist/modules/apimapper/merge-constants.js +26 -0
- package/dist/modules/apimapper/merge-constants.js.map +1 -0
- package/dist/modules/apimapper/node-schema.d.ts +52 -2
- package/dist/modules/apimapper/node-schema.js +95 -4
- package/dist/modules/apimapper/node-schema.js.map +1 -1
- package/dist/modules/apimapper/onboarding.d.ts +29 -0
- package/dist/modules/apimapper/onboarding.js +117 -9
- package/dist/modules/apimapper/onboarding.js.map +1 -1
- package/dist/modules/apimapper/read-cache.d.ts +16 -3
- package/dist/modules/apimapper/read-cache.js +59 -4
- package/dist/modules/apimapper/read-cache.js.map +1 -1
- package/dist/modules/apimapper/render/index.js +26 -5
- package/dist/modules/apimapper/render/index.js.map +1 -1
- package/dist/modules/apimapper/resource-id.d.ts +13 -0
- package/dist/modules/apimapper/resource-id.js +69 -0
- package/dist/modules/apimapper/resource-id.js.map +1 -0
- package/dist/modules/apimapper/tool-result.d.ts +20 -0
- package/dist/modules/apimapper/tool-result.js +67 -5
- package/dist/modules/apimapper/tool-result.js.map +1 -1
- package/dist/modules/apimapper/toolslist-size.d.ts +10 -10
- package/dist/modules/apimapper/toolslist-size.js +29 -18
- package/dist/modules/apimapper/toolslist-size.js.map +1 -1
- package/dist/modules/apimapper/types.d.ts +13 -0
- package/dist/modules/apimapper/types.js +1 -1
- package/dist/modules/apimapper/types.js.map +1 -1
- package/dist/modules/apimapper/whitelist-drift.js +16 -1
- package/dist/modules/apimapper/whitelist-drift.js.map +1 -1
- package/dist/modules/apimapper/workflows.js +221 -32
- package/dist/modules/apimapper/workflows.js.map +1 -1
- package/dist/modules/apimapper/yootheme-binding.js +103 -22
- package/dist/modules/apimapper/yootheme-binding.js.map +1 -1
- package/dist/platform/index.js +7 -0
- package/dist/platform/index.js.map +1 -1
- package/dist/proxy/bridge.d.ts +35 -0
- package/dist/proxy/bridge.js +129 -0
- package/dist/proxy/bridge.js.map +1 -0
- package/dist/proxy/mode.d.ts +9 -0
- package/dist/proxy/mode.js +20 -0
- package/dist/proxy/mode.js.map +1 -0
- package/dist/setup/probe-auth.d.ts +51 -0
- package/dist/setup/probe-auth.js +141 -0
- package/dist/setup/probe-auth.js.map +1 -0
- package/dist/setup-cli.d.ts +9 -0
- package/dist/setup-cli.js +34 -0
- package/dist/setup-cli.js.map +1 -1
- package/dist/sites/loader.d.ts +7 -0
- package/dist/sites/loader.js +16 -1
- package/dist/sites/loader.js.map +1 -1
- package/dist/skill-instructions.d.ts +14 -1
- package/dist/skill-instructions.js +30 -6
- package/dist/skill-instructions.js.map +1 -1
- package/manifest.json +2 -2
- package/package.json +3 -2
- package/skills/apimapper/SKILL.md +78 -3
- package/skills/apimapper/reference/dynamize-existing-layout.md +158 -0
- package/skills/apimapper/reference/jmespath-cookbook.md +241 -0
- package/skills/apimapper/reference/jmespath-pitfalls.md +81 -0
- package/skills/apimapper/reference/library-template-discovery.md +1 -1
- package/skills/apimapper/reference/merge-two-sources-on-key.md +117 -12
- package/skills/apimapper/reference/oauth.md +143 -52
- package/skills/apimapper/reference/troubleshooting.md +2 -2
- package/skills/apimapper/reference/yootheme-source-to-builder-handoff.md +348 -0
- package/skills/apimapper/reference/yootheme.md +75 -44
|
@@ -1,6 +1,33 @@
|
|
|
1
1
|
import type { FlowNode, FlowEdge } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Local-source descriptor (F25, 2026-06-10): a CMS-native content source
|
|
4
|
+
* (WordPress posts / Joomla articles) queried straight from the platform DB —
|
|
5
|
+
* no Connection. Mirrors the `local-source` node-schema (`data.contentType`,
|
|
6
|
+
* `data.limit`, `data.filters`).
|
|
7
|
+
*/
|
|
8
|
+
export interface LocalSourceDescriptor {
|
|
9
|
+
/**
|
|
10
|
+
* Fully-qualified content type, e.g. `wordpress/post`, `wordpress/page`,
|
|
11
|
+
* `joomla/article`. The bare `post` is NOT accepted — the PHP save-time guard
|
|
12
|
+
* (F26) and the executor (C5) reject under-qualified types.
|
|
13
|
+
*/
|
|
14
|
+
content_type: string;
|
|
15
|
+
/** Max items to fetch (clamped to the tier maximum server-side). */
|
|
16
|
+
limit?: number;
|
|
17
|
+
/** Server-side filters (e.g. `{ category: "news" }`). */
|
|
18
|
+
filters?: Record<string, unknown>;
|
|
19
|
+
}
|
|
2
20
|
export interface SourceSpec {
|
|
3
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Connection ID for an API source. Mutually exclusive with `local_source`:
|
|
23
|
+
* exactly ONE of `connection` / `local_source` must be set per source.
|
|
24
|
+
*/
|
|
25
|
+
connection?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Local-source descriptor for a CMS-native source. Mutually exclusive with
|
|
28
|
+
* `connection`. F25 (2026-06-10).
|
|
29
|
+
*/
|
|
30
|
+
local_source?: LocalSourceDescriptor;
|
|
4
31
|
endpoint?: string;
|
|
5
32
|
template_fields?: Record<string, string>;
|
|
6
33
|
items_path?: string;
|
|
@@ -15,6 +42,28 @@ export interface MergeSpec {
|
|
|
15
42
|
export interface TransformSpec {
|
|
16
43
|
expression?: string;
|
|
17
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* A single filter condition. `value` is omitted for value-less operators
|
|
47
|
+
* (`exists`/`not_exists`/`empty`/`not_empty`). F54 (2026-06-10).
|
|
48
|
+
*/
|
|
49
|
+
export interface FilterCondition {
|
|
50
|
+
field: string;
|
|
51
|
+
operator: string;
|
|
52
|
+
value?: unknown;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* One-shot filter descriptor (F54). Two shapes are accepted:
|
|
56
|
+
* - inline single condition: `{ field, operator, value }`
|
|
57
|
+
* - explicit list: `{ conditions: [...], logic? }`
|
|
58
|
+
* The inline form is normalised into a one-element `conditions` array.
|
|
59
|
+
*/
|
|
60
|
+
export interface FilterSpec {
|
|
61
|
+
field?: string;
|
|
62
|
+
operator?: string;
|
|
63
|
+
value?: unknown;
|
|
64
|
+
conditions?: FilterCondition[];
|
|
65
|
+
logic?: "and" | "or";
|
|
66
|
+
}
|
|
18
67
|
export interface OutputSpec {
|
|
19
68
|
type?: "yootheme" | "shortcode";
|
|
20
69
|
name: string;
|
|
@@ -23,9 +72,33 @@ export interface OutputSpec {
|
|
|
23
72
|
export interface BuildFlowGraphInput {
|
|
24
73
|
sources: SourceSpec[];
|
|
25
74
|
merge?: MergeSpec;
|
|
26
|
-
|
|
75
|
+
filter?: FilterSpec;
|
|
76
|
+
/**
|
|
77
|
+
* F181 (2026-06-12): a single `TransformSpec` OR an array of them. An array
|
|
78
|
+
* is chained source(s) → [merge →] [filter →] t1 → t2 → … → output, each
|
|
79
|
+
* transform's output feeding the next. This is the canonical remedy for the
|
|
80
|
+
* JMESPath depth cap (10): a too-deeply-nested reshape is split into two (or
|
|
81
|
+
* more) chained transforms — the pipe between nodes resets the depth counter.
|
|
82
|
+
* A bare object and a one-element array produce an identical graph; an empty
|
|
83
|
+
* array is treated as no transform at all (back-compat with `undefined`).
|
|
84
|
+
*/
|
|
85
|
+
transform?: TransformSpec | TransformSpec[];
|
|
27
86
|
output: OutputSpec;
|
|
28
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* Normalise a {@link FilterSpec} into a validated `{ conditions, logic }`
|
|
90
|
+
* payload for the filter node, throwing a HARD error on any invalid condition
|
|
91
|
+
* (F53). This is the build chokepoint: rejecting here means the agent learns
|
|
92
|
+
* immediately, instead of shipping a flow that silently yields 0 rows at
|
|
93
|
+
* render time.
|
|
94
|
+
*
|
|
95
|
+
* @throws Error when a condition is missing `field`, uses an unknown operator,
|
|
96
|
+
* or omits a required `value`.
|
|
97
|
+
*/
|
|
98
|
+
export declare function normalizeFilterSpec(filter: FilterSpec): {
|
|
99
|
+
conditions: FilterCondition[];
|
|
100
|
+
logic: "and" | "or";
|
|
101
|
+
};
|
|
29
102
|
export interface BuildFlowGraphResult {
|
|
30
103
|
nodes: FlowNode[];
|
|
31
104
|
edges: FlowEdge[];
|
|
@@ -43,5 +116,15 @@ export interface BuildFlowGraphResult {
|
|
|
43
116
|
* - sources.length === 0
|
|
44
117
|
* - sources.length >= 2 without `merge`
|
|
45
118
|
* - merge.strategy === "join" without `joinKey`
|
|
119
|
+
* - a source with NEITHER `connection` nor `local_source` (F25)
|
|
120
|
+
* - a source with BOTH `connection` and `local_source` (F25)
|
|
121
|
+
* - a `local_source` with an empty `content_type` (F25)
|
|
122
|
+
* - a `filter` condition with an unknown operator / missing field / missing
|
|
123
|
+
* required value (F53/F54)
|
|
124
|
+
*
|
|
125
|
+
* Node order is deterministic left-to-right: sources → merge? → filter? →
|
|
126
|
+
* transform? → output. The filter sits AFTER merge (so it filters the joined
|
|
127
|
+
* rows) and BEFORE transform (so a derived/coerced field a Transform produces
|
|
128
|
+
* is NOT yet visible — filter on raw fields, then reshape).
|
|
46
129
|
*/
|
|
47
130
|
export declare function buildFlowGraph(input: BuildFlowGraphInput): BuildFlowGraphResult;
|
|
@@ -5,6 +5,50 @@
|
|
|
5
5
|
// isolation and reusable from future tooling (Joomla parity, MCP composite
|
|
6
6
|
// tools beyond setup_with_sources, etc.).
|
|
7
7
|
import { normalizeMergeStrategy } from "./normalizers.js";
|
|
8
|
+
import { isValidFilterOperator, operatorNeedsValue, unknownOperatorMessage, } from "./filter-operators.js";
|
|
9
|
+
/**
|
|
10
|
+
* Normalise a {@link FilterSpec} into a validated `{ conditions, logic }`
|
|
11
|
+
* payload for the filter node, throwing a HARD error on any invalid condition
|
|
12
|
+
* (F53). This is the build chokepoint: rejecting here means the agent learns
|
|
13
|
+
* immediately, instead of shipping a flow that silently yields 0 rows at
|
|
14
|
+
* render time.
|
|
15
|
+
*
|
|
16
|
+
* @throws Error when a condition is missing `field`, uses an unknown operator,
|
|
17
|
+
* or omits a required `value`.
|
|
18
|
+
*/
|
|
19
|
+
export function normalizeFilterSpec(filter) {
|
|
20
|
+
// Accept either the inline single-condition form or an explicit list.
|
|
21
|
+
let conditions;
|
|
22
|
+
if (Array.isArray(filter.conditions) && filter.conditions.length > 0) {
|
|
23
|
+
conditions = filter.conditions;
|
|
24
|
+
}
|
|
25
|
+
else if (typeof filter.field === "string") {
|
|
26
|
+
conditions = [{ field: filter.field, operator: filter.operator ?? "equals", value: filter.value }];
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
throw new Error("filter requires either an inline `{ field, operator, value }` or a non-empty `conditions` array");
|
|
30
|
+
}
|
|
31
|
+
const validated = conditions.map((c, i) => {
|
|
32
|
+
if (typeof c.field !== "string" || c.field === "") {
|
|
33
|
+
throw new Error(`filter.conditions[${i}]: \`field\` is required (non-empty string)`);
|
|
34
|
+
}
|
|
35
|
+
const operator = c.operator;
|
|
36
|
+
if (typeof operator !== "string" || !isValidFilterOperator(operator)) {
|
|
37
|
+
throw new Error(`filter.conditions[${i}]: ${unknownOperatorMessage(String(operator))}`);
|
|
38
|
+
}
|
|
39
|
+
if (operatorNeedsValue(operator) && (c.value === undefined || c.value === null)) {
|
|
40
|
+
throw new Error(`filter.conditions[${i}]: operator "${operator}" requires a \`value\` (only ` +
|
|
41
|
+
`exists/not_exists/empty/not_empty are value-less).`);
|
|
42
|
+
}
|
|
43
|
+
// Re-emit a clean condition (drop stray keys, keep value only when present
|
|
44
|
+
// so value-less operators serialise minimally — matches FilterStep.php).
|
|
45
|
+
const out = { field: c.field, operator };
|
|
46
|
+
if (c.value !== undefined)
|
|
47
|
+
out.value = c.value;
|
|
48
|
+
return out;
|
|
49
|
+
});
|
|
50
|
+
return { conditions: validated, logic: filter.logic === "or" ? "or" : "and" };
|
|
51
|
+
}
|
|
8
52
|
/**
|
|
9
53
|
* Build a complete React-Flow graph from declarative source/merge/transform
|
|
10
54
|
* /output specs. Layout is deterministic (left-to-right columns).
|
|
@@ -13,9 +57,19 @@ import { normalizeMergeStrategy } from "./normalizers.js";
|
|
|
13
57
|
* - sources.length === 0
|
|
14
58
|
* - sources.length >= 2 without `merge`
|
|
15
59
|
* - merge.strategy === "join" without `joinKey`
|
|
60
|
+
* - a source with NEITHER `connection` nor `local_source` (F25)
|
|
61
|
+
* - a source with BOTH `connection` and `local_source` (F25)
|
|
62
|
+
* - a `local_source` with an empty `content_type` (F25)
|
|
63
|
+
* - a `filter` condition with an unknown operator / missing field / missing
|
|
64
|
+
* required value (F53/F54)
|
|
65
|
+
*
|
|
66
|
+
* Node order is deterministic left-to-right: sources → merge? → filter? →
|
|
67
|
+
* transform? → output. The filter sits AFTER merge (so it filters the joined
|
|
68
|
+
* rows) and BEFORE transform (so a derived/coerced field a Transform produces
|
|
69
|
+
* is NOT yet visible — filter on raw fields, then reshape).
|
|
16
70
|
*/
|
|
17
71
|
export function buildFlowGraph(input) {
|
|
18
|
-
const { sources, merge, transform, output } = input;
|
|
72
|
+
const { sources, merge, filter, transform, output } = input;
|
|
19
73
|
if (sources.length === 0) {
|
|
20
74
|
throw new Error("buildFlowGraph: at least one source is required");
|
|
21
75
|
}
|
|
@@ -25,17 +79,63 @@ export function buildFlowGraph(input) {
|
|
|
25
79
|
if (merge && (merge.strategy === "join") && !merge.joinKey) {
|
|
26
80
|
throw new Error("buildFlowGraph: merge.joinKey is required for strategy=join");
|
|
27
81
|
}
|
|
82
|
+
// F25 (2026-06-10): validate the connection-vs-local discriminator on every
|
|
83
|
+
// source up-front so the error names the offending index, instead of a
|
|
84
|
+
// confusing downstream compile failure on a half-built node.
|
|
85
|
+
sources.forEach((s, i) => {
|
|
86
|
+
const hasConnection = typeof s.connection === "string" && s.connection !== "";
|
|
87
|
+
const hasLocal = !!s.local_source;
|
|
88
|
+
if (!hasConnection && !hasLocal) {
|
|
89
|
+
throw new Error(`buildFlowGraph: source[${i}] must set either \`connection\` or \`local_source\``);
|
|
90
|
+
}
|
|
91
|
+
if (hasConnection && hasLocal) {
|
|
92
|
+
throw new Error(`buildFlowGraph: source[${i}] must set \`connection\` or \`local_source\`, not both`);
|
|
93
|
+
}
|
|
94
|
+
if (hasLocal && (typeof s.local_source.content_type !== "string" || s.local_source.content_type === "")) {
|
|
95
|
+
throw new Error(`buildFlowGraph: source[${i}].local_source.content_type is required (non-empty)`);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
// F53/F54: validate + normalise the filter spec up-front so an unknown
|
|
99
|
+
// operator / missing field / missing value throws BEFORE we build any node
|
|
100
|
+
// (mirrors the source-validation pattern above — fail fast, name the issue).
|
|
101
|
+
const filterPayload = filter ? normalizeFilterSpec(filter) : null;
|
|
28
102
|
const nodes = [];
|
|
29
103
|
const edges = [];
|
|
30
104
|
const baseX = 100;
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
//
|
|
105
|
+
// Column / row pitch for the auto-laid-out graph. Canvas node cards are
|
|
106
|
+
// `min-w-[220px] max-w-[300px]` (admin-ui BaseNode), so the pitch MUST exceed
|
|
107
|
+
// the max card width or programmatically-created nodes overlap / touch with no
|
|
108
|
+
// breathing room (reported 2026-06-14). Pitch = max card width (300) + a
|
|
109
|
+
// comfortable gutter so adjacent nodes never crowd, regardless of card width.
|
|
110
|
+
const colWidth = 400; // 300 max card + 100 horizontal gutter
|
|
111
|
+
const rowHeight = 240; // stacked merge sources: card height + vertical gutter
|
|
112
|
+
// Sources column. Each descriptor emits EITHER a connection `source` node OR
|
|
113
|
+
// a CMS-native `local-source` node (F25). Both share the `source-{n}` id
|
|
114
|
+
// convention so the merge/transform/output wiring below is source-kind-blind.
|
|
34
115
|
sources.forEach((s, i) => {
|
|
116
|
+
const id = `source-${i + 1}`;
|
|
117
|
+
const position = { x: baseX, y: 100 + i * rowHeight };
|
|
118
|
+
if (s.local_source) {
|
|
119
|
+
const ls = s.local_source;
|
|
120
|
+
nodes.push({
|
|
121
|
+
id,
|
|
122
|
+
type: "local-source",
|
|
123
|
+
position,
|
|
124
|
+
data: {
|
|
125
|
+
label: s.label || `Source ${i + 1}`,
|
|
126
|
+
contentType: ls.content_type,
|
|
127
|
+
// Only forward limit/filters when provided so the node data stays
|
|
128
|
+
// minimal (executor defaults limit; filters default to []).
|
|
129
|
+
...(ls.limit !== undefined ? { limit: ls.limit } : {}),
|
|
130
|
+
...(ls.filters !== undefined ? { filters: ls.filters } : {}),
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
35
135
|
nodes.push({
|
|
36
|
-
id
|
|
136
|
+
id,
|
|
37
137
|
type: "source",
|
|
38
|
-
position
|
|
138
|
+
position,
|
|
39
139
|
data: {
|
|
40
140
|
label: s.label || `Source ${i + 1}`,
|
|
41
141
|
connectionId: s.connection,
|
|
@@ -75,32 +175,68 @@ export function buildFlowGraph(input) {
|
|
|
75
175
|
});
|
|
76
176
|
lastNodeId = mergeId;
|
|
77
177
|
}
|
|
78
|
-
//
|
|
79
|
-
|
|
80
|
-
|
|
178
|
+
// F54: Filter column — sits AFTER merge, BEFORE transform. `col` tracks the
|
|
179
|
+
// next free left-to-right column so positions stay non-overlapping whether
|
|
180
|
+
// or not a filter/transform is present.
|
|
181
|
+
let col = 2;
|
|
182
|
+
if (filterPayload) {
|
|
183
|
+
const filterId = "filter-1";
|
|
184
|
+
nodes.push({
|
|
185
|
+
id: filterId,
|
|
186
|
+
type: "filter",
|
|
187
|
+
position: { x: baseX + col * colWidth, y: 200 },
|
|
188
|
+
data: {
|
|
189
|
+
label: "Filter",
|
|
190
|
+
conditions: filterPayload.conditions,
|
|
191
|
+
logic: filterPayload.logic,
|
|
192
|
+
},
|
|
193
|
+
});
|
|
194
|
+
edges.push({
|
|
195
|
+
id: `e-${lastNodeId}-filter`,
|
|
196
|
+
source: lastNodeId,
|
|
197
|
+
target: filterId,
|
|
198
|
+
});
|
|
199
|
+
lastNodeId = filterId;
|
|
200
|
+
col += 1;
|
|
201
|
+
}
|
|
202
|
+
// Transform column(s). F181: a bare TransformSpec is treated as a
|
|
203
|
+
// one-element chain; an array chains each transform's output into the next
|
|
204
|
+
// (source(s) → [merge →] [filter →] t1 → t2 → … → output). An empty array
|
|
205
|
+
// (or omitted transform) emits no transform node — identical to the legacy
|
|
206
|
+
// no-transform graph. The pipe between two chained transform nodes resets the
|
|
207
|
+
// JMESPath depth counter, so splitting a depth-cap-overflowing expression
|
|
208
|
+
// into N shallow transforms is now expressible in one composite call.
|
|
209
|
+
const transformChain = transform === undefined
|
|
210
|
+
? []
|
|
211
|
+
: Array.isArray(transform)
|
|
212
|
+
? transform
|
|
213
|
+
: [transform];
|
|
214
|
+
transformChain.forEach((t, i) => {
|
|
215
|
+
const transformId = `transform-${i + 1}`;
|
|
81
216
|
nodes.push({
|
|
82
217
|
id: transformId,
|
|
83
218
|
type: "transform",
|
|
84
|
-
position: { x: baseX +
|
|
219
|
+
position: { x: baseX + (col + i) * colWidth, y: 200 },
|
|
85
220
|
data: {
|
|
86
|
-
label: "Transform",
|
|
87
|
-
expression:
|
|
221
|
+
label: transformChain.length > 1 ? `Transform ${i + 1}` : "Transform",
|
|
222
|
+
expression: t.expression ?? "[*]",
|
|
88
223
|
},
|
|
89
224
|
});
|
|
90
225
|
edges.push({
|
|
91
|
-
id: `e-${lastNodeId}
|
|
226
|
+
id: `e-${lastNodeId}-${transformId}`,
|
|
92
227
|
source: lastNodeId,
|
|
93
228
|
target: transformId,
|
|
94
229
|
});
|
|
95
230
|
lastNodeId = transformId;
|
|
96
|
-
}
|
|
231
|
+
});
|
|
232
|
+
col += transformChain.length;
|
|
97
233
|
// Output column
|
|
98
234
|
const outputId = "output-1";
|
|
99
235
|
const outputType = output.type === "shortcode" ? "output-shortcode" : "output-yootheme";
|
|
100
236
|
nodes.push({
|
|
101
237
|
id: outputId,
|
|
102
238
|
type: outputType,
|
|
103
|
-
position: { x: baseX +
|
|
239
|
+
position: { x: baseX + col * colWidth, y: 200 },
|
|
104
240
|
data: {
|
|
105
241
|
label: output.name,
|
|
106
242
|
name: output.name,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-builder.js","sourceRoot":"","sources":["../../../src/modules/apimapper/graph-builder.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,8EAA8E;AAC9E,EAAE;AACF,2EAA2E;AAC3E,2EAA2E;AAC3E,0CAA0C;AAG1C,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"graph-builder.js","sourceRoot":"","sources":["../../../src/modules/apimapper/graph-builder.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,8EAA8E;AAC9E,EAAE;AACF,2EAA2E;AAC3E,2EAA2E;AAC3E,0CAA0C;AAG1C,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAgG/B;;;;;;;;;GASG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAkB;IAIpD,sEAAsE;IACtE,IAAI,UAA6B,CAAC;IAClC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrE,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;IACjC,CAAC;SAAM,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC5C,UAAU,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;IACrG,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,KAAK,CACb,iGAAiG,CAClG,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAsB,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAC3D,IAAI,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,CAAC,KAAK,KAAK,EAAE,EAAE,CAAC;YAClD,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,6CAA6C,CAAC,CAAC;QACvF,CAAC;QACD,MAAM,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC;QAC5B,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,EAAE,CAAC;YACrE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,MAAM,sBAAsB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC;QAC1F,CAAC;QACD,IAAI,kBAAkB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,EAAE,CAAC;YAChF,MAAM,IAAI,KAAK,CACb,qBAAqB,CAAC,gBAAgB,QAAQ,+BAA+B;gBAC3E,oDAAoD,CACvD,CAAC;QACJ,CAAC;QACD,2EAA2E;QAC3E,yEAAyE;QACzE,MAAM,GAAG,GAAoB,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC;QAC1D,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS;YAAE,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;QAC/C,OAAO,GAAG,CAAC;IACb,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;AAChF,CAAC;AAQD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,cAAc,CAAC,KAA0B;IACvD,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IAE5D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;IACrF,CAAC;IACD,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,QAAQ,KAAK,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;IACjF,CAAC;IAED,4EAA4E;IAC5E,uEAAuE;IACvE,6DAA6D;IAC7D,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACvB,MAAM,aAAa,GAAG,OAAO,CAAC,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,CAAC,UAAU,KAAK,EAAE,CAAC;QAC9E,MAAM,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC;QAClC,IAAI,CAAC,aAAa,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CACb,0BAA0B,CAAC,sDAAsD,CAClF,CAAC;QACJ,CAAC;QACD,IAAI,aAAa,IAAI,QAAQ,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CACb,0BAA0B,CAAC,yDAAyD,CACrF,CAAC;QACJ,CAAC;QACD,IAAI,QAAQ,IAAI,CAAC,OAAO,CAAC,CAAC,YAAa,CAAC,YAAY,KAAK,QAAQ,IAAI,CAAC,CAAC,YAAa,CAAC,YAAY,KAAK,EAAE,CAAC,EAAE,CAAC;YAC1G,MAAM,IAAI,KAAK,CACb,0BAA0B,CAAC,qDAAqD,CACjF,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,uEAAuE;IACvE,2EAA2E;IAC3E,6EAA6E;IAC7E,MAAM,aAAa,GAAG,MAAM,CAAC,CAAC,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAElE,MAAM,KAAK,GAAe,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAe,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAG,GAAG,CAAC;IAClB,wEAAwE;IACxE,8EAA8E;IAC9E,+EAA+E;IAC/E,yEAAyE;IACzE,8EAA8E;IAC9E,MAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,uCAAuC;IAC7D,MAAM,SAAS,GAAG,GAAG,CAAC,CAAC,uDAAuD;IAE9E,6EAA6E;IAC7E,yEAAyE;IACzE,8EAA8E;IAC9E,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACvB,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,GAAG,CAAC,GAAG,SAAS,EAAE,CAAC;QACtD,IAAI,CAAC,CAAC,YAAY,EAAE,CAAC;YACnB,MAAM,EAAE,GAAG,CAAC,CAAC,YAAY,CAAC;YAC1B,KAAK,CAAC,IAAI,CAAC;gBACT,EAAE;gBACF,IAAI,EAAE,cAAc;gBACpB,QAAQ;gBACR,IAAI,EAAE;oBACJ,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE;oBACnC,WAAW,EAAE,EAAE,CAAC,YAAY;oBAC5B,kEAAkE;oBAClE,4DAA4D;oBAC5D,GAAG,CAAC,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACtD,GAAG,CAAC,EAAE,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAC7D;aACF,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,KAAK,CAAC,IAAI,CAAC;YACT,EAAE;YACF,IAAI,EAAE,QAAQ;YACd,QAAQ;YACR,IAAI,EAAE;gBACJ,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE;gBACnC,YAAY,EAAE,CAAC,CAAC,UAAU;gBAC1B,UAAU,EAAE,CAAC,CAAC,QAAQ;gBACtB,cAAc,EAAE,CAAC,CAAC,eAAe,IAAI,EAAE;gBACvC,SAAS,EAAE,CAAC,CAAC,UAAU;aACxB;SACF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAI,UAAU,GAAG,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IAExD,+BAA+B;IAC/B,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,QAAQ,GAAG,sBAAsB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACxD,MAAM,OAAO,GAAG,SAAS,CAAC;QAC1B,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,OAAO;YACX,IAAI,EAAE,OAAO;YACb,QAAQ,EAAE;gBACR,CAAC,EAAE,KAAK,GAAG,QAAQ;gBACnB,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,SAAS,GAAG,EAAE;aAC1D;YACD,IAAI,EAAE;gBACJ,KAAK,EAAE,UAAU,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE;gBAC5D,QAAQ;gBACR,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,EAAE;gBAC5B,YAAY,EAAE,KAAK,CAAC,YAAY;gBAChC,QAAQ,EAAE,KAAK,CAAC,QAAQ;aACzB;SACF,CAAC,CAAC;QACH,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE;YACxB,KAAK,CAAC,IAAI,CAAC;gBACT,EAAE,EAAE,WAAW,CAAC,GAAG,CAAC,QAAQ;gBAC5B,MAAM,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE;gBACzB,MAAM,EAAE,OAAO;gBACf,YAAY,EAAE,SAAS,CAAC,EAAE;aAC3B,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,UAAU,GAAG,OAAO,CAAC;IACvB,CAAC;IAED,4EAA4E;IAC5E,2EAA2E;IAC3E,wCAAwC;IACxC,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,QAAQ,GAAG,UAAU,CAAC;QAC5B,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,QAAQ;YACZ,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,EAAE,CAAC,EAAE,KAAK,GAAG,GAAG,GAAG,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE;YAC/C,IAAI,EAAE;gBACJ,KAAK,EAAE,QAAQ;gBACf,UAAU,EAAE,aAAa,CAAC,UAAU;gBACpC,KAAK,EAAE,aAAa,CAAC,KAAK;aAC3B;SACF,CAAC,CAAC;QACH,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,KAAK,UAAU,SAAS;YAC5B,MAAM,EAAE,UAAU;YAClB,MAAM,EAAE,QAAQ;SACjB,CAAC,CAAC;QACH,UAAU,GAAG,QAAQ,CAAC;QACtB,GAAG,IAAI,CAAC,CAAC;IACX,CAAC;IAED,kEAAkE;IAClE,2EAA2E;IAC3E,0EAA0E;IAC1E,2EAA2E;IAC3E,8EAA8E;IAC9E,0EAA0E;IAC1E,sEAAsE;IACtE,MAAM,cAAc,GAAoB,SAAS,KAAK,SAAS;QAC7D,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC;YACxB,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAClB,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QAC9B,MAAM,WAAW,GAAG,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;QACzC,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,WAAW;YACf,IAAI,EAAE,WAAW;YACjB,QAAQ,EAAE,EAAE,CAAC,EAAE,KAAK,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE;YACrD,IAAI,EAAE;gBACJ,KAAK,EAAE,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW;gBACrE,UAAU,EAAE,CAAC,CAAC,UAAU,IAAI,KAAK;aAClC;SACF,CAAC,CAAC;QACH,KAAK,CAAC,IAAI,CAAC;YACT,EAAE,EAAE,KAAK,UAAU,IAAI,WAAW,EAAE;YACpC,MAAM,EAAE,UAAU;YAClB,MAAM,EAAE,WAAW;SACpB,CAAC,CAAC;QACH,UAAU,GAAG,WAAW,CAAC;IAC3B,CAAC,CAAC,CAAC;IACH,GAAG,IAAI,cAAc,CAAC,MAAM,CAAC;IAE7B,gBAAgB;IAChB,MAAM,QAAQ,GAAG,UAAU,CAAC;IAC5B,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,iBAAiB,CAAC;IACxF,KAAK,CAAC,IAAI,CAAC;QACT,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,EAAE,CAAC,EAAE,KAAK,GAAG,GAAG,GAAG,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE;QAC/C,IAAI,EAAE;YACJ,KAAK,EAAE,MAAM,CAAC,IAAI;YAClB,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,IAAI,EAAE,MAAM,CAAC,IAAI;SAClB;KACF,CAAC,CAAC;IACH,KAAK,CAAC,IAAI,CAAC;QACT,EAAE,EAAE,KAAK,UAAU,SAAS;QAC5B,MAAM,EAAE,UAAU;QAClB,MAAM,EAAE,QAAQ;KACjB,CAAC,CAAC;IAEH,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;AAC7D,CAAC"}
|
|
@@ -2,7 +2,27 @@ import { z } from "zod";
|
|
|
2
2
|
import { formatResult, errorResult, readOnly } from "@getimo/mcp-toolkit";
|
|
3
3
|
import { request, hintFor } from "./client.js";
|
|
4
4
|
import { restErrorResult } from "./tool-result.js";
|
|
5
|
-
import { nodeSchema, edgeSchema } from "./node-schema.js";
|
|
5
|
+
import { nodeSchema, edgeSchema, ensureEdgeIds, isOutputNode } from "./node-schema.js";
|
|
6
|
+
/**
|
|
7
|
+
* F10 (2026-06-09): pick the flow's TERMINAL node id — the output-* node that
|
|
8
|
+
* the graph computes up to by default. Returns the id of the LAST output node
|
|
9
|
+
* in document order (a flow has exactly one terminal output; on the rare
|
|
10
|
+
* multi-output graph the last one authored wins, matching the FlowCompiler's
|
|
11
|
+
* findOutputNode tail-bias) or `undefined` when no output node exists. A loose
|
|
12
|
+
* `{ id?, type? }` shape is accepted so it works on both validated FlowNodes
|
|
13
|
+
* and raw hydrated wire objects.
|
|
14
|
+
*/
|
|
15
|
+
function terminalOutputNodeId(nodes) {
|
|
16
|
+
let found;
|
|
17
|
+
for (const n of nodes) {
|
|
18
|
+
if (isOutputNode(n)) {
|
|
19
|
+
const id = n.id;
|
|
20
|
+
if (typeof id === "string" && id !== "")
|
|
21
|
+
found = id;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return found;
|
|
25
|
+
}
|
|
6
26
|
import { buildFlowVisualization, SIDECAR_RESPONSE_MAX_CHARS, } from "./render/sidecar.js";
|
|
7
27
|
/**
|
|
8
28
|
* L-7 (W3F-5): hydrate `{nodes, edges}` from a saved flow when the
|
|
@@ -42,8 +62,14 @@ export function registerGraphTools(server) {
|
|
|
42
62
|
"result without re-executing the pipeline. Use `forceRefresh: true` only after a " +
|
|
43
63
|
"Connection/Credential mutation or when upstream API data is known to have changed. " +
|
|
44
64
|
"Do NOT call repeatedly to 're-render' or 'double-check' the same graph — the second " +
|
|
45
|
-
"call returns the same payload as the first
|
|
46
|
-
"
|
|
65
|
+
"call returns the same payload as the first.\n\n" +
|
|
66
|
+
"**Merge join with 0 rows:** when a `merge` node (strategy `join`) yields 0 items while both " +
|
|
67
|
+
"its inputs had data, the response carries a `merge_diagnostics[<mergeNodeId>]` object " +
|
|
68
|
+
"(`reason: merge_no_match`) with the join keys and a sample of the non-matching key values " +
|
|
69
|
+
"from each side. Read it instead of guessing — the usual cause is a wrong/incomparable join " +
|
|
70
|
+
"key (e.g. string \"P-100\" vs number 42). Sample both sides with apimapper_connection_data, " +
|
|
71
|
+
"then fix the merge joinKey/joinKeyRight." +
|
|
72
|
+
"\n\nExample:\n apimapper_graph_preview({ nodes: [{ id: 'src1', type: 'source', position: { x: 0, y: 0 }, data: { connectionId: 'con_abc123' } }], edges: [], target_node_id: 'src1' })" +
|
|
47
73
|
"\n apimapper_graph_preview({ id: 'flow_Z2fLg70M84' }) // `id` is an alias for `flow_id`",
|
|
48
74
|
inputSchema: {
|
|
49
75
|
// L-7 (W3F-5): `flow_id` shortcut hydrates {nodes, edges} from
|
|
@@ -79,14 +105,54 @@ export function registerGraphTools(server) {
|
|
|
79
105
|
targetNodeId: z
|
|
80
106
|
.string()
|
|
81
107
|
.optional()
|
|
82
|
-
.describe("Compute preview up to this node and return its output
|
|
108
|
+
.describe("Compute preview up to this node and return its output. When omitted, defaults " +
|
|
109
|
+
"to the flow's terminal output node (the output-* node) so passing just a flow id " +
|
|
110
|
+
"previews the finished source. Snake_case alias: `target_node_id`."),
|
|
111
|
+
// F60 + F152: snake_case alias. graph_preview is one of the
|
|
112
|
+
// few tools with a camelCase wire contract; cold agents reflexively
|
|
113
|
+
// pass the snake_case form (every other tool uses it, and this tool's
|
|
114
|
+
// OWN example shows `target_node_id`). Accept both — `targetNodeId`
|
|
115
|
+
// (canonical) wins on conflict. The wire body keeps camelCase
|
|
116
|
+
// (whitelist-drift pins {nodes,edges,targetNodeId,forceRefresh}).
|
|
117
|
+
target_node_id: z
|
|
118
|
+
.string()
|
|
119
|
+
.optional()
|
|
120
|
+
.describe("Snake_case alias of `targetNodeId`. `targetNodeId` wins when both are set."),
|
|
121
|
+
// F10 (2026-06-09): accept a `limit` arg gracefully. The AI passes it
|
|
122
|
+
// reflexively (mirroring the *_list / *_query tools); rejecting it as an
|
|
123
|
+
// unknown key forced a confusing retry. The preview already caps the
|
|
124
|
+
// returned items at 50 server-side-of-the-tool; `limit` lets the caller
|
|
125
|
+
// ask for fewer. Clamped to [1, 50] — the upstream pipeline still
|
|
126
|
+
// executes fully; this only trims the items echoed back.
|
|
127
|
+
limit: z
|
|
128
|
+
.number()
|
|
129
|
+
.int()
|
|
130
|
+
.min(1)
|
|
131
|
+
.max(50)
|
|
132
|
+
.optional()
|
|
133
|
+
.describe("Max preview items to return (1-50, default 50). Caps only the echoed items list — " +
|
|
134
|
+
"the pipeline still executes in full. Accepted for ergonomic parity with the list/query tools."),
|
|
83
135
|
forceRefresh: z
|
|
84
136
|
.boolean()
|
|
85
137
|
.default(false)
|
|
86
|
-
.describe("Skip snapshot/cache; always live-fetch from upstream"
|
|
138
|
+
.describe("Skip snapshot/cache; always live-fetch from upstream. " +
|
|
139
|
+
"Snake_case alias: `force_refresh`."),
|
|
140
|
+
// F60 + F152: snake_case alias for `forceRefresh` — same
|
|
141
|
+
// ergonomics rationale as `target_node_id`. No default here so an
|
|
142
|
+
// absent value does not shadow the canonical `forceRefresh: false`
|
|
143
|
+
// default; the handler ORs the two (either truthy → refresh).
|
|
144
|
+
force_refresh: z
|
|
145
|
+
.boolean()
|
|
146
|
+
.optional()
|
|
147
|
+
.describe("Snake_case alias of `forceRefresh`. Either spelling being true forces a refresh."),
|
|
87
148
|
},
|
|
88
149
|
annotations: readOnly({ title: "Preview Graph", openWorld: true }),
|
|
89
|
-
}, async ({ flow_id, id, nodes, edges, targetNodeId, forceRefresh }) => {
|
|
150
|
+
}, async ({ flow_id, id, nodes, edges, targetNodeId, target_node_id, limit, forceRefresh, force_refresh }) => {
|
|
151
|
+
// F60 + F152: resolve the snake_case aliases. Canonical camelCase
|
|
152
|
+
// wins for the target node (explicit `targetNodeId` over the alias);
|
|
153
|
+
// `forceRefresh` is a boolean OR so either spelling being true refreshes.
|
|
154
|
+
const resolvedTargetNodeId = targetNodeId ?? target_node_id;
|
|
155
|
+
const resolvedForceRefresh = forceRefresh || force_refresh === true;
|
|
90
156
|
// D (2026-06-04): resolve the `id` alias — explicit `flow_id` (canonical)
|
|
91
157
|
// wins over `id` when both are present, mirroring
|
|
92
158
|
// apimapper_flow_full_recompile_publish.
|
|
@@ -119,31 +185,62 @@ export function registerGraphTools(server) {
|
|
|
119
185
|
resolvedEdges = [];
|
|
120
186
|
}
|
|
121
187
|
const localNodes = resolvedNodes;
|
|
122
|
-
|
|
188
|
+
// F5 (2026-06-09): stamp a stable id on any id-less inline edge before
|
|
189
|
+
// POST so the backend graph engine accepts the graph (same fix as
|
|
190
|
+
// flow_create). Hydrated edges already carry ids; ensureEdgeIds is a
|
|
191
|
+
// no-op for them.
|
|
192
|
+
const localEdges = ensureEdgeIds(resolvedEdges);
|
|
193
|
+
// F10 (2026-06-09): when no explicit targetNodeId was given, default to
|
|
194
|
+
// the flow's terminal output node so passing just a flow id previews the
|
|
195
|
+
// finished source (instead of an ambiguous "(terminal)" the backend has
|
|
196
|
+
// to guess). An explicit targetNodeId always wins. Falls back to
|
|
197
|
+
// undefined (backend picks) when the graph carries no output node yet.
|
|
198
|
+
const effectiveTargetNodeId = resolvedTargetNodeId ?? terminalOutputNodeId(localNodes);
|
|
123
199
|
// PHP success body: {preview, outputCount, executedNodes, nodeOutputCounts,
|
|
124
200
|
// nodeOutputs}. There's no `trace` key. Audit: F-A2-11.
|
|
125
201
|
const r = await request("/graph/preview", {
|
|
126
202
|
method: "POST",
|
|
127
|
-
body: JSON.stringify({
|
|
203
|
+
body: JSON.stringify({
|
|
204
|
+
nodes: localNodes,
|
|
205
|
+
edges: localEdges,
|
|
206
|
+
targetNodeId: effectiveTargetNodeId,
|
|
207
|
+
forceRefresh: resolvedForceRefresh,
|
|
208
|
+
}),
|
|
128
209
|
});
|
|
129
210
|
if (!r.success) {
|
|
130
|
-
return restErrorResult(r, { node_count: localNodes.length, edge_count: localEdges.length, targetNodeId, forceRefresh }, { message: "graph preview failed" });
|
|
211
|
+
return restErrorResult(r, { node_count: localNodes.length, edge_count: localEdges.length, targetNodeId: effectiveTargetNodeId, forceRefresh: resolvedForceRefresh }, { message: "graph preview failed" });
|
|
131
212
|
}
|
|
132
213
|
const items = Array.isArray(r.data?.preview) ? r.data.preview : [];
|
|
133
214
|
const itemCount = items.length;
|
|
215
|
+
// A2: forward the merge-no-match diagnostic verbatim (PHP owns the
|
|
216
|
+
// {reason, message, joinKey, joinKeyRight, *_key_sample, …} contract).
|
|
217
|
+
// Additive: only present when PHP attached it (a 0-row join with
|
|
218
|
+
// non-empty inputs), so the happy-path envelope shape is unchanged.
|
|
219
|
+
const mergeDiagnostics = r.data?.mergeDiagnostics !== null &&
|
|
220
|
+
typeof r.data?.mergeDiagnostics === "object" &&
|
|
221
|
+
!Array.isArray(r.data?.mergeDiagnostics) &&
|
|
222
|
+
Object.keys(r.data.mergeDiagnostics).length > 0
|
|
223
|
+
? r.data.mergeDiagnostics
|
|
224
|
+
: undefined;
|
|
225
|
+
// F10: honor `limit` (clamped at the schema to 1..50) when echoing items.
|
|
226
|
+
// The pipeline already executed in full; this only trims the echoed list.
|
|
227
|
+
const itemCap = typeof limit === "number" ? Math.min(limit, 50) : 50;
|
|
134
228
|
return formatResult({
|
|
135
229
|
ok: true,
|
|
136
230
|
item_count: itemCount,
|
|
137
231
|
output_count: r.data?.outputCount,
|
|
138
232
|
executed_nodes: r.data?.executedNodes,
|
|
139
233
|
node_output_counts: r.data?.nodeOutputCounts,
|
|
140
|
-
target_node:
|
|
141
|
-
force_refresh:
|
|
234
|
+
target_node: effectiveTargetNodeId || "(terminal)",
|
|
235
|
+
force_refresh: resolvedForceRefresh,
|
|
142
236
|
...(typeof resolvedFlowId === "string" && resolvedFlowId !== ""
|
|
143
237
|
? { flow_id: resolvedFlowId }
|
|
144
238
|
: {}),
|
|
145
|
-
|
|
146
|
-
|
|
239
|
+
...(mergeDiagnostics ? { merge_diagnostics: mergeDiagnostics } : {}),
|
|
240
|
+
items: items.slice(0, itemCap),
|
|
241
|
+
note: itemCount > itemCap
|
|
242
|
+
? `Showing first ${itemCap} of ${itemCount} items.`
|
|
243
|
+
: undefined,
|
|
147
244
|
}, false, { maxChars: 6000 });
|
|
148
245
|
});
|
|
149
246
|
// ── apimapper_graph_validate ───────────────────────────────────────
|
|
@@ -151,7 +248,7 @@ export function registerGraphTools(server) {
|
|
|
151
248
|
title: "Graph Validate (Shape Check)",
|
|
152
249
|
description: "Validate a graph's structure (cycles, disconnected nodes, missing outputs, type mismatches) " +
|
|
153
250
|
"WITHOUT executing the pipeline. Fast — no upstream fetches." +
|
|
154
|
-
"\n\nExample:\n apimapper_graph_validate({ nodes: [{ id: 'src1', type: 'source' }, { id: 'out1', type: 'output' }], edges: [{ source: 'src1', target: 'out1' }] })",
|
|
251
|
+
"\n\nExample:\n apimapper_graph_validate({ nodes: [{ id: 'src1', type: 'source', position: { x: 0, y: 0 }, data: { connectionId: 'con_abc123' } }, { id: 'out1', type: 'output', position: { x: 320, y: 0 }, data: {} }], edges: [{ source: 'src1', target: 'out1' }] })",
|
|
155
252
|
inputSchema: {
|
|
156
253
|
// L-7 (W3F-5): symmetric with apimapper_graph_preview — pass
|
|
157
254
|
// `flow_id` to validate a saved flow without re-sending the
|
|
@@ -199,7 +296,10 @@ export function registerGraphTools(server) {
|
|
|
199
296
|
resolvedEdges = [];
|
|
200
297
|
}
|
|
201
298
|
const localNodes = resolvedNodes;
|
|
202
|
-
|
|
299
|
+
// F5 (2026-06-09): stamp a stable id on any id-less inline edge before
|
|
300
|
+
// POST — same fix as flow_create / graph_preview. The validator reports
|
|
301
|
+
// edges by id, so an id-less edge surfaced confusing diagnostics.
|
|
302
|
+
const localEdges = ensureEdgeIds(resolvedEdges);
|
|
203
303
|
// PHP success body: {valid:true, warnings:[], nodeCount, edgeCount}. On
|
|
204
304
|
// invalid the errors are squashed to a single string via
|
|
205
305
|
// HandlerResult::error() and surface as `r.error` here. Wave 1C may emit
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../../../src/modules/apimapper/graph.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"graph.js","sourceRoot":"","sources":["../../../src/modules/apimapper/graph.ts"],"names":[],"mappings":"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"}
|