kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
feat: add gravatar tool
rodzic
e5dd72a393
commit
42a7241bcd
|
@ -23,7 +23,7 @@ jobs:
|
||||||
- name: Install pnpm
|
- name: Install pnpm
|
||||||
uses: pnpm/action-setup@v4
|
uses: pnpm/action-setup@v4
|
||||||
with:
|
with:
|
||||||
version: 10.4.1
|
version: 10.5.2
|
||||||
run_install: false
|
run_install: false
|
||||||
|
|
||||||
- name: Install Node.js
|
- name: Install Node.js
|
||||||
|
|
|
@ -63,6 +63,7 @@
|
||||||
"tools/exa",
|
"tools/exa",
|
||||||
"tools/firecrawl",
|
"tools/firecrawl",
|
||||||
"tools/hacker-news",
|
"tools/hacker-news",
|
||||||
|
"tools/gravatar",
|
||||||
"tools/hunter",
|
"tools/hunter",
|
||||||
"tools/jina",
|
"tools/jina",
|
||||||
"tools/leadmagic",
|
"tools/leadmagic",
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
---
|
||||||
|
title: Gravatar
|
||||||
|
description: Gravatar Profile API.
|
||||||
|
---
|
||||||
|
|
||||||
|
- package: `@agentic/gravatar`
|
||||||
|
- exports: `class GravatarClient`, `namespace gravatar`
|
||||||
|
- env vars: `GRAVATAR_API_KEY` _(optional)_
|
||||||
|
- [source](https://github.com/transitive-bullshit/agentic/blob/main/packages/gravatar/src/gravatar-client.ts)
|
||||||
|
- [Gravatar API docs](https://docs.gravatar.com/api/profiles/rest-api/)
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
<CodeGroup>
|
||||||
|
```bash npm
|
||||||
|
npm install @agentic/gravatar
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash yarn
|
||||||
|
yarn add @agentic/gravatar
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash pnpm
|
||||||
|
pnpm add @agentic/gravatar
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeGroup>
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```ts
|
||||||
|
import { GravatarClient } from '@agentic/gravatar'
|
||||||
|
|
||||||
|
const gravatar = new GravatarClient()
|
||||||
|
const profile = await gravatar.getProfileByIdentifier('my-email@example.com')
|
||||||
|
```
|
|
@ -1,6 +1,6 @@
|
||||||
import 'dotenv/config'
|
import 'dotenv/config'
|
||||||
|
|
||||||
import { ZoomInfoClient } from '@agentic/stdlib'
|
import * as stdlib from '@agentic/stdlib'
|
||||||
import restoreCursor from 'restore-cursor'
|
import restoreCursor from 'restore-cursor'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -135,15 +135,17 @@ async function main() {
|
||||||
// category: 'linkedin profile'
|
// category: 'linkedin profile'
|
||||||
// })
|
// })
|
||||||
|
|
||||||
const zoomInfo = new ZoomInfoClient()
|
// const zoomInfo = new ZoomInfoClient()
|
||||||
const res = await zoomInfo.enrichContact({
|
// const res = await zoomInfo.enrichContact({
|
||||||
// emailAddress: 'travis@transitivebullsh.it'
|
// // emailAddress: 'travis@transitivebullsh.it'
|
||||||
fullName: 'Kevin Raheja',
|
// fullName: 'Kevin Raheja',
|
||||||
companyName: 'HeyGen'
|
// companyName: 'HeyGen'
|
||||||
})
|
// })
|
||||||
// const res = await zoomInfo.searchContacts({
|
// const res = await zoomInfo.searchContacts({
|
||||||
// fullName: 'Kevin Raheja'
|
// fullName: 'Kevin Raheja'
|
||||||
// })
|
// })
|
||||||
|
const gravatar = new stdlib.GravatarClient()
|
||||||
|
const res = await gravatar.getProfileByIdentifier('email@example.com')
|
||||||
|
|
||||||
console.log(JSON.stringify(res, null, 2))
|
console.log(JSON.stringify(res, null, 2))
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/transitive-bullshit/agentic.git"
|
"url": "git+https://github.com/transitive-bullshit/agentic.git"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@10.4.1",
|
"packageManager": "pnpm@10.5.2",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
{
|
||||||
|
"name": "@agentic/gravatar",
|
||||||
|
"version": "7.4.1",
|
||||||
|
"description": "Agentic SDK for Gravatar.",
|
||||||
|
"author": "Travis Fischer <travis@transitivebullsh.it>",
|
||||||
|
"license": "MIT",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/transitive-bullshit/agentic.git",
|
||||||
|
"directory": "packages/gravatar"
|
||||||
|
},
|
||||||
|
"type": "module",
|
||||||
|
"source": "./src/index.ts",
|
||||||
|
"types": "./dist/index.d.ts",
|
||||||
|
"sideEffects": false,
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./dist/index.d.ts",
|
||||||
|
"import": "./dist/index.js",
|
||||||
|
"default": "./dist/index.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"dist"
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsup --config ../../tsup.config.ts",
|
||||||
|
"dev": "tsup --config ../../tsup.config.ts --watch",
|
||||||
|
"clean": "del dist",
|
||||||
|
"test": "run-s test:*",
|
||||||
|
"test:lint": "eslint .",
|
||||||
|
"test:typecheck": "tsc --noEmit"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@agentic/core": "workspace:*",
|
||||||
|
"ky": "^1.7.5",
|
||||||
|
"p-throttle": "^6.2.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"zod": "^3.24.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@agentic/tsconfig": "workspace:*"
|
||||||
|
},
|
||||||
|
"publishConfig": {
|
||||||
|
"access": "public"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://agentic.so">
|
||||||
|
<img alt="Agentic" src="https://raw.githubusercontent.com/transitive-bullshit/agentic/main/docs/media/agentic-header.jpg" width="308">
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<em>AI agent stdlib that works with any LLM and TypeScript AI SDK.</em>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://github.com/transitive-bullshit/agentic/actions/workflows/main.yml"><img alt="Build Status" src="https://github.com/transitive-bullshit/agentic/actions/workflows/main.yml/badge.svg" /></a>
|
||||||
|
<a href="https://www.npmjs.com/package/@agentic/stdlib"><img alt="NPM" src="https://img.shields.io/npm/v/@agentic/stdlib.svg" /></a>
|
||||||
|
<a href="https://github.com/transitive-bullshit/agentic/blob/main/license"><img alt="MIT License" src="https://img.shields.io/badge/license-MIT-blue" /></a>
|
||||||
|
<a href="https://prettier.io"><img alt="Prettier Code Formatting" src="https://img.shields.io/badge/code_style-prettier-brightgreen.svg" /></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
# Agentic
|
||||||
|
|
||||||
|
**See the [github repo](https://github.com/transitive-bullshit/agentic) or [docs](https://agentic.so) for more info.**
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
MIT © [Travis Fischer](https://x.com/transitive_bs)
|
|
@ -0,0 +1,148 @@
|
||||||
|
import crypto from 'node:crypto'
|
||||||
|
|
||||||
|
import {
|
||||||
|
aiFunction,
|
||||||
|
AIFunctionsProvider,
|
||||||
|
getEnv,
|
||||||
|
throttleKy
|
||||||
|
} from '@agentic/core'
|
||||||
|
import defaultKy, { type KyInstance } from 'ky'
|
||||||
|
import pThrottle from 'p-throttle'
|
||||||
|
import z from 'zod'
|
||||||
|
|
||||||
|
export namespace gravatar {
|
||||||
|
export const API_BASE_URL = 'https://api.gravatar.com'
|
||||||
|
|
||||||
|
// Allow up to 100 unauthenticated requests per hour by default.
|
||||||
|
export const unauthenticatedThrottle = pThrottle({
|
||||||
|
limit: 100,
|
||||||
|
interval: 60 * 60 * 1000
|
||||||
|
})
|
||||||
|
|
||||||
|
// Allow up to 1000 authenticated requests per hour by default.
|
||||||
|
export const authenticatedThrottle = pThrottle({
|
||||||
|
limit: 1000,
|
||||||
|
interval: 60 * 60 * 1000
|
||||||
|
})
|
||||||
|
|
||||||
|
export type GetProfileByIdentifierOptions = {
|
||||||
|
email: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Profile {
|
||||||
|
/** The SHA256 hash of the user’s primary email address. */
|
||||||
|
hash: string
|
||||||
|
/** The user’s display name that appears on their profile. */
|
||||||
|
display_name: string
|
||||||
|
/** The full URL to the user’s Gravatar profile. */
|
||||||
|
profile_url: string
|
||||||
|
/** The URL to the user’s avatar image, if set. */
|
||||||
|
avatar_url: string
|
||||||
|
/** Alternative text describing the user’s avatar. */
|
||||||
|
avatar_alt_text: string
|
||||||
|
/** The user’s geographical location. */
|
||||||
|
location: string
|
||||||
|
/** A short biography or description about the user found on their profile. */
|
||||||
|
description: string
|
||||||
|
/** The user’s current job title. */
|
||||||
|
job_title: string
|
||||||
|
/** The name of the company where the user is employed. */
|
||||||
|
company: string
|
||||||
|
/** An array of verified accounts the user has added to their profile. The number of verified accounts displayed is limited to a maximum of 4 in unauthenticated requests. */
|
||||||
|
verified_accounts: any[]
|
||||||
|
/** A phonetic guide to pronouncing the user’s name. */
|
||||||
|
pronunciation: string
|
||||||
|
/** The pronouns the user prefers to use. */
|
||||||
|
pronouns: string
|
||||||
|
|
||||||
|
/** The total number of verified accounts the user has added to their profile, including those not displayed on their profile. This property is only provided in authenticated API requests. */
|
||||||
|
number_verified_accounts?: number
|
||||||
|
|
||||||
|
/** The date and time (UTC) when the user last edited their profile. This property is only provided in authenticated API requests. Example: "2021-10-01T12:00:00Z" */
|
||||||
|
last_profile_edit?: string
|
||||||
|
|
||||||
|
/** The date the user registered their account. This property is only provided in authenticated API requests. Example: "2021-10-01" */
|
||||||
|
registration_date?: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A client for the Gravatar API.
|
||||||
|
*
|
||||||
|
* API key is optional.
|
||||||
|
*
|
||||||
|
* @see https://docs.gravatar.com/getting-started/
|
||||||
|
*/
|
||||||
|
export class GravatarClient extends AIFunctionsProvider {
|
||||||
|
protected readonly ky: KyInstance
|
||||||
|
protected readonly apiKey?: string
|
||||||
|
protected readonly apiBaseUrl: string
|
||||||
|
|
||||||
|
constructor({
|
||||||
|
apiKey = getEnv('GRAVATAR_API_KEY'),
|
||||||
|
apiBaseUrl = gravatar.API_BASE_URL,
|
||||||
|
timeoutMs = 60_000,
|
||||||
|
throttle = true,
|
||||||
|
ky = defaultKy
|
||||||
|
}: {
|
||||||
|
apiKey?: string
|
||||||
|
apiBaseUrl?: string
|
||||||
|
timeoutMs?: number
|
||||||
|
throttle?: boolean
|
||||||
|
ky?: KyInstance
|
||||||
|
} = {}) {
|
||||||
|
super()
|
||||||
|
|
||||||
|
// API key is optional
|
||||||
|
this.apiKey = apiKey
|
||||||
|
this.apiBaseUrl = apiBaseUrl
|
||||||
|
|
||||||
|
const throttledKy = throttle
|
||||||
|
? throttleKy(
|
||||||
|
ky,
|
||||||
|
apiKey
|
||||||
|
? gravatar.authenticatedThrottle
|
||||||
|
: gravatar.unauthenticatedThrottle
|
||||||
|
)
|
||||||
|
: ky
|
||||||
|
|
||||||
|
this.ky = throttledKy.extend({
|
||||||
|
prefixUrl: apiBaseUrl,
|
||||||
|
timeout: timeoutMs,
|
||||||
|
headers: Object.fromEntries(
|
||||||
|
apiKey ? [['Authorization', `Bearer ${apiKey}`]] : []
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
@aiFunction({
|
||||||
|
name: 'gravatar_get_profile',
|
||||||
|
description:
|
||||||
|
'Get Gravatar profile by email. Returns a profile object or `undefined` if not found.',
|
||||||
|
inputSchema: z.object({
|
||||||
|
email: z.string()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
async getProfileByIdentifier(
|
||||||
|
emailOrOpts: string | gravatar.GetProfileByIdentifierOptions
|
||||||
|
): Promise<gravatar.Profile | undefined> {
|
||||||
|
const { email } =
|
||||||
|
typeof emailOrOpts === 'string' ? { email: emailOrOpts } : emailOrOpts
|
||||||
|
const hashedEmail = crypto
|
||||||
|
.createHash('SHA256')
|
||||||
|
.update(email.trim().toLowerCase(), 'utf8')
|
||||||
|
.digest('hex')
|
||||||
|
|
||||||
|
try {
|
||||||
|
return await this.ky
|
||||||
|
.get(`v3/profiles/${hashedEmail}`)
|
||||||
|
.json<gravatar.Profile>()
|
||||||
|
} catch (err: any) {
|
||||||
|
if (err.response?.status === 404) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './gravatar-client'
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"extends": "@agentic/tsconfig/base.json",
|
||||||
|
"include": ["src"],
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
|
@ -45,6 +45,7 @@
|
||||||
"@agentic/firecrawl": "workspace:*",
|
"@agentic/firecrawl": "workspace:*",
|
||||||
"@agentic/genkit": "workspace:*",
|
"@agentic/genkit": "workspace:*",
|
||||||
"@agentic/github": "workspace:*",
|
"@agentic/github": "workspace:*",
|
||||||
|
"@agentic/gravatar": "workspace:*",
|
||||||
"@agentic/hacker-news": "workspace:*",
|
"@agentic/hacker-news": "workspace:*",
|
||||||
"@agentic/hunter": "workspace:*",
|
"@agentic/hunter": "workspace:*",
|
||||||
"@agentic/jina": "workspace:*",
|
"@agentic/jina": "workspace:*",
|
||||||
|
|
|
@ -8,6 +8,7 @@ export * from '@agentic/e2b'
|
||||||
export * from '@agentic/exa'
|
export * from '@agentic/exa'
|
||||||
export * from '@agentic/firecrawl'
|
export * from '@agentic/firecrawl'
|
||||||
export * from '@agentic/github'
|
export * from '@agentic/github'
|
||||||
|
export * from '@agentic/gravatar'
|
||||||
export * from '@agentic/hacker-news'
|
export * from '@agentic/hacker-news'
|
||||||
export * from '@agentic/hunter'
|
export * from '@agentic/hunter'
|
||||||
export * from '@agentic/jina'
|
export * from '@agentic/jina'
|
||||||
|
|
|
@ -495,6 +495,25 @@ importers:
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../tsconfig
|
version: link:../tsconfig
|
||||||
|
|
||||||
|
packages/gravatar:
|
||||||
|
dependencies:
|
||||||
|
'@agentic/core':
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../core
|
||||||
|
ky:
|
||||||
|
specifier: ^1.7.5
|
||||||
|
version: 1.7.5
|
||||||
|
p-throttle:
|
||||||
|
specifier: ^6.2.0
|
||||||
|
version: 6.2.0
|
||||||
|
zod:
|
||||||
|
specifier: ^3.24.2
|
||||||
|
version: 3.24.2
|
||||||
|
devDependencies:
|
||||||
|
'@agentic/tsconfig':
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../tsconfig
|
||||||
|
|
||||||
packages/hacker-news:
|
packages/hacker-news:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@agentic/core':
|
'@agentic/core':
|
||||||
|
@ -883,6 +902,9 @@ importers:
|
||||||
'@agentic/github':
|
'@agentic/github':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../github
|
version: link:../github
|
||||||
|
'@agentic/gravatar':
|
||||||
|
specifier: workspace:*
|
||||||
|
version: link:../gravatar
|
||||||
'@agentic/hacker-news':
|
'@agentic/hacker-news':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../hacker-news
|
version: link:../hacker-news
|
||||||
|
|
|
@ -157,6 +157,7 @@ Full docs are available at [agentic.so](https://agentic.so).
|
||||||
| [E2B](https://e2b.dev) | `@agentic/e2b` | [docs](https://agentic.so/tools/e2b) | Hosted Python code interpreter sandbox which is really useful for data analysis, flexible code execution, and advanced reasoning on-the-fly. |
|
| [E2B](https://e2b.dev) | `@agentic/e2b` | [docs](https://agentic.so/tools/e2b) | Hosted Python code interpreter sandbox which is really useful for data analysis, flexible code execution, and advanced reasoning on-the-fly. |
|
||||||
| [Exa](https://docs.exa.ai) | `@agentic/exa` | [docs](https://agentic.so/tools/exa) | Web search tailored for LLMs. |
|
| [Exa](https://docs.exa.ai) | `@agentic/exa` | [docs](https://agentic.so/tools/exa) | Web search tailored for LLMs. |
|
||||||
| [Firecrawl](https://www.firecrawl.dev) | `@agentic/firecrawl` | [docs](https://agentic.so/tools/firecrawl) | Website scraping and structured data extraction. |
|
| [Firecrawl](https://www.firecrawl.dev) | `@agentic/firecrawl` | [docs](https://agentic.so/tools/firecrawl) | Website scraping and structured data extraction. |
|
||||||
|
| [Gravatar](https://docs.gravatar.com/api/profiles/rest-api/) | `@agentic/gravatar` | [docs](https://agentic.so/tools/gravatar) | Gravatar profile API. |
|
||||||
| [HackerNews](https://github.com/HackerNews/API) | `@agentic/hacker-news` | [docs](https://agentic.so/tools/hacker-news) | Official HackerNews API. |
|
| [HackerNews](https://github.com/HackerNews/API) | `@agentic/hacker-news` | [docs](https://agentic.so/tools/hacker-news) | Official HackerNews API. |
|
||||||
| [Hunter](https://hunter.io) | `@agentic/hunter` | [docs](https://agentic.so/tools/hunter) | Email finder, verifier, and enrichment. |
|
| [Hunter](https://hunter.io) | `@agentic/hunter` | [docs](https://agentic.so/tools/hunter) | Email finder, verifier, and enrichment. |
|
||||||
| [Jina](https://jina.ai/reader) | `@agentic/jina` | [docs](https://agentic.so/tools/jina) | URL scraper and web search. |
|
| [Jina](https://jina.ai/reader) | `@agentic/jina` | [docs](https://agentic.so/tools/jina) | URL scraper and web search. |
|
||||||
|
|
Ładowanie…
Reference in New Issue