Skip to content

Commit d168b4b

Browse files
NgoHarrisonHarrison Ngo
andauthored
[APO-2121] Codegen workflow trigger id for scenarios (#3067)
* [APO-2121] Codegen workflow trigger id for scenarios * update to generate trigger class instead of id * npm run lint --------- Co-authored-by: Harrison Ngo <[email protected]>
1 parent dd30817 commit d168b4b

File tree

4 files changed

+151
-3
lines changed

4 files changed

+151
-3
lines changed

ee/codegen/src/__test__/__snapshots__/workflow-sandbox.test.ts.snap

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,31 @@
11
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
22

3+
exports[`Workflow Sandbox > write > should generate DatasetRow with trigger when workflow_trigger_id is provided 1`] = `
4+
"from vellum.workflows.inputs import DatasetRow
5+
from vellum.workflows.sandbox import WorkflowSandboxRunner
6+
7+
from .inputs import Inputs
8+
from .triggers.scheduled import ScheduleTrigger
9+
from .workflow import TestWorkflow
10+
11+
dataset = [
12+
DatasetRow(
13+
label="Scenario with Trigger ID",
14+
inputs=Inputs(test_input="test-value"),
15+
trigger=ScheduleTrigger,
16+
),
17+
DatasetRow(
18+
label="Scenario without Trigger ID", inputs=Inputs(test_input="test-value-2")
19+
),
20+
]
21+
22+
runner = WorkflowSandboxRunner(workflow=TestWorkflow(), dataset=dataset)
23+
24+
if __name__ == "__main__":
25+
runner.run()
26+
"
27+
`;
28+
329
exports[`Workflow Sandbox > write > should generate DatasetRow without inputs parameter when dataset row has label but no inputs 1`] = `
430
"from vellum.workflows.inputs import DatasetRow
531
from vellum.workflows.sandbox import WorkflowSandboxRunner

ee/codegen/src/__test__/workflow-sandbox.test.ts

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ import { workflowContextFactory } from "./helpers";
66
import { inputVariableContextFactory } from "./helpers/input-variable-context-factory";
77

88
import * as codegen from "src/codegen";
9-
import { WorkflowSandboxDatasetRow } from "src/types/vellum";
9+
import {
10+
WorkflowSandboxDatasetRow,
11+
WorkflowTrigger,
12+
WorkflowTriggerType,
13+
} from "src/types/vellum";
1014

1115
describe("Workflow Sandbox", () => {
1216
const generateSandboxFile = async (
@@ -172,5 +176,74 @@ describe("Workflow Sandbox", () => {
172176
expect(result).toContain('DatasetRow(label="Test Label Only")');
173177
expect(result).not.toContain("inputs=");
174178
});
179+
180+
it("should generate DatasetRow with trigger when workflow_trigger_id is provided", async () => {
181+
const writer = new Writer();
182+
const triggerId = "550e8400-e29b-41d4-a716-446655440000";
183+
const triggers: WorkflowTrigger[] = [
184+
{
185+
id: triggerId,
186+
type: WorkflowTriggerType.SCHEDULED,
187+
attributes: [],
188+
cron: "* * * * *",
189+
timezone: "UTC",
190+
},
191+
];
192+
const uniqueWorkflowContext = workflowContextFactory({ triggers });
193+
const inputVariable: VellumVariable = {
194+
id: "1",
195+
key: "test_input",
196+
type: "STRING",
197+
};
198+
199+
uniqueWorkflowContext.addInputVariableContext(
200+
inputVariableContextFactory({
201+
inputVariableData: inputVariable,
202+
workflowContext: uniqueWorkflowContext,
203+
})
204+
);
205+
206+
const sandboxInputs: WorkflowSandboxDatasetRow[] = [
207+
{
208+
label: "Scenario with Trigger ID",
209+
inputs: [
210+
{
211+
name: inputVariable.key,
212+
type: "STRING",
213+
value: "test-value",
214+
},
215+
],
216+
workflow_trigger_id: triggerId,
217+
},
218+
{
219+
label: "Scenario without Trigger ID",
220+
inputs: [
221+
{
222+
name: inputVariable.key,
223+
type: "STRING",
224+
value: "test-value-2",
225+
},
226+
],
227+
},
228+
];
229+
230+
const sandbox = codegen.workflowSandboxFile({
231+
workflowContext: uniqueWorkflowContext,
232+
sandboxInputs,
233+
});
234+
235+
sandbox.write(writer);
236+
const result = await writer.toStringFormatted();
237+
238+
expect(result).toMatchSnapshot();
239+
expect(result).toContain("trigger=ScheduleTrigger");
240+
const lines = result.split("\n");
241+
const secondDatasetRowIndex = lines.findIndex((line) =>
242+
line.includes('label="Scenario without Trigger ID"')
243+
);
244+
expect(secondDatasetRowIndex).toBeGreaterThan(-1);
245+
const secondDatasetRowLine = lines[secondDatasetRowIndex];
246+
expect(secondDatasetRowLine).not.toContain("trigger=");
247+
});
175248
});
176249
});

ee/codegen/src/generators/workflow-sandbox-file.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
} from "src/types/vellum";
1111
import { removeEscapeCharacters } from "src/utils/casing";
1212
import { getGeneratedInputsModulePath } from "src/utils/paths";
13+
import { getTriggerClassInfo } from "src/utils/triggers";
1314

1415
export declare namespace WorkflowSandboxFile {
1516
interface Args extends BasePersistedFile.Args {
@@ -98,6 +99,9 @@ if __name__ == "__main__":
9899
const label: string = Array.isArray(row)
99100
? `Example ${index + 1}`
100101
: row.label;
102+
const workflowTriggerId: string | undefined = Array.isArray(row)
103+
? undefined
104+
: row.workflow_trigger_id;
101105

102106
const hasInputs = inputs.length > 0;
103107
const arguments_: python.MethodArgument[] = [
@@ -147,6 +151,19 @@ if __name__ == "__main__":
147151
);
148152
}
149153

154+
if (!isNil(workflowTriggerId)) {
155+
const triggerReference = this.getTriggerReference(workflowTriggerId);
156+
157+
if (triggerReference) {
158+
arguments_.push(
159+
python.methodArgument({
160+
name: "trigger",
161+
value: triggerReference,
162+
})
163+
);
164+
}
165+
}
166+
150167
return python.instantiateClass({
151168
classReference: python.reference({
152169
name: "DatasetRow",
@@ -155,4 +172,32 @@ if __name__ == "__main__":
155172
arguments_,
156173
});
157174
}
175+
176+
private getTriggerReference(
177+
workflowTriggerId: string
178+
): python.Reference | undefined {
179+
const triggerContext =
180+
this.workflowContext.findTriggerContext(workflowTriggerId);
181+
182+
if (triggerContext) {
183+
return python.reference({
184+
name: triggerContext.triggerClassName,
185+
modulePath: triggerContext.triggerModulePath,
186+
});
187+
}
188+
189+
const triggers = this.workflowContext.triggers ?? [];
190+
const trigger = triggers.find((t) => t.id === workflowTriggerId);
191+
192+
if (!trigger) {
193+
return undefined;
194+
}
195+
196+
const triggerClassInfo = getTriggerClassInfo(trigger, this.workflowContext);
197+
198+
return python.reference({
199+
name: triggerClassInfo.className,
200+
modulePath: triggerClassInfo.modulePath,
201+
});
202+
}
158203
}

ee/codegen/src/types/vellum.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -888,8 +888,12 @@ type WorkflowSandboxInput =
888888
export type WorkflowSandboxInputs = WorkflowSandboxInput[];
889889
export type WorkflowSandboxDatasetRow =
890890
| WorkflowSandboxInputs
891-
| { label: string; inputs: WorkflowSandboxInputs }
892-
| { label: string };
891+
| {
892+
label: string;
893+
inputs: WorkflowSandboxInputs;
894+
workflow_trigger_id?: string;
895+
}
896+
| { label: string; workflow_trigger_id?: string };
893897

894898
export interface UnaryWorkflowExpression {
895899
type: "UNARY_EXPRESSION";

0 commit comments

Comments
 (0)