Skip to content

Commit 686ff39

Browse files
Update step context structure to exclude stepName field (#1695)
<!-- Ensure the title clearly reflects what was changed. Provide a clear and concise description of the changes made. The PR should only contain the changes related to the issue, and no other unrelated changes. --> Part of OPS-3137.
1 parent cb38688 commit 686ff39

File tree

7 files changed

+92
-57
lines changed

7 files changed

+92
-57
lines changed

packages/react-ui/src/app/features/ai/lib/enrich-context.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,9 @@ export const createAdditionalContext = (
2323
flowVersionId: flowVersion.id,
2424
runId,
2525
currentStepId: stepData?.id ?? '',
26-
currentStepName: stepData?.name ?? '',
2726
steps: [
2827
{
2928
id: stepData?.id ?? '',
30-
stepName: stepData?.name ?? '',
3129
variables: variables.length > 0 ? variables : undefined,
3230
},
3331
],

packages/server/api/src/app/ai/chat/context-enrichment.service.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,6 @@ async function enrichSteps(
181181
} catch (error) {
182182
return {
183183
id: step.id,
184-
stepName: step.stepName,
185184
variables: step.variables?.map((variable) => ({
186185
name: variable.name,
187186
value: String(error),
@@ -202,7 +201,6 @@ async function enrichStep(
202201
if (!step.variables || step.variables.length === 0) {
203202
return {
204203
id: step.id,
205-
stepName: step.stepName,
206204
variables: step.variables,
207205
};
208206
}
@@ -215,7 +213,6 @@ async function enrichStep(
215213

216214
return {
217215
id: step.id,
218-
stepName: step.stepName,
219216
variables: resolvedVariables,
220217
};
221218
}
@@ -253,11 +250,20 @@ async function resolveVariable(
253250
flowData: FlowData,
254251
projectId: string,
255252
): Promise<{ name: string; value: unknown }> {
253+
const workflowStep = flowHelper.getStepById(flowData.flow.version, step.id);
254+
255+
if (!workflowStep) {
256+
return {
257+
name: variable.name,
258+
value: 'Failed to resolve variable: Step not found in the workflow.',
259+
};
260+
}
261+
256262
const { result } = await engineRunner.executeVariable(flowData.engineToken, {
257263
variableExpression: variable.value,
258264
flowVersion: flowData.flow.version,
259265
projectId,
260-
stepName: step.stepName,
266+
stepName: workflowStep.name,
261267
stepTestOutputs: flowData.stepTestOutputs,
262268
});
263269

packages/server/api/src/app/ai/chat/prompts.service.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,10 +139,6 @@ export const buildUIContextSection = async (
139139
contextParts.push(`step id ${flowContext.currentStepId}`);
140140
}
141141

142-
if (flowContext.currentStepName) {
143-
contextParts.push(`step name "${flowContext.currentStepName}"`);
144-
}
145-
146142
if (contextParts.length === 0) {
147143
return '';
148144
}

packages/server/api/test/unit/ai/context-enrichment.service.test.ts

Lines changed: 67 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { jest } from '@jest/globals';
22
import {
3+
Action,
34
ChatFlowContext,
45
EngineResponseStatus,
56
flowHelper,
@@ -59,6 +60,7 @@ jest.mock('server-worker', () => ({
5960
jest.mock('@openops/shared', () => ({
6061
flowHelper: {
6162
getAllStepIds: jest.fn(),
63+
getStepById: jest.fn(),
6264
},
6365
groupStepOutputsById: jest.fn(),
6466
}));
@@ -99,6 +101,12 @@ describe('ContextEnrichmentService', () => {
99101
mockEngineToken,
100102
);
101103
mockFlowHelper.getAllStepIds.mockReturnValue(['step-1']);
104+
mockFlowHelper.getStepById.mockImplementation((_version, stepId) => {
105+
if (stepId === 'step-1') {
106+
return { name: 'step_1' } as Action;
107+
}
108+
return { name: stepId } as Action;
109+
});
102110
mockFlowStepTestOutputService.listEncrypted.mockResolvedValue([]);
103111
mockGroupStepOutputsById.mockReturnValue({});
104112

@@ -111,7 +119,6 @@ describe('ContextEnrichmentService', () => {
111119
steps: [
112120
{
113121
id: 'step-1',
114-
stepName: 'step_1',
115122
variables: [
116123
{
117124
name: 'variable1',
@@ -159,7 +166,6 @@ describe('ContextEnrichmentService', () => {
159166
steps: [
160167
{
161168
id: 'step-1',
162-
stepName: 'step_1',
163169
variables: [
164170
{
165171
name: 'variable1',
@@ -196,7 +202,6 @@ describe('ContextEnrichmentService', () => {
196202
steps: [
197203
{
198204
id: 'step-1',
199-
stepName: 'step_1',
200205
},
201206
],
202207
};
@@ -219,7 +224,6 @@ describe('ContextEnrichmentService', () => {
219224
steps: [
220225
{
221226
id: 'step-1',
222-
stepName: 'step_1',
223227
variables: undefined,
224228
},
225229
],
@@ -241,7 +245,6 @@ describe('ContextEnrichmentService', () => {
241245
steps: [
242246
{
243247
id: 'step-1',
244-
stepName: 'step_1',
245248
variables: [
246249
{
247250
name: 'variable1',
@@ -280,7 +283,6 @@ describe('ContextEnrichmentService', () => {
280283
steps: [
281284
{
282285
id: 'step-1',
283-
stepName: 'step_1',
284286
variables: [
285287
{
286288
name: 'variable1',
@@ -292,6 +294,63 @@ describe('ContextEnrichmentService', () => {
292294
});
293295
});
294296

297+
it("should set an error value when step isn't found (getStepById returns undefined)", async () => {
298+
const mockFlow = {
299+
version: {
300+
trigger: { id: 'trigger-id' },
301+
},
302+
} as PopulatedFlow;
303+
304+
const mockInputContext = {
305+
flowId: mockFlowId,
306+
flowVersionId: mockFlowVersionId,
307+
steps: [
308+
{
309+
id: 'step-unknown',
310+
variables: [
311+
{
312+
name: 'variable1',
313+
value: '{{some.expression}}',
314+
},
315+
],
316+
},
317+
],
318+
};
319+
320+
mockFlowService.getOnePopulatedOrThrow.mockResolvedValue(mockFlow);
321+
mockAccessTokenManager.generateEngineToken.mockResolvedValue(
322+
mockEngineToken,
323+
);
324+
mockFlowHelper.getAllStepIds.mockReturnValue(['step-unknown']);
325+
mockFlowHelper.getStepById.mockReturnValue(undefined);
326+
mockFlowStepTestOutputService.listEncrypted.mockResolvedValue([]);
327+
mockGroupStepOutputsById.mockReturnValue({});
328+
329+
const result = await enrichContext(mockInputContext, mockProjectId);
330+
331+
expect(result).toEqual({
332+
flowId: mockFlowId,
333+
flowVersionId: mockFlowVersionId,
334+
currentStepId: undefined,
335+
currentStepData: '',
336+
steps: [
337+
{
338+
id: 'step-unknown',
339+
variables: [
340+
{
341+
name: 'variable1',
342+
value:
343+
'Failed to resolve variable: Step not found in the workflow.',
344+
},
345+
],
346+
},
347+
],
348+
});
349+
350+
// Ensure engine is not called when step cannot be found
351+
expect(mockEngineRunner.executeVariable).not.toHaveBeenCalled();
352+
});
353+
295354
it('should handle engine runner exceptions', async () => {
296355
const mockFlow = {
297356
version: {
@@ -305,7 +364,6 @@ describe('ContextEnrichmentService', () => {
305364
steps: [
306365
{
307366
id: 'step-1',
308-
stepName: 'step_1',
309367
variables: [
310368
{
311369
name: 'variable1',
@@ -338,11 +396,11 @@ describe('ContextEnrichmentService', () => {
338396
steps: [
339397
{
340398
id: 'step-1',
341-
stepName: 'step_1',
342399
variables: [
343400
{
344401
name: 'variable1',
345-
value: 'Error resolving variable: Engine error',
402+
value:
403+
'Failed to resolve variable: Step not found in the workflow.',
346404
},
347405
],
348406
},

packages/server/api/test/unit/ai/prompts.service.test.ts

Lines changed: 4 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -257,15 +257,13 @@ describe('getSystemPrompt', () => {
257257
steps: [
258258
{
259259
id: 'step1',
260-
stepName: 'step1',
261260
variables: [
262261
{ name: 'var1', value: 'value1' },
263262
{ name: 'var2', value: 'value2' },
264263
],
265264
},
266265
{
267266
id: 'step2',
268-
stepName: 'step2',
269267
variables: [{ name: 'var3', value: 'value3' }],
270268
},
271269
],
@@ -300,10 +298,7 @@ describe('getSystemPrompt', () => {
300298
const enrichedContext = {
301299
flowId: 'test-flow-id',
302300
flowVersionId: 'test-flow-version-id',
303-
steps: [
304-
{ id: 'step1', stepName: 'step1' },
305-
{ id: 'step2', stepName: 'step2' },
306-
],
301+
steps: [{ id: 'step1' }, { id: 'step2' }],
307302
};
308303

309304
const result = await getBlockSystemPrompt(
@@ -358,16 +353,13 @@ describe('getSystemPrompt', () => {
358353
steps: [
359354
{
360355
id: 'step1',
361-
stepName: 'step1',
362356
variables: [{ name: 'var1', value: 'value1' }],
363357
},
364358
{
365359
id: 'step2',
366-
stepName: 'step2',
367360
},
368361
{
369362
id: 'step3',
370-
stepName: 'step3',
371363
variables: [{ name: 'var2', value: 'value2' }],
372364
},
373365
],
@@ -438,7 +430,6 @@ describe('buildUIContextSection', () => {
438430
flowVersionId: 'version-456',
439431
runId: 'run-789',
440432
currentStepId: 'step-abc',
441-
currentStepName: 'Data Processing Step',
442433
};
443434

444435
const EXPECTED_STRINGS = {
@@ -544,26 +535,6 @@ describe('buildUIContextSection', () => {
544535
},
545536
`flow ${TEST_IDS.flowId} with flowVersion ${TEST_IDS.flowVersionId} with step id ${TEST_IDS.currentStepId}`,
546537
],
547-
[
548-
'basic fields with currentStepName',
549-
{
550-
flowId: TEST_IDS.flowId,
551-
flowVersionId: TEST_IDS.flowVersionId,
552-
currentStepName: TEST_IDS.currentStepName,
553-
},
554-
`flow ${TEST_IDS.flowId} with flowVersion ${TEST_IDS.flowVersionId} with step name "${TEST_IDS.currentStepName}"`,
555-
],
556-
[
557-
'all fields including step info',
558-
{
559-
flowId: TEST_IDS.flowId,
560-
flowVersionId: TEST_IDS.flowVersionId,
561-
runId: TEST_IDS.runId,
562-
currentStepId: TEST_IDS.currentStepId,
563-
currentStepName: TEST_IDS.currentStepName,
564-
},
565-
`flow ${TEST_IDS.flowId} with flowVersion ${TEST_IDS.flowVersionId} with run ${TEST_IDS.runId} with step id ${TEST_IDS.currentStepId} with step name "${TEST_IDS.currentStepName}"`,
566-
],
567538
])(
568539
'should build context with %s',
569540
async (
@@ -581,15 +552,15 @@ describe('buildUIContextSection', () => {
581552
describe('handles edge cases', () => {
582553
it.each([
583554
[
584-
'mixed empty and valid context fields',
555+
'mixed empty and valid context fields (step name ignored)',
585556
{
586557
flowId: TEST_IDS.flowId,
587558
flowVersionId: '',
588559
runId: TEST_IDS.runId,
589560
currentStepId: '',
590-
currentStepName: TEST_IDS.currentStepName,
591561
},
592-
`flow ${TEST_IDS.flowId} with run ${TEST_IDS.runId} with step name "${TEST_IDS.currentStepName}"`,
562+
// step name is ignored; empty flowVersion/currentStepId removed
563+
`flow ${TEST_IDS.flowId} with run ${TEST_IDS.runId}`,
593564
],
594565
[
595566
'undefined optional fields gracefully',
@@ -598,7 +569,6 @@ describe('buildUIContextSection', () => {
598569
flowVersionId: TEST_IDS.flowVersionId,
599570
runId: undefined,
600571
currentStepId: undefined,
601-
currentStepName: undefined,
602572
},
603573
`flow ${TEST_IDS.flowId} with flowVersion ${TEST_IDS.flowVersionId}`,
604574
],
@@ -610,12 +580,10 @@ describe('buildUIContextSection', () => {
610580
steps: [
611581
{
612582
id: 'step1',
613-
stepName: 'Step One',
614583
variables: [{ name: 'var1', value: 'value1' }],
615584
},
616585
{
617586
id: 'step2',
618-
stepName: 'Step Two',
619587
},
620588
],
621589
},

packages/shared/src/lib/ai/chat/index.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ export type VariableContext = Static<typeof VariableContext>;
4343

4444
export const StepContext = Type.Object({
4545
id: Type.String(),
46-
stepName: Type.String(),
4746
variables: Type.Optional(Type.Array(VariableContext)),
4847
});
4948
export type StepContext = Static<typeof StepContext>;
@@ -53,7 +52,6 @@ export const ChatFlowContext = Type.Object({
5352
flowVersionId: Type.String(),
5453
runId: Type.Optional(Type.String()),
5554
currentStepId: Type.Optional(Type.String()),
56-
currentStepName: Type.Optional(Type.String()),
5755
currentStepData: Type.Optional(Type.Any()),
5856
steps: Type.Array(StepContext),
5957
});

packages/shared/src/lib/flows/flow-helper.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,16 @@ function getStep(
336336
);
337337
}
338338

339+
function getStepById(
340+
flowVersion: FlowVersion,
341+
stepId: string,
342+
): Action | TriggerWithOptionalId | undefined {
343+
if (flowVersion.trigger.id === stepId) {
344+
return flowVersion.trigger;
345+
}
346+
return getAllSteps(flowVersion.trigger).find((step) => step.id === stepId);
347+
}
348+
339349
function getStepWithIndex(
340350
flowVersion: FlowVersion,
341351
stepName: string,
@@ -1314,6 +1324,7 @@ export const flowHelper = {
13141324
},
13151325

13161326
getStep,
1327+
getStepById,
13171328
getStepWithIndex,
13181329
isAction,
13191330
isTrigger,

0 commit comments

Comments
 (0)