Skip to content
Merged
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
58 changes: 25 additions & 33 deletions apps/sim/enrichments/company-info/company-info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,63 +3,55 @@ import { Building2 } from 'lucide-react'
import { normalizeDomain, str, toolProvider } from '@/enrichments/providers'
import type { EnrichmentConfig } from '@/enrichments/types'

/** Returns the value when it's a finite number, else `undefined`. */
function num(value: unknown): number | undefined {
return typeof value === 'number' && Number.isFinite(value) ? value : undefined
}

/**
* Company Info enrichment. Looks up firmographics for a company domain, trying
* People Data Labs first (richest record, incl. employee count) then Hunter as
* a fallback.
* Company Info enrichment. Looks up a company by domain, trying Hunter first
* (free) then People Data Labs as a fallback. Outputs are limited to the fields
* both providers reliably return — employee count and description — so the
* result stays consistent regardless of which provider fills the cell.
* `employeeCount` is a string so Hunter's range bucket (e.g. `"11-50"`) and
* PDL's exact count map onto the same column.
*/
export const companyInfoEnrichment: EnrichmentConfig = {
id: 'company-info',
name: 'Company Info',
description:
"Look up a company's industry, size, founding year, and description from its domain.",
description: "Look up a company's size and description from its domain.",
icon: Building2,
inputs: [{ id: 'domain', name: 'Company domain', type: 'string', required: true }],
outputs: [
{ id: 'industry', name: 'industry', type: 'string' },
{ id: 'employeeCount', name: 'employee count', type: 'number' },
{ id: 'foundedYear', name: 'founded year', type: 'number' },
{ id: 'employeeCount', name: 'employee count', type: 'string' },
Comment thread
greptile-apps[bot] marked this conversation as resolved.
{ id: 'description', name: 'description', type: 'string' },
],
providers: [
toolProvider({
id: 'pdl',
label: 'People Data Labs',
toolId: 'pdl_company_enrich',
id: 'hunter',
label: 'Hunter',
toolId: 'hunter_companies_find',
buildParams: (inputs) => {
const website = normalizeDomain(inputs.domain)
if (!website) return null
return { website }
const domain = normalizeDomain(inputs.domain)
if (!domain) return null
return { domain }
},
mapOutput: (output) => {
const company = output.company as Record<string, unknown> | undefined
return filterUndefined({
industry: str(company?.industry) || undefined,
employeeCount: num(company?.employee_count),
foundedYear: num(company?.founded),
description: str(company?.summary) || undefined,
employeeCount: str(output.size) || undefined,
description: str(output.description) || undefined,
Comment thread
TheodoreSpeaks marked this conversation as resolved.
})
},
}),
Comment on lines 24 to +40
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Hunter partial-hit silently blocks PDL employee count

The cascade runner (run.ts:80) stops at the first provider whose mapOutput returns any non-empty field. If Hunter finds a company record but its response has no size field, Hunter still wins (because industry, foundedYear, or description satisfies hasResult), PDL is never attempted, and employeeCount stays blank — the same symptom the PR set out to fix, just narrowed to Hunter-known companies where size is absent. In that scenario the reorder actively regresses coverage relative to the previous PDL-first order.

toolProvider({
id: 'hunter',
label: 'Hunter',
toolId: 'hunter_companies_find',
id: 'pdl',
label: 'People Data Labs',
toolId: 'pdl_company_enrich',
buildParams: (inputs) => {
const domain = normalizeDomain(inputs.domain)
if (!domain) return null
return { domain }
const website = normalizeDomain(inputs.domain)
if (!website) return null
return { website }
},
mapOutput: (output) => {
const company = output.company as Record<string, unknown> | undefined
return filterUndefined({
industry: str(output.industry) || undefined,
foundedYear: num(output.founded_year),
description: str(output.description) || undefined,
employeeCount: str(company?.employee_count) || undefined,
description: str(company?.summary) || undefined,
})
},
}),
Expand Down
Loading