Skip to content

Commit a98130f

Browse files
WIP: Restructure comments
1 parent e26566a commit a98130f

10 files changed

Lines changed: 341 additions & 108 deletions

File tree

apps/sandbox/src/main.ts

Lines changed: 218 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,231 @@
1-
import { AnalyticsRepositoryRegistry } from '@idl/mcp/analytics-repository';
1+
// import { AnalyticsRepositoryRegistry } from '@idl/mcp/analytics-repository';
2+
import {
3+
CreateENVIModelerWorkflow,
4+
ValidateENVIModelerNodes,
5+
} from '@idl/envi/modeler';
6+
import { LogManager } from '@idl/logger';
7+
import { MCPTaskRegistry } from '@idl/mcp/tasks';
8+
import { IDLIndex } from '@idl/parsing/index';
9+
import { GLOBAL_TOKEN_TYPES } from '@idl/types/idl-data-types';
10+
import { ENVIModelerEdge, ENVIModelerNode } from '@idl/types/mcp';
11+
import { DEFAULT_IDL_EXTENSION_CONFIG } from '@idl/vscode/extension-config';
12+
import { writeFileSync } from 'fs';
213

314
// const parsed2 = IDLTypeHelper.parseIDLType(serialize);
415

516
// console.log(StringifyDataForLog('', parsed));
617
// console.log(StringifyDataForLog('', serialize));
718
// console.log(StringifyDataForLog('', parsed2));
819

