Skip to content

Commit f2dc7f7

Browse files
fix(enrichment): keep cascade detail sticky on upsert; mark unattempted providers not_run on abort
1 parent 9134d99 commit f2dc7f7

3 files changed

Lines changed: 39 additions & 19 deletions

File tree

apps/sim/enrichments/run.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,21 @@ describe('runEnrichment cascade detail', () => {
125125
expect(mockExecuteTool).not.toHaveBeenCalled()
126126
})
127127

128+
it('marks unattempted providers not_run when the signal is already aborted', async () => {
129+
const controller = new AbortController()
130+
controller.abort()
131+
const outcome = await runEnrichment(
132+
config([prov('a'), prov('b')]),
133+
{},
134+
{
135+
...ctx,
136+
signal: controller.signal,
137+
}
138+
)
139+
expect(mockExecuteTool).not.toHaveBeenCalled()
140+
expect(outcome.detail.providers.map((p) => p.status)).toEqual(['not_run', 'not_run'])
141+
})
142+
128143
it('does not error when some providers no-match and only some error', async () => {
129144
mockExecuteTool.mockImplementation((toolId: string) => {
130145
if (toolId === 'tool_a') return { success: false, output: { status: 500 } }

apps/sim/enrichments/run.ts

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ export async function runEnrichment(
8383
let errorCount = 0
8484
let lastError: string | null = null
8585
let matchedProvider: string | null = null
86-
let matchedIndex = -1
8786
let winner: { result: Record<string, unknown>; label: string } | null = null
8887
const providers: EnrichmentProviderOutcome[] = []
8988
const startedAt = Date.now()
@@ -147,7 +146,6 @@ export async function runEnrichment(
147146
error: null,
148147
})
149148
matchedProvider = provider.id
150-
matchedIndex = i
151149
winner = { result, label: provider.label }
152150
logger.info('Enrichment hit', { enrichmentId: enrichment.id, provider: provider.id })
153151
break
@@ -182,21 +180,21 @@ export async function runEnrichment(
182180
}
183181
}
184182

185-
// The cascade short-circuits on a match — record the providers it never
186-
// reached so the panel shows the full configured cascade.
187-
if (matchedIndex >= 0) {
188-
for (let i = matchedIndex + 1; i < enrichment.providers.length; i++) {
189-
const provider = enrichment.providers[i]
190-
providers.push({
191-
id: provider.id,
192-
label: provider.label,
193-
toolId: provider.toolId,
194-
status: 'not_run',
195-
cost: 0,
196-
durationMs: 0,
197-
error: null,
198-
})
199-
}
183+
// Any provider not represented yet never ran — the cascade short-circuited on
184+
// a match or aborted mid-run. Record them as `not_run` (in registry order) so
185+
// the panel always shows the full configured cascade.
186+
const seen = new Set(providers.map((p) => p.id))
187+
for (const provider of enrichment.providers) {
188+
if (seen.has(provider.id)) continue
189+
providers.push({
190+
id: provider.id,
191+
label: provider.label,
192+
toolId: provider.toolId,
193+
status: 'not_run',
194+
cost: 0,
195+
durationMs: 0,
196+
error: null,
197+
})
200198
}
201199

202200
const completedAt = Date.now()

apps/sim/lib/table/rows/executions.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,11 @@ export async function writeExecutionsPatch(
276276
runningBlockIds: insertValues.runningBlockIds,
277277
blockErrors: insertValues.blockErrors,
278278
cancelledAt: insertValues.cancelledAt,
279-
enrichmentDetails: insertValues.enrichmentDetails,
279+
// Sticky: preserve a prior cascade breakdown when this write omits
280+
// it (e.g. the running pickup stamp) so only an explicit detail
281+
// overwrites it. Re-runs delete the row first, so this never serves
282+
// stale detail across runs.
283+
enrichmentDetails: sql`coalesce(excluded.enrichment_details, ${tableRowExecutions.enrichmentDetails})`,
280284
updatedAt: insertValues.updatedAt,
281285
},
282286
where: and(
@@ -311,7 +315,10 @@ export async function writeExecutionsPatch(
311315
runningBlockIds: insertValues.runningBlockIds,
312316
blockErrors: insertValues.blockErrors,
313317
cancelledAt: insertValues.cancelledAt,
314-
enrichmentDetails: insertValues.enrichmentDetails,
318+
// Sticky: preserve a prior cascade breakdown when this write omits it
319+
// (e.g. the running pickup stamp) so only an explicit detail overwrites
320+
// it. Re-runs delete the row first, so this never serves stale detail.
321+
enrichmentDetails: sql`coalesce(excluded.enrichment_details, ${tableRowExecutions.enrichmentDetails})`,
315322
updatedAt: insertValues.updatedAt,
316323
},
317324
})

0 commit comments

Comments
 (0)