Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2158,7 +2158,7 @@

await new LoadRelatedRecordStepExecutor(context).execute();

const firstRow = JSON.parse(selectRecordPrompt(invoke).match(/\[0\] (\{[^\n]*\})/)![1]);

Check warning on line 2161 in packages/workflow-executor/test/executors/load-related-record-step-executor.test.ts

View workflow job for this annotation

GitHub Actions / Linting & Testing (workflow-executor)

Forbidden non-null assertion
expect(Object.keys(firstRow)).toHaveLength(6);
});

Expand Down Expand Up @@ -3603,6 +3603,71 @@
});
});

describe('backward compatibility (PRD-552): legacy and deterministic coexist', () => {
it('runs the AI path for a legacy step and the deterministic path for a configured step', async () => {
// Legacy prompt-only step → AI selects the relation.
const legacy = makeMockModel({ relationName: 'Orders', reasoning: 'r' });
await new LoadRelatedRecordStepExecutor(
makeContext({
model: legacy.model,
stepDefinition: makeStep({ executionType: StepExecutionMode.FullyAutomated }),
}),
).execute();

expect(legacy.bindTools).toHaveBeenCalled();

// Deterministic step (source + relation pinned) → no relation AI call.
const ordersSchema = makeCollectionSchema({
collectionName: 'orders',
collectionDisplayName: 'Orders',
fields: [
{
fieldName: 'customer',
displayName: 'Customer',
isRelationship: true,
relationType: 'BelongsTo',
relatedCollectionName: 'customers',
},
],
});
const deterministic = makeMockModel();
const runStore = makeMockRunStore({
getStepExecutions: jest.fn().mockResolvedValue([
{
type: 'load-related-record',
stepIndex: 1,
executionResult: {
relation: { name: 'order', displayName: 'Order' },
record: { collectionName: 'orders', recordId: [99], stepIndex: 1 },
},
selectedRecordRef: makeRecordRef(),
},
]),
});
const result = await new LoadRelatedRecordStepExecutor(
makeContext({
model: deterministic.model,
runStore,
agentPort: makeMockAgentPort([
makeRelatedRecordData({ collectionName: 'customers', recordId: [7], values: {} }),
]),
workflowPort: makeMockWorkflowPort({
customers: makeCollectionSchema(),
orders: ordersSchema,
}),
previousSteps: [makeLoadRelatedPreviousStep(1)],
stepDefinition: makeStep({
executionType: StepExecutionMode.FullyAutomated,
preRecordedArgs: { selectedRecordStepId: 'load-1', relationName: 'customer' },

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

non-blocking: selectedRecordStepId is not a recognized preRecordedArgs key (the schema/executor only accept selectedRecordStepIndex / selectedRecordIndex / relationName), so the source-record pinning this test sets up is silently ignored — selection falls back to all available records. The test passes only because relationName: 'customer' still pins the relation; it doesn't validate the step-index pinning its fixture implies. Use selectedRecordStepIndex: 1 (as in the existing deterministic test) to actually exercise it.

}),
}),
).execute();

expect(result.stepOutcome.status).toBe('success');
expect(deterministic.bindTools).not.toHaveBeenCalled();
});
});

describe('record pool after revision', () => {
it('re-executes a revised load step from the base record, not from the dead branch record', async () => {
// Given: the run loaded an owner before the user revised the "Load store" step. The
Expand Down
Loading