9-
async function Main() {
10-
const registry = new AnalyticsRepositoryRegistry([
20+
const model = {
21+
output_path:
22+
'c:\\Users\\Zachary.Norman\\Desktop\\scratch-sprint-review\\ml_change_detection.model',
23+
nodes: [
24+
{
25+
id: 'inputs',
26+
type: 'inputparameters',
27+
parameters: [
28+
{
29+
name: 'time1_raster',
30+
display_name: 'Time 1 Image',
31+
description: 'Pre-event raster image',
32+
type: 'ENVIRaster',
33+
},
34+
{
35+
name: 'time2_raster',
36+
display_name: 'Time 2 Image',
37+
description: 'Post-event raster image',
38+
type: 'ENVIRaster',
39+
},
40+
{
41+
name: 'training_rois',
42+
display_name: 'Training ROIs',
43+
description: 'ROIs with Background (no change) and Change classes',
44+
type: 'ENVIROIArray',
45+
},
46+
],
47+
},
48+
{
49+
id: 'intersection',
50+
type: 'task',
51+
display_name: 'Image Intersection',
52+
task_name: 'ImageIntersection',
53+
},
54+
{
55+
id: 'bandstack',
56+
type: 'task',
57+
display_name: 'Build Band Stack',
58+
task_name: 'BuildBandStack',
59+
},
60+
{
61+
id: 'normstats',
62+
type: 'task',
63+
display_name: 'Normalization Statistics',
64+
task_name: 'NormalizationStatistics',
65+
},
66+
{
67+
id: 'trainingdata',
68+
type: 'task',
69+
display_name: 'Extract Training Data',
70+
task_name: 'MLTrainingDataFromROIs',
71+
},
72+
{
73+
id: 'trainmodel',
74+
type: 'task',
75+
display_name: 'Train Random Forest Model',
76+
task_name: 'TrainRandomForest',
77+
},
78+
{
79+
id: 'classify',
80+
type: 'task',
81+
display_name: 'ML Classification',
82+
task_name: 'MachineLearningClassification',
83+
},
84+
{
85+
id: 'smoothing',
86+
type: 'task',
87+
display_name: 'Classification Smoothing',
88+
task_name: 'ClassificationSmoothing',
89+
},
90+
{
91+
id: 'outputs',
92+
type: 'outputparameters',
93+
display_name: 'Workflow Outputs',
94+
},
95+
{ id: 'view_result', type: 'view', display_name: 'View Result' },
96+
],
97+
edges: [
98+
{
99+
from: 'inputs',
100+
from_parameters: ['time1_raster', 'time2_raster'],
101+
to: 'intersection',
102+
to_parameters: ['input_raster1', 'input_raster2'],
103+
},
104+
{
105+
from: 'intersection',
106+
from_parameters: ['output_raster1', 'output_raster2'],
107+
to: 'bandstack',
108+
to_parameters: ['input_raster1', 'input_raster2'],
109+
},
110+
{
111+
from: 'bandstack',
112+
from_parameters: ['output_raster'],
113+
to: 'normstats',
114+
to_parameters: ['input_raster'],
115+
},
116+
{
117+
from: 'bandstack',
118+
from_parameters: ['output_raster'],
119+
to: 'trainingdata',
120+
to_parameters: ['input_raster'],
121+
},
122+
{
123+
from: 'inputs',
124+
from_parameters: ['training_rois'],
125+
to: 'trainingdata',
126+
to_parameters: ['input_roi'],
127+
},
128+
{
129+
from: 'trainingdata',
130+
from_parameters: ['output_training_data'],
131+
to: 'trainmodel',
132+
to_parameters: ['input_training_data'],
133+
},
134+
{
135+
from: 'normstats',
136+
from_parameters: ['output_normalization_statistics'],
137+
to: 'trainmodel',
138+
to_parameters: ['input_normalization_statistics'],
139+
},
140+
{
141+
from: 'bandstack',
142+
from_parameters: ['output_raster'],
143+
to: 'classify',
144+
to_parameters: ['input_raster'],
145+
},
146+
{
147+
from: 'trainmodel',
148+
from_parameters: ['output_model'],
149+
to: 'classify',
150+
to_parameters: ['input_model'],
151+
},
152+
{
153+
from: 'normstats',
154+
from_parameters: ['output_normalization_statistics'],
155+
to: 'classify',
156+
to_parameters: ['input_normalization_statistics'],
157+
},
158+
{
159+
from: 'classify',
160+
from_parameters: ['output_raster'],
161+
to: 'smoothing',
162+
to_parameters: ['input_raster'],
163+
},
164+
{
165+
from: 'smoothing',
166+
from_parameters: ['output_raster'],
167+
to: 'outputs',
168+
to_parameters: [''],
169+
},
11170
{
12-
url: 'http://localhost:9194',
171+
from: 'smoothing',
172+
from_parameters: ['output_raster'],
173+
to: 'view_result',
174+
to_parameters: ['input_raster'],
13175
},
14-
]);
176+
],
177+
};
178+
179+
async function Main() {
180+
// const registry = new AnalyticsRepositoryRegistry([
181+
// {
182+
// url: 'http://localhost:9194',
183+
// },
184+
// ]);
185+
186+
// console.log(await registry.searchRepositories());
187+
188+
const logManager = new LogManager({
189+
alert: () => {
190+
//
191+
},
192+
});
193+
194+
// index
195+
const index = new IDLIndex(logManager, 1, false);
196+
197+
// load global tokens
198+
index.loadGlobalTokens(DEFAULT_IDL_EXTENSION_CONFIG);
199+
200+
const registry = new MCPTaskRegistry(logManager);
201+
202+
registry.registerTasksFromGlobalTokens(
203+
index.globalIndex.globalTokensByTypeByName[GLOBAL_TOKEN_TYPES.FUNCTION],
204+
index.globalIndex.globalTokensByTypeByName[GLOBAL_TOKEN_TYPES.STRUCTURE],
205+
);
206+
207+
const errs = ValidateENVIModelerNodes(
208+
model.nodes as ENVIModelerNode[],
209+
model.edges as ENVIModelerEdge[],
210+
registry,
211+
);
212+
213+
if (errs.length > 0) {
214+
console.log(errs);
215+
return;
216+
}
217+
218+
const modelJson = CreateENVIModelerWorkflow(
219+
model.nodes as ENVIModelerNode[],
220+
model.edges as ENVIModelerEdge[],
221+
registry,
222+
);
15223

16-
console.log(await registry.searchRepositories());
224+
writeFileSync(
225+
'C:\\Users\\Zach\\Documents\\node\\vscode-idl\\apps\\sandbox\\src\\model.model',
226+
JSON.stringify(modelJson, null, 2),
227+
'utf-8',
228+
);
17229
}
18230

19231
Main()

extension/github-copilot/prompts/ENVI/enviModelerWorkflow.prompt.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,8 @@ Use `create-envi-modeler-workflow` with:
6767
3. Optionally `iterator` + `aggregator` nodes for batch/loop processing.
6868
4. Optionally `arrayvalues` nodes for iterating over literal value lists.
6969
5. `view` and/or `datamanager` nodes at the end.
70-
6. `comment` nodes scattered throughout to document the workflow for future readers.
70+
6. `comment` property on any node — set `comment: "..."` to place an annotation above that node on the canvas.
71+
Comments are auto-positioned and follow the node if layout shifts.
7172

7273
**edges** — connect outputs to inputs:
7374

@@ -117,7 +118,7 @@ iterator → task_1 → aggregator → task_2 → view
117118

118119
- **Do not** include task parameters in `static_input` if they match the task default.
119120
- **Do not** add more than one `view`, `datamanager`, or `outputparameters` node — only a single instance of each is valid in a workflow.
120-
- **Do** add `comment` nodes to explain non-obvious design decisions (see official examples).
121+
- **Do** add a `comment` property to nodes that need annotation to explain non-obvious design decisions.
121122
- **Do** add a `view` and `datamanager` node for final raster outputs so the workflow is usable interactively.
122123
- **Do** expose parameters in `inputparameters` that users will realistically vary between runs.
123124
- Parameter `name` values in `inputparameters.parameters[]` should be UPPERCASE.

libs/envi/modeler/src/lib/create-envi-modeler-workflow.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { ENVIModelerEdge, ENVIModelerNode } from '@idl/types/envi/modeler';
44
import {
55
LAYOUT_BASE_X,
66
LAYOUT_BASE_Y,
7+
LAYOUT_COMMENT_Y_OFFSET,
78
} from './create-envi-modeler-workflow.interface';
89
import { InjectAggregatorNodes } from './helpers/add-aggregator-nodes';
910
import { BuildIdMap } from './helpers/build-id-map';
@@ -44,6 +45,23 @@ export function CreateENVIModelerWorkflow(
4445
return BuildNodeJSON(node, modelName, location, registry);
4546
});
4647

48+
// Synthesize comment nodes from node.comment properties
49+
let commentCounter = 0;
50+
for (const node of injected.nodes) {
51+
if (node.comment) {
52+
const rawLocation = layout.get(node.id);
53+
const parentX = rawLocation ? rawLocation[0] : LAYOUT_BASE_X;
54+
const parentY = rawLocation ? rawLocation[1] : LAYOUT_BASE_Y;
55+
commentCounter++;
56+
modelNodes.push({
57+
display_name: node.comment,
58+
location: [parentX, parentY + LAYOUT_COMMENT_Y_OFFSET],
59+
name: `comment_${commentCounter}`,
60+
type: 'comment',
61+
});
62+
}
63+
}
64+
4765
// Build edges array
4866
const modelEdges = injected.edges.map((edge) => ({
4967
from_node: idMap.get(edge.from) ?? edge.from,

0 commit comments

Comments
 (0)