feat: minor improvements to diffbot, predictleads, and proxycurl

old-agentic
Travis Fischer 2024-06-09 19:18:06 -05:00
rodzic 5ec06aaf22
commit 513a2aa294
5 zmienionych plików z 86 dodań i 42 usunięć

Wyświetl plik

@ -72,6 +72,7 @@
"scripts": { "scripts": {
"preinstall": "npx only-allow pnpm", "preinstall": "npx only-allow pnpm",
"build": "tsup", "build": "tsup",
"dev": "tsup --watch",
"clean": "del dist", "clean": "del dist",
"prebuild": "run-s clean", "prebuild": "run-s clean",
"predev": "run-s clean", "predev": "run-s clean",

Wyświetl plik

@ -1,3 +1,4 @@
import type { Simplify } from 'type-fest'
import defaultKy, { type KyInstance } from 'ky' import defaultKy, { type KyInstance } from 'ky'
import pThrottle from 'p-throttle' import pThrottle from 'p-throttle'
import { z } from 'zod' import { z } from 'zod'
@ -657,6 +658,8 @@ export namespace diffbot {
'interests' 'interests'
) )
} }
export type PrunedEntity = Simplify<ReturnType<typeof pruneEntity>>
} }
/** /**
@ -747,7 +750,9 @@ export class DiffbotClient extends AIFunctionsProvider {
threshold: true threshold: true
}) })
}) })
async enhanceEntity(opts: diffbot.EnhanceEntityOptions) { async enhanceEntity(
opts: diffbot.EnhanceEntityOptions
): Promise<diffbot.PrunedEntity[]> {
const res = await this.kyKnowledgeGraph const res = await this.kyKnowledgeGraph
.get('kg/v3/enhance', { .get('kg/v3/enhance', {
searchParams: sanitizeSearchParams({ searchParams: sanitizeSearchParams({

Wyświetl plik

@ -532,7 +532,7 @@ export class PredictLeadsClient extends AIFunctionsProvider {
'Returns basic information about a company given its `domain` like location, name, stock ticker, description, etc.', 'Returns basic information about a company given its `domain` like location, name, stock ticker, description, etc.',
inputSchema: predictleads.CompanyParamsSchema inputSchema: predictleads.CompanyParamsSchema
}) })
async company(domainOrOpts: string | predictleads.CompanyParams) { async getCompany(domainOrOpts: string | predictleads.CompanyParams) {
const opts = const opts =
typeof domainOrOpts === 'string' ? { domain: domainOrOpts } : domainOrOpts typeof domainOrOpts === 'string' ? { domain: domainOrOpts } : domainOrOpts
const { domain } = opts const { domain } = opts

Wyświetl plik

@ -3,7 +3,7 @@ import pThrottle from 'p-throttle'
import { z } from 'zod' import { z } from 'zod'
import { aiFunction, AIFunctionsProvider } from '../fns.js' import { aiFunction, AIFunctionsProvider } from '../fns.js'
import { assert, getEnv, throttleKy } from '../utils.js' import { assert, getEnv, sanitizeSearchParams, throttleKy } from '../utils.js'
// All proxycurl types are auto-generated from their openapi spec // All proxycurl types are auto-generated from their openapi spec
export namespace proxycurl { export namespace proxycurl {
@ -25,35 +25,48 @@ export namespace proxycurl {
]) ])
export type CompanyType = z.infer<typeof CompanyTypeSchema> export type CompanyType = z.infer<typeof CompanyTypeSchema>
export const OptionalFieldSchema = z.enum(['exclude', 'include']).optional()
export type OptionalField = z.infer<typeof OptionalFieldSchema>
export const OptionalEnrichFieldSchema = z.enum(['skip', 'enrich']).optional()
export type OptionalEnrichField = z.infer<typeof OptionalEnrichFieldSchema>
export const UseCacheSchema = z.enum(['if-present', 'if-recent']).optional()
export type UseCache = z.infer<typeof UseCacheSchema>
export const FallbackToCacheSchema = z.enum(['on-error', 'never']).optional()
export type FallbackToCache = z.infer<typeof FallbackToCacheSchema>
export const CompanyProfileEndpointParamsQueryClassSchema = z.object({ export const CompanyProfileEndpointParamsQueryClassSchema = z.object({
acquisitions: z.string().optional(),
categories: z.string().optional(),
exit_data: z.string().optional(),
extra: z.string().optional(),
fallback_to_cache: z.string().optional(),
funding_data: z.string().optional(),
resolve_numeric_id: z.string().optional(),
url: z.string(), url: z.string(),
use_cache: z.string().optional() acquisitions: OptionalFieldSchema,
categories: OptionalFieldSchema,
exit_data: OptionalFieldSchema,
extra: OptionalFieldSchema,
funding_data: OptionalFieldSchema,
resolve_numeric_id: z.boolean().optional(),
fallback_to_cache: FallbackToCacheSchema,
use_cache: UseCacheSchema
}) })
export type CompanyProfileEndpointParamsQueryClass = z.infer< export type CompanyProfileEndpointParamsQueryClass = z.infer<
typeof CompanyProfileEndpointParamsQueryClassSchema typeof CompanyProfileEndpointParamsQueryClassSchema
> >
export const PersonProfileEndpointParamsQueryClassSchema = z.object({ export const PersonProfileEndpointParamsQueryClassSchema = z.object({
extra: z.string().optional(), // requires one of `facebook_profile_url`, `linkedin_profile_url`, or `twitter_profile_url`
facebook_profile_id: z.string().optional(),
facebook_profile_url: z.string().optional(), facebook_profile_url: z.string().optional(),
fallback_to_cache: z.string().optional(),
github_profile_id: z.string().optional(),
inferred_salary: z.string().optional(),
linkedin_profile_url: z.string().optional(), linkedin_profile_url: z.string().optional(),
personal_contact_number: z.string().optional(),
personal_email: z.string().optional(),
skills: z.string().optional(),
twitter_profile_id: z.string().optional(),
twitter_profile_url: z.string().optional(), twitter_profile_url: z.string().optional(),
use_cache: z.string().optional() facebook_profile_id: OptionalFieldSchema,
twitter_profile_id: OptionalFieldSchema,
extra: OptionalFieldSchema,
github_profile_id: OptionalFieldSchema,
inferred_salary: OptionalFieldSchema,
personal_contact_number: OptionalFieldSchema,
personal_email: OptionalFieldSchema,
skills: OptionalFieldSchema,
fallback_to_cache: FallbackToCacheSchema,
use_cache: UseCacheSchema
}) })
export type PersonProfileEndpointParamsQueryClass = z.infer< export type PersonProfileEndpointParamsQueryClass = z.infer<
typeof PersonProfileEndpointParamsQueryClassSchema typeof PersonProfileEndpointParamsQueryClassSchema
@ -63,12 +76,12 @@ export namespace proxycurl {
company_domain: z company_domain: z
.string() .string()
.describe('The domain URL of the company the person works at'), .describe('The domain URL of the company the person works at'),
enrich_profile: z.string().optional(),
first_name: z.string(), first_name: z.string(),
last_name: z.string().optional(), last_name: z.string().optional(),
location: z.string().optional(), location: z.string().optional(),
similarity_checks: z.string().optional(), similarity_checks: z.string().optional(),
title: z.string().optional() title: z.string().optional(),
enrich_profile: OptionalEnrichFieldSchema
}) })
export type PersonLookupEndpointParamsQueryClass = z.infer< export type PersonLookupEndpointParamsQueryClass = z.infer<
typeof PersonLookupEndpointParamsQueryClassSchema typeof PersonLookupEndpointParamsQueryClassSchema
@ -77,7 +90,7 @@ export namespace proxycurl {
export const RoleLookupEndpointParamsQueryClassSchema = z.object({ export const RoleLookupEndpointParamsQueryClassSchema = z.object({
company_name: z.string(), company_name: z.string(),
role: z.string(), role: z.string(),
enrich_profile: z.string().optional() enrich_profile: OptionalEnrichFieldSchema
}) })
export type RoleLookupEndpointParamsQueryClass = z.infer< export type RoleLookupEndpointParamsQueryClass = z.infer<
typeof RoleLookupEndpointParamsQueryClassSchema typeof RoleLookupEndpointParamsQueryClassSchema
@ -87,7 +100,7 @@ export namespace proxycurl {
company_domain: z.string().optional(), company_domain: z.string().optional(),
company_location: z.string().optional(), company_location: z.string().optional(),
company_name: z.string().optional(), company_name: z.string().optional(),
enrich_profile: z.string().optional() enrich_profile: OptionalEnrichFieldSchema
}) })
export type CompanyLookupEndpointParamsQueryClass = z.infer< export type CompanyLookupEndpointParamsQueryClass = z.infer<
typeof CompanyLookupEndpointParamsQueryClassSchema typeof CompanyLookupEndpointParamsQueryClassSchema
@ -95,7 +108,7 @@ export namespace proxycurl {
export const ReverseEmailLookupEndpointParamsQueryClassSchema = z.object({ export const ReverseEmailLookupEndpointParamsQueryClassSchema = z.object({
email: z.string(), email: z.string(),
enrich_profile: z.string().optional(), enrich_profile: OptionalEnrichFieldSchema,
lookup_depth: z.string().optional() lookup_depth: z.string().optional()
}) })
export type ReverseEmailLookupEndpointParamsQueryClass = z.infer< export type ReverseEmailLookupEndpointParamsQueryClass = z.infer<
@ -2068,7 +2081,12 @@ export class ProxycurlClient extends AIFunctionsProvider {
) { ) {
return this.ky return this.ky
.get('api/linkedin/company', { .get('api/linkedin/company', {
searchParams: { ...opts } searchParams: sanitizeSearchParams({
funding_data: 'include',
exit_data: 'include',
extra_data: 'include',
...opts
})
}) })
.json<proxycurl.ResultProfile>() .json<proxycurl.ResultProfile>()
} }
@ -2084,7 +2102,7 @@ export class ProxycurlClient extends AIFunctionsProvider {
) { ) {
return this.ky return this.ky
.get('api/v2/linkedin', { .get('api/v2/linkedin', {
searchParams: { ...opts } searchParams: sanitizeSearchParams(opts)
}) })
.json<proxycurl.PublicPerson>() .json<proxycurl.PublicPerson>()
} }
@ -2100,7 +2118,10 @@ export class ProxycurlClient extends AIFunctionsProvider {
) { ) {
return this.ky return this.ky
.get('api/linkedin/profile/resolve', { .get('api/linkedin/profile/resolve', {
searchParams: { ...opts } searchParams: sanitizeSearchParams({
enrich_profile: 'enrich',
...opts
})
}) })
.json<proxycurl.PublicPerson>() .json<proxycurl.PublicPerson>()
} }
@ -2116,7 +2137,10 @@ export class ProxycurlClient extends AIFunctionsProvider {
) { ) {
return this.ky return this.ky
.get('api/linkedin/profile/resolve/email', { .get('api/linkedin/profile/resolve/email', {
searchParams: { ...opts } searchParams: sanitizeSearchParams({
enrich_profile: 'enrich',
...opts
})
}) })
.json<proxycurl.ReverseEmailUrlEnrichResult>() .json<proxycurl.ReverseEmailUrlEnrichResult>()
} }
@ -2132,7 +2156,10 @@ export class ProxycurlClient extends AIFunctionsProvider {
) { ) {
return this.ky return this.ky
.get('api/find/company/role/', { .get('api/find/company/role/', {
searchParams: { ...opts } searchParams: sanitizeSearchParams({
enrich_profile: 'enrich',
...opts
})
}) })
.json<proxycurl.PublicPerson>() .json<proxycurl.PublicPerson>()
} }
@ -2148,7 +2175,10 @@ export class ProxycurlClient extends AIFunctionsProvider {
) { ) {
return this.ky return this.ky
.get('api/linkedin/company/resolve', { .get('api/linkedin/company/resolve', {
searchParams: { ...opts } searchParams: sanitizeSearchParams({
enrich_profile: 'enrich',
...opts
})
}) })
.json<proxycurl.ResultProfile>() .json<proxycurl.ResultProfile>()
} }
@ -2162,7 +2192,7 @@ export class ProxycurlClient extends AIFunctionsProvider {
async searchCompanies(opts: proxycurl.CompanySearchEndpointParamsQueryClass) { async searchCompanies(opts: proxycurl.CompanySearchEndpointParamsQueryClass) {
return this.ky return this.ky
.get('api/v2/search/company', { .get('api/v2/search/company', {
searchParams: { ...opts } searchParams: sanitizeSearchParams(opts)
}) })
.json<proxycurl.CompanySearchResult>() .json<proxycurl.CompanySearchResult>()
} }
@ -2176,7 +2206,7 @@ export class ProxycurlClient extends AIFunctionsProvider {
async searchPeople(opts: proxycurl.PersonSearchEndpointParamsQueryClass) { async searchPeople(opts: proxycurl.PersonSearchEndpointParamsQueryClass) {
return this.ky return this.ky
.get('api/v2/search/person/', { .get('api/v2/search/person/', {
searchParams: { ...opts } searchParams: sanitizeSearchParams(opts)
}) })
.json<proxycurl.PersonSearchResult>() .json<proxycurl.PersonSearchResult>()
} }

Wyświetl plik

@ -7,7 +7,7 @@ import QuickLRU from 'quick-lru'
import { hashObject } from './utils.js' import { hashObject } from './utils.js'
const protocolAllowList = new Set(['https:', 'http:']) const protocolAllowList = new Set(['https:', 'http:'])
const normalizedUrlCache = new QuickLRU<string, string | null>({ const normalizedUrlCache = new QuickLRU<string, string>({
maxSize: 4000 maxSize: 4000
}) })
@ -42,11 +42,11 @@ export function isRelativeUrl(url: string): boolean {
export function normalizeUrl( export function normalizeUrl(
url: string, url: string,
options?: NormalizeUrlOptions options?: NormalizeUrlOptions
): string | null { ): string | undefined {
let normalizedUrl: string | null | undefined let normalizedUrl: string | undefined
if (!url || isRelativeUrl(url)) { if (!url || isRelativeUrl(url)) {
return null return undefined
} }
const opts = { const opts = {
@ -71,18 +71,26 @@ export function normalizeUrl(
normalizedUrl = normalizedUrlCache.get(cacheKey) normalizedUrl = normalizedUrlCache.get(cacheKey)
if (normalizedUrl !== undefined) { if (normalizedUrl !== undefined) {
return normalizedUrl if (normalizedUrl) {
return normalizedUrl
} else {
return undefined
}
} }
normalizedUrl = normalizeUrlImpl(url, opts) normalizedUrl = normalizeUrlImpl(url, opts)
if (!normalizeUrl) { if (!normalizeUrl) {
normalizedUrl = null normalizedUrl = ''
} }
} catch { } catch {
// ignore invalid urls // ignore invalid urls
normalizedUrl = null normalizedUrl = ''
} }
normalizedUrlCache.set(cacheKey, normalizedUrl!) normalizedUrlCache.set(cacheKey, normalizedUrl!)
return normalizedUrl if (normalizedUrl) {
return normalizedUrl
} else {
return undefined
}
} }