@eclipse-glsp-examples/workflow-server 2.6.0-next.3 → 2.7.0-next.10
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/lib/browser/example1.json +558 -502
- package/lib/common/graph-extension.d.ts +1 -1
- package/lib/common/graph-extension.js +3 -3
- package/lib/common/graph-extension.js.map +1 -1
- package/lib/common/index.d.ts +4 -0
- package/lib/common/index.d.ts.map +1 -1
- package/lib/common/index.js +4 -0
- package/lib/common/index.js.map +1 -1
- package/lib/common/mcp/workflow-element-types-provider.d.ts +27 -0
- package/lib/common/mcp/workflow-element-types-provider.d.ts.map +1 -0
- package/lib/common/mcp/workflow-element-types-provider.js +62 -0
- package/lib/common/mcp/workflow-element-types-provider.js.map +1 -0
- package/lib/common/mcp/workflow-mcp-label-provider.d.ts +27 -0
- package/lib/common/mcp/workflow-mcp-label-provider.d.ts.map +1 -0
- package/lib/common/mcp/workflow-mcp-label-provider.js +48 -0
- package/lib/common/mcp/workflow-mcp-label-provider.js.map +1 -0
- package/lib/common/mcp/workflow-mcp-model-serializer.d.ts +29 -0
- package/lib/common/mcp/workflow-mcp-model-serializer.d.ts.map +1 -0
- package/lib/common/mcp/workflow-mcp-model-serializer.js +189 -0
- package/lib/common/mcp/workflow-mcp-model-serializer.js.map +1 -0
- package/lib/common/mcp/workflow-mcp-module.d.ts +36 -0
- package/lib/common/mcp/workflow-mcp-module.d.ts.map +1 -0
- package/lib/common/mcp/workflow-mcp-module.js +49 -0
- package/lib/common/mcp/workflow-mcp-module.js.map +1 -0
- package/lib/common/util/model-types.d.ts +1 -1
- package/lib/common/util/model-types.d.ts.map +1 -1
- package/lib/common/util/model-types.js +1 -2
- package/lib/common/util/model-types.js.map +1 -1
- package/lib/common/workflow-diagram-module.d.ts +3 -3
- package/lib/common/workflow-diagram-module.d.ts.map +1 -1
- package/lib/common/workflow-diagram-module.js +3 -3
- package/lib/common/workflow-diagram-module.js.map +1 -1
- package/lib/common/workflow-glsp-server.d.ts +4 -4
- package/lib/common/workflow-glsp-server.d.ts.map +1 -1
- package/lib/common/workflow-glsp-server.js +12 -13
- package/lib/common/workflow-glsp-server.js.map +1 -1
- package/lib/node/app.d.ts +1 -1
- package/lib/node/app.js +6 -5
- package/lib/node/app.js.map +1 -1
- package/package.json +6 -5
- package/src/browser/example1.json +558 -502
- package/src/common/graph-extension.ts +3 -3
- package/src/common/index.ts +4 -0
- package/src/common/mcp/workflow-element-types-provider.ts +54 -0
- package/src/common/mcp/workflow-mcp-label-provider.ts +37 -0
- package/src/common/mcp/workflow-mcp-model-serializer.ts +187 -0
- package/src/common/mcp/workflow-mcp-module.ts +54 -0
- package/src/common/util/model-types.ts +1 -2
- package/src/common/workflow-diagram-module.ts +5 -5
- package/src/common/workflow-glsp-server.ts +17 -10
- package/src/node/app.ts +12 -8
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/********************************************************************************
|
|
2
|
-
* Copyright (c) 2022-
|
|
2
|
+
* Copyright (c) 2022-2026 STMicroelectronics and others.
|
|
3
3
|
*
|
|
4
4
|
* This program and the accompanying materials are made available under the
|
|
5
5
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
@@ -86,7 +86,7 @@ export class TaskNodeBuilder<T extends TaskNode = TaskNode> extends GNodeBuilder
|
|
|
86
86
|
protected createCompartmentHeader(): GLabel {
|
|
87
87
|
return new GLabelBuilder(GLabel)
|
|
88
88
|
.type(ModelTypes.LABEL_HEADING)
|
|
89
|
-
.id(this.proxy.id + '
|
|
89
|
+
.id(this.proxy.id + '_label')
|
|
90
90
|
.text(this.proxy.name)
|
|
91
91
|
.build();
|
|
92
92
|
}
|
|
@@ -151,7 +151,7 @@ export class CategoryNodeBuilder<T extends Category = Category> extends Activity
|
|
|
151
151
|
protected createCompartmentHeader(): GLabel {
|
|
152
152
|
return new GLabelBuilder(GLabel)
|
|
153
153
|
.type(ModelTypes.LABEL_HEADING)
|
|
154
|
-
.id(this.proxy.id + '
|
|
154
|
+
.id(this.proxy.id + '_label')
|
|
155
155
|
.text(this.proxy.name)
|
|
156
156
|
.build();
|
|
157
157
|
}
|
package/src/common/index.ts
CHANGED
|
@@ -32,6 +32,10 @@ export * from './handler/grid-snapper';
|
|
|
32
32
|
export * from './labeledit/workflow-label-edit-validator';
|
|
33
33
|
export * from './layout/workflow-layout-configurator';
|
|
34
34
|
export * from './marker/workflow-model-validator';
|
|
35
|
+
export * from './mcp/workflow-element-types-provider';
|
|
36
|
+
export * from './mcp/workflow-mcp-label-provider';
|
|
37
|
+
export * from './mcp/workflow-mcp-model-serializer';
|
|
38
|
+
export * from './mcp/workflow-mcp-module';
|
|
35
39
|
export * from './model/workflow-navigation-target-resolver';
|
|
36
40
|
export * from './provider/abstract-next-or-previous-navigation-target-provider';
|
|
37
41
|
export * from './provider/next-node-navigation-target-provider';
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2026 EclipseSource and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
*
|
|
8
|
+
* This Source Code may also be made available under the following Secondary
|
|
9
|
+
* Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
* with the GNU Classpath Exception which is available at
|
|
12
|
+
* https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
*
|
|
14
|
+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
********************************************************************************/
|
|
16
|
+
|
|
17
|
+
import { DefaultTypes } from '@eclipse-glsp/server';
|
|
18
|
+
import { ElementTypeEntry, ElementTypes, ElementTypesProvider } from '@eclipse-glsp/server-mcp';
|
|
19
|
+
import { injectable } from 'inversify';
|
|
20
|
+
import { ModelTypes } from '../util/model-types';
|
|
21
|
+
|
|
22
|
+
const NODE_TYPES: ElementTypeEntry[] = [
|
|
23
|
+
{ id: ModelTypes.AUTOMATED_TASK, label: 'Automated Task', description: 'Task without human input', acceptsText: true },
|
|
24
|
+
{ id: ModelTypes.MANUAL_TASK, label: 'Manual Task', description: 'Task done by a human', acceptsText: true },
|
|
25
|
+
{ id: ModelTypes.JOIN_NODE, label: 'Join Node', description: 'Gateway that merges parallel flows', acceptsText: false },
|
|
26
|
+
{ id: ModelTypes.FORK_NODE, label: 'Fork Node', description: 'Gateway that splits into parallel flows', acceptsText: false },
|
|
27
|
+
{ id: ModelTypes.MERGE_NODE, label: 'Merge Node', description: 'Gateway that merges alternative flows', acceptsText: false },
|
|
28
|
+
{ id: ModelTypes.DECISION_NODE, label: 'Decision Node', description: 'Gateway that splits into alternative flows', acceptsText: false },
|
|
29
|
+
{ id: ModelTypes.CATEGORY, label: 'Category', description: 'Container node that groups other elements', acceptsText: true }
|
|
30
|
+
];
|
|
31
|
+
|
|
32
|
+
const EDGE_TYPES: ElementTypeEntry[] = [
|
|
33
|
+
{ id: DefaultTypes.EDGE, label: 'Edge', description: 'Standard control flow edge', acceptsText: false },
|
|
34
|
+
{
|
|
35
|
+
id: ModelTypes.WEIGHTED_EDGE,
|
|
36
|
+
label: 'Weighted Edge',
|
|
37
|
+
description: 'Edge that indicates a weighted probability. Typically used with a Decision Node.',
|
|
38
|
+
acceptsText: false
|
|
39
|
+
}
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Workflow-specific {@link ElementTypesProvider}. Returns the constant set of creatable types
|
|
44
|
+
* with richer LLM-facing fields (`description`, `acceptsText`) than the default registry-scrape
|
|
45
|
+
* impl can infer. Bound on the workflow MCP diagram module via `bindElementTypesProvider()`;
|
|
46
|
+
* the standard `element-types` tool handler exposes the full entries via `structuredContent`
|
|
47
|
+
* (with a short summary in the text content) — no handler rebind needed.
|
|
48
|
+
*/
|
|
49
|
+
@injectable()
|
|
50
|
+
export class WorkflowElementTypesProvider implements ElementTypesProvider {
|
|
51
|
+
get(): ElementTypes {
|
|
52
|
+
return { nodeTypes: NODE_TYPES, edgeTypes: EDGE_TYPES };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2026 EclipseSource and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
*
|
|
8
|
+
* This Source Code may also be made available under the following Secondary
|
|
9
|
+
* Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
* with the GNU Classpath Exception which is available at
|
|
12
|
+
* https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
*
|
|
14
|
+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
********************************************************************************/
|
|
16
|
+
|
|
17
|
+
import { GLabel, GModelElement } from '@eclipse-glsp/server';
|
|
18
|
+
import { DefaultMcpLabelProvider } from '@eclipse-glsp/server-mcp';
|
|
19
|
+
import { injectable } from 'inversify';
|
|
20
|
+
import { ModelTypes } from '../util/model-types';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Workflow-specific {@link DefaultMcpLabelProvider}: category labels are nested inside a
|
|
24
|
+
* compartment-header child rather than directly under the category, so the default
|
|
25
|
+
* direct-child lookup misses them. Other workflow element types fall through to the
|
|
26
|
+
* inherited default.
|
|
27
|
+
*/
|
|
28
|
+
@injectable()
|
|
29
|
+
export class WorkflowMcpLabelProvider extends DefaultMcpLabelProvider {
|
|
30
|
+
override getLabel(element: GModelElement): GLabel | undefined {
|
|
31
|
+
if (element.type === ModelTypes.CATEGORY) {
|
|
32
|
+
const header = element.children.find(child => child.type === ModelTypes.COMP_HEADER);
|
|
33
|
+
return header?.children.find((child): child is GLabel => child instanceof GLabel);
|
|
34
|
+
}
|
|
35
|
+
return super.getLabel(element);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2026 EclipseSource and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
*
|
|
8
|
+
* This Source Code may also be made available under the following Secondary
|
|
9
|
+
* Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
* with the GNU Classpath Exception which is available at
|
|
12
|
+
* https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
*
|
|
14
|
+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
********************************************************************************/
|
|
16
|
+
|
|
17
|
+
import { GModelElement } from '@eclipse-glsp/graph';
|
|
18
|
+
import { Dimension, DefaultTypes } from '@eclipse-glsp/server';
|
|
19
|
+
import { MarkdownMcpModelSerializer, SerializedElement } from '@eclipse-glsp/server-mcp';
|
|
20
|
+
import { injectable } from 'inversify';
|
|
21
|
+
import { ModelTypes } from '../util/model-types';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* As compared to the {@link MarkdownMcpModelSerializer}, this is a specific implementation and we
|
|
25
|
+
* know not only the structure of our graph but also each relevant attribute. This enables us to
|
|
26
|
+
* order them semantically so the produced serialization makes more sense if read with semantics
|
|
27
|
+
* mind. As LLMs (i.e., the MCP clients) work semantically, this is superior to a random ordering.
|
|
28
|
+
* Furthermore, including only the relevant information without redundancies decreases context size.
|
|
29
|
+
*/
|
|
30
|
+
@injectable()
|
|
31
|
+
export class WorkflowMcpModelSerializer extends MarkdownMcpModelSerializer {
|
|
32
|
+
override prepareElement(element: GModelElement): Record<string, SerializedElement[]> {
|
|
33
|
+
// Pass the live parent's id so the input element gets `parentId` set even when the
|
|
34
|
+
// spread inside `flattenStructure` doesn't carry the (typically non-enumerable) `parent`
|
|
35
|
+
// reference. Without this, `query-elements` inspect on a single leaf drops `parentId`,
|
|
36
|
+
// creating an inconsistency with `diagram-model`.
|
|
37
|
+
const elements = this.flattenStructure(element as unknown as SerializedElement, element.parent?.id);
|
|
38
|
+
|
|
39
|
+
// Define the order of keys
|
|
40
|
+
const result: Record<string, SerializedElement[]> = {
|
|
41
|
+
[DefaultTypes.GRAPH]: [],
|
|
42
|
+
[ModelTypes.CATEGORY]: [],
|
|
43
|
+
[ModelTypes.AUTOMATED_TASK]: [],
|
|
44
|
+
[ModelTypes.MANUAL_TASK]: [],
|
|
45
|
+
[ModelTypes.FORK_NODE]: [],
|
|
46
|
+
[ModelTypes.JOIN_NODE]: [],
|
|
47
|
+
[ModelTypes.DECISION_NODE]: [],
|
|
48
|
+
[ModelTypes.MERGE_NODE]: [],
|
|
49
|
+
[DefaultTypes.EDGE]: [],
|
|
50
|
+
[ModelTypes.WEIGHTED_EDGE]: []
|
|
51
|
+
};
|
|
52
|
+
elements.forEach(serialized => {
|
|
53
|
+
this.combinePositionAndSize(serialized);
|
|
54
|
+
|
|
55
|
+
const adjustedElement = this.adjustElement(serialized);
|
|
56
|
+
if (!adjustedElement) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const type = serialized.type;
|
|
61
|
+
if (typeof type === 'string' && result[type]) {
|
|
62
|
+
result[type].push(adjustedElement);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
private adjustElement(element: SerializedElement): SerializedElement | undefined {
|
|
70
|
+
const type = element.type;
|
|
71
|
+
switch (type) {
|
|
72
|
+
case ModelTypes.AUTOMATED_TASK:
|
|
73
|
+
case ModelTypes.MANUAL_TASK: {
|
|
74
|
+
const children = Array.isArray(element.children) ? (element.children as SerializedElement[]) : [];
|
|
75
|
+
const label = children.find(child => child.type === ModelTypes.LABEL_HEADING);
|
|
76
|
+
if (!label || !Dimension.is(label.size)) {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// For tasks, the only content with impact on element size is the label
|
|
81
|
+
// Therefore, all other factors get integrated into the label size for the AI to do proper resizing operations
|
|
82
|
+
const labelSize = {
|
|
83
|
+
// 10px padding right, 31px padding left (incl. icon)
|
|
84
|
+
width: Math.trunc(label.size.width + 10 + 31),
|
|
85
|
+
// 7px padding top and bottom each
|
|
86
|
+
height: Math.trunc(label.size.height + 14)
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
// If the task lives inside a `STRUCTURE` (a layout-only wrapper), report the
|
|
90
|
+
// structure's parent as the logical parent. Falls back to the direct `parentId`
|
|
91
|
+
// when the task is at the root or the structure has no parent.
|
|
92
|
+
const liveParent = (element as { parent?: GModelElement }).parent;
|
|
93
|
+
const parentId = liveParent?.type === ModelTypes.STRUCTURE ? liveParent.parent?.id ?? element.parentId : element.parentId;
|
|
94
|
+
return {
|
|
95
|
+
id: element.id,
|
|
96
|
+
type,
|
|
97
|
+
position: element.position,
|
|
98
|
+
size: element.size,
|
|
99
|
+
bounds: element.bounds,
|
|
100
|
+
label: label.text,
|
|
101
|
+
labelSize,
|
|
102
|
+
parentId
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
case ModelTypes.CATEGORY: {
|
|
106
|
+
const children = Array.isArray(element.children) ? (element.children as SerializedElement[]) : [];
|
|
107
|
+
const header = children.find(child => child.type === ModelTypes.COMP_HEADER);
|
|
108
|
+
const headerChildren = header && Array.isArray(header.children) ? (header.children as SerializedElement[]) : [];
|
|
109
|
+
const label = headerChildren.find(child => child.type === ModelTypes.LABEL_HEADING);
|
|
110
|
+
if (!label || !Dimension.is(label.size)) {
|
|
111
|
+
return undefined;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const labelSize = {
|
|
115
|
+
width: Math.trunc(label.size.width + 20),
|
|
116
|
+
height: Math.trunc(label.size.height + 20)
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
// `combinePositionAndSize` (in MarkdownMcpModelSerializer) omits `size`/`bounds`
|
|
120
|
+
// when an element has no explicit geometry yet, so the LLM doesn't try to "fix"
|
|
121
|
+
// placeholder bounds. Categories normally do have an explicit size in the model,
|
|
122
|
+
// but if a freshly created (or otherwise unsized) category lands here, skip the
|
|
123
|
+
// derived `usableSpaceSize` rather than crashing on `element.size.width`.
|
|
124
|
+
const usableSpaceSize = Dimension.is(element.size)
|
|
125
|
+
? {
|
|
126
|
+
width: Math.trunc(Math.max(0, element.size.width - 10)),
|
|
127
|
+
height: Math.trunc(Math.max(0, element.size.height - labelSize.height - 10))
|
|
128
|
+
}
|
|
129
|
+
: undefined;
|
|
130
|
+
|
|
131
|
+
return {
|
|
132
|
+
id: element.id,
|
|
133
|
+
type,
|
|
134
|
+
isContainer: true,
|
|
135
|
+
position: element.position,
|
|
136
|
+
size: element.size,
|
|
137
|
+
bounds: element.bounds,
|
|
138
|
+
label: label.text,
|
|
139
|
+
labelSize,
|
|
140
|
+
usableSpaceSize,
|
|
141
|
+
parentId: element.parentId
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
case ModelTypes.JOIN_NODE:
|
|
145
|
+
case ModelTypes.MERGE_NODE:
|
|
146
|
+
case ModelTypes.DECISION_NODE:
|
|
147
|
+
case ModelTypes.FORK_NODE: {
|
|
148
|
+
return {
|
|
149
|
+
id: element.id,
|
|
150
|
+
type,
|
|
151
|
+
position: element.position,
|
|
152
|
+
size: element.size,
|
|
153
|
+
bounds: element.bounds,
|
|
154
|
+
parentId: element.parentId
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
case DefaultTypes.EDGE: {
|
|
158
|
+
return {
|
|
159
|
+
id: element.id,
|
|
160
|
+
type,
|
|
161
|
+
sourceId: element.sourceId,
|
|
162
|
+
targetId: element.targetId,
|
|
163
|
+
parentId: element.parentId
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
case ModelTypes.WEIGHTED_EDGE: {
|
|
167
|
+
return {
|
|
168
|
+
id: element.id,
|
|
169
|
+
type,
|
|
170
|
+
sourceId: element.sourceId,
|
|
171
|
+
targetId: element.targetId,
|
|
172
|
+
probability: element.probability,
|
|
173
|
+
parentId: element.parentId
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
case DefaultTypes.GRAPH: {
|
|
177
|
+
return {
|
|
178
|
+
id: element.id,
|
|
179
|
+
type,
|
|
180
|
+
isContainer: true
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
default:
|
|
184
|
+
return undefined;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (c) 2026 EclipseSource and others.
|
|
3
|
+
*
|
|
4
|
+
* This program and the accompanying materials are made available under the
|
|
5
|
+
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
* http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
*
|
|
8
|
+
* This Source Code may also be made available under the following Secondary
|
|
9
|
+
* Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
* with the GNU Classpath Exception which is available at
|
|
12
|
+
* https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
*
|
|
14
|
+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
********************************************************************************/
|
|
16
|
+
|
|
17
|
+
import { BindingTarget } from '@eclipse-glsp/server';
|
|
18
|
+
import {
|
|
19
|
+
DefaultMcpDiagramModule,
|
|
20
|
+
DefaultMcpServerModule,
|
|
21
|
+
ElementTypesProvider,
|
|
22
|
+
McpLabelProvider,
|
|
23
|
+
McpModelSerializer
|
|
24
|
+
} from '@eclipse-glsp/server-mcp';
|
|
25
|
+
import { WorkflowElementTypesProvider } from './workflow-element-types-provider';
|
|
26
|
+
import { WorkflowMcpLabelProvider } from './workflow-mcp-label-provider';
|
|
27
|
+
import { WorkflowMcpModelSerializer } from './workflow-mcp-model-serializer';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Workflow-specific server-scope MCP module. Currently no server-scope customizations beyond
|
|
31
|
+
* the defaults — every diagram-type-specific override lives on {@link WorkflowMcpDiagramModule}.
|
|
32
|
+
* Kept as the named entry point and as a hook for future server-scope extensions.
|
|
33
|
+
*/
|
|
34
|
+
export class WorkflowMcpServerModule extends DefaultMcpServerModule {}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Workflow-specific diagram-scope MCP module — swaps in the workflow-aware
|
|
38
|
+
* {@link McpLabelProvider}, {@link McpModelSerializer}, and {@link ElementTypesProvider}.
|
|
39
|
+
* `LayoutMcpToolHandler` ships in the default tool set and self-skips when no `LayoutEngine`
|
|
40
|
+
* is bound, so workflow doesn't need to add it explicitly.
|
|
41
|
+
*/
|
|
42
|
+
export class WorkflowMcpDiagramModule extends DefaultMcpDiagramModule {
|
|
43
|
+
protected override bindLabelProvider(): BindingTarget<McpLabelProvider> {
|
|
44
|
+
return WorkflowMcpLabelProvider;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
protected override bindModelSerializer(): BindingTarget<McpModelSerializer> {
|
|
48
|
+
return WorkflowMcpModelSerializer;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
protected override bindElementTypesProvider(): BindingTarget<ElementTypesProvider> {
|
|
52
|
+
return WorkflowElementTypesProvider;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/********************************************************************************
|
|
2
|
-
* Copyright (c) 2022-
|
|
2
|
+
* Copyright (c) 2022-2026 STMicroelectronics and others.
|
|
3
3
|
*
|
|
4
4
|
* This program and the accompanying materials are made available under the
|
|
5
5
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
*
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
|
-
/* eslint-disable @typescript-eslint/padding-line-between-statements */
|
|
17
16
|
export namespace ModelTypes {
|
|
18
17
|
export const LABEL_HEADING = 'label:heading';
|
|
19
18
|
export const LABEL_TEXT = 'label:text';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/********************************************************************************
|
|
2
|
-
* Copyright (c) 2022-
|
|
2
|
+
* Copyright (c) 2022-2026 STMicroelectronics and others.
|
|
3
3
|
*
|
|
4
4
|
* This program and the accompanying materials are made available under the
|
|
5
5
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
ContextMenuItemProvider,
|
|
22
22
|
DiagramConfiguration,
|
|
23
23
|
EdgeCreationChecker,
|
|
24
|
-
|
|
24
|
+
GLSPServerInitializer,
|
|
25
25
|
GModelDiagramModule,
|
|
26
26
|
InstanceMultiBinding,
|
|
27
27
|
LabelEditValidator,
|
|
@@ -57,13 +57,13 @@ import { TaskEditContextActionProvider } from './taskedit/task-edit-context-prov
|
|
|
57
57
|
import { TaskEditValidator } from './taskedit/task-edit-validator';
|
|
58
58
|
import { WorkflowDiagramConfiguration } from './workflow-diagram-configuration';
|
|
59
59
|
import { WorkflowEdgeCreationChecker } from './workflow-edge-creation-checker';
|
|
60
|
-
import {
|
|
60
|
+
import { CustomArgsInitContribution } from './workflow-glsp-server';
|
|
61
61
|
import { WorkflowPopupFactory } from './workflow-popup-factory';
|
|
62
62
|
|
|
63
63
|
@injectable()
|
|
64
64
|
export class WorkflowServerModule extends ServerModule {
|
|
65
|
-
protected override
|
|
66
|
-
|
|
65
|
+
protected override configureGLSPServerInitializers(binding: MultiBinding<GLSPServerInitializer>): void {
|
|
66
|
+
binding.add(CustomArgsInitContribution);
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/********************************************************************************
|
|
2
|
-
* Copyright (c) 2022-
|
|
2
|
+
* Copyright (c) 2022-2026 STMicroelectronics and others.
|
|
3
3
|
*
|
|
4
4
|
* This program and the accompanying materials are made available under the
|
|
5
5
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
@@ -13,25 +13,32 @@
|
|
|
13
13
|
*
|
|
14
14
|
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
15
|
********************************************************************************/
|
|
16
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
ArgsUtil,
|
|
18
|
+
GLSPServer,
|
|
19
|
+
GLSPServerInitializer,
|
|
20
|
+
InitializeParameters,
|
|
21
|
+
InitializeResult,
|
|
22
|
+
Logger,
|
|
23
|
+
MaybePromise
|
|
24
|
+
} from '@eclipse-glsp/server';
|
|
17
25
|
import { inject, injectable } from 'inversify';
|
|
18
26
|
|
|
19
27
|
@injectable()
|
|
20
|
-
export class
|
|
28
|
+
export class CustomArgsInitContribution implements GLSPServerInitializer {
|
|
21
29
|
MESSAGE_KEY = 'message';
|
|
22
30
|
TIMESTAMP_KEY = 'timestamp';
|
|
23
31
|
|
|
24
|
-
@inject(Logger)
|
|
25
|
-
protected override logger: Logger;
|
|
32
|
+
@inject(Logger) protected logger: Logger;
|
|
26
33
|
|
|
27
|
-
|
|
28
|
-
if (!args) {
|
|
34
|
+
initializeServer(server: GLSPServer, params: InitializeParameters, result: InitializeResult): MaybePromise<InitializeResult> {
|
|
35
|
+
if (!params.args) {
|
|
29
36
|
return result;
|
|
30
37
|
}
|
|
31
|
-
const timestamp = ArgsUtil.get(args, this.TIMESTAMP_KEY);
|
|
32
|
-
const message = ArgsUtil.get(args, this.MESSAGE_KEY);
|
|
38
|
+
const timestamp = ArgsUtil.get(params.args, this.TIMESTAMP_KEY);
|
|
39
|
+
const message = ArgsUtil.get(params.args, this.MESSAGE_KEY);
|
|
33
40
|
|
|
34
|
-
this.logger.
|
|
41
|
+
this.logger.info(`${timestamp}: ${message}`);
|
|
35
42
|
return result;
|
|
36
43
|
}
|
|
37
44
|
}
|
package/src/node/app.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/********************************************************************************
|
|
2
|
-
* Copyright (c) 2022-
|
|
2
|
+
* Copyright (c) 2022-2026 STMicroelectronics and others.
|
|
3
3
|
*
|
|
4
4
|
* This program and the accompanying materials are made available under the
|
|
5
5
|
* terms of the Eclipse Public License v. 2.0 which is available at
|
|
@@ -15,11 +15,12 @@
|
|
|
15
15
|
********************************************************************************/
|
|
16
16
|
import 'reflect-metadata';
|
|
17
17
|
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
18
|
+
import { ElkLayoutModule } from '@eclipse-glsp/layout-elk';
|
|
19
|
+
import { GModelStorage, Logger, SocketServerLauncher, WebSocketServerLauncher, createAppModule } from '@eclipse-glsp/server/node';
|
|
20
20
|
import { Container } from 'inversify';
|
|
21
21
|
|
|
22
22
|
import { WorkflowLayoutConfigurator } from '../common/layout/workflow-layout-configurator';
|
|
23
|
+
import { WorkflowMcpDiagramModule, WorkflowMcpServerModule } from '../common/mcp/workflow-mcp-module';
|
|
23
24
|
import { WorkflowDiagramModule, WorkflowServerModule } from '../common/workflow-diagram-module';
|
|
24
25
|
import { createWorkflowCliParser } from './workflow-cli-parser';
|
|
25
26
|
|
|
@@ -38,16 +39,19 @@ async function launch(argv?: string[]): Promise<void> {
|
|
|
38
39
|
logger.error('Uncaught exception:', error);
|
|
39
40
|
});
|
|
40
41
|
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
const serverModule = new WorkflowServerModule().configureDiagramModule(
|
|
43
|
+
new WorkflowDiagramModule(() => GModelStorage),
|
|
44
|
+
new ElkLayoutModule({ algorithms: ['layered'], layoutConfigurator: WorkflowLayoutConfigurator }),
|
|
45
|
+
new WorkflowMcpDiagramModule()
|
|
46
|
+
);
|
|
47
|
+
const mcpServerModule = new WorkflowMcpServerModule();
|
|
44
48
|
if (options.webSocket) {
|
|
45
49
|
const launcher = appContainer.resolve(WebSocketServerLauncher);
|
|
46
|
-
launcher.configure(serverModule);
|
|
50
|
+
launcher.configure(serverModule, mcpServerModule);
|
|
47
51
|
await launcher.start({ port: options.port, host: options.host, path: 'workflow' });
|
|
48
52
|
} else {
|
|
49
53
|
const launcher = appContainer.resolve(SocketServerLauncher);
|
|
50
|
-
launcher.configure(serverModule);
|
|
54
|
+
launcher.configure(serverModule, mcpServerModule);
|
|
51
55
|
await launcher.start({ port: options.port, host: options.host });
|
|
52
56
|
}
|
|
53
57
|
}
|