kopia lustrzana https://github.com/transitive-bullshit/chatgpt-api
feat: add getEnv function
rodzic
d8fb25f9c2
commit
bbe66bd6fa
42
.eslintrc
42
.eslintrc
|
@ -1,13 +1,7 @@
|
||||||
{
|
{
|
||||||
"parser": "@typescript-eslint/parser",
|
"parser": "@typescript-eslint/parser",
|
||||||
"extends": [
|
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
|
||||||
"eslint:recommended",
|
"plugins": ["@typescript-eslint", "eslint-plugin-tsdoc"],
|
||||||
"plugin:@typescript-eslint/recommended"
|
|
||||||
],
|
|
||||||
"plugins": [
|
|
||||||
"@typescript-eslint",
|
|
||||||
"eslint-plugin-tsdoc"
|
|
||||||
],
|
|
||||||
"root": true,
|
"root": true,
|
||||||
"env": {
|
"env": {
|
||||||
"browser": false,
|
"browser": false,
|
||||||
|
@ -38,43 +32,35 @@
|
||||||
"error",
|
"error",
|
||||||
{
|
{
|
||||||
"blankLine": "always",
|
"blankLine": "always",
|
||||||
"prev": [
|
"prev": ["block", "block-like"],
|
||||||
"block",
|
|
||||||
"block-like"
|
|
||||||
],
|
|
||||||
"next": "*"
|
"next": "*"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"blankLine": "always",
|
"blankLine": "always",
|
||||||
"prev": "*",
|
"prev": "*",
|
||||||
"next": [
|
"next": ["block", "block-like"]
|
||||||
"block",
|
|
||||||
"block-like"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"blankLine": "any",
|
"blankLine": "any",
|
||||||
"prev": [
|
"prev": ["singleline-const", "singleline-let", "expression"],
|
||||||
"singleline-const",
|
"next": ["block", "block-like"]
|
||||||
"singleline-let",
|
|
||||||
"expression"
|
|
||||||
],
|
|
||||||
"next": [
|
|
||||||
"block",
|
|
||||||
"block-like"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"tsdoc/syntax": "warn"
|
"tsdoc/syntax": "warn"
|
||||||
},
|
},
|
||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{
|
||||||
"files": [
|
"files": ["*.tsx"],
|
||||||
"*.tsx"
|
|
||||||
],
|
|
||||||
"rules": {
|
"rules": {
|
||||||
"no-undef": "off"
|
"no-undef": "off"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// disable process.env for framework source files
|
||||||
|
"files": "src/**/*.ts",
|
||||||
|
"rules": {
|
||||||
|
"no-process-env": "error"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"settings": {},
|
"settings": {},
|
||||||
|
|
|
@ -10,7 +10,6 @@ import { defaultLogger } from './logger'
|
||||||
import { defaultIDGeneratorFn, isFunction, isString } from './utils'
|
import { defaultIDGeneratorFn, isFunction, isString } from './utils'
|
||||||
|
|
||||||
export class Agentic {
|
export class Agentic {
|
||||||
// _taskMap: WeakMap<string, BaseTask<any, any>>
|
|
||||||
protected _ky: types.KyInstance
|
protected _ky: types.KyInstance
|
||||||
protected _logger: types.Logger
|
protected _logger: types.Logger
|
||||||
|
|
||||||
|
@ -103,7 +102,7 @@ export class Agentic {
|
||||||
return this._idGeneratorFn
|
return this._idGeneratorFn
|
||||||
}
|
}
|
||||||
|
|
||||||
openaiChatCompletion<TInput extends types.TaskInput = any>(
|
openaiChatCompletion<TInput extends types.TaskInput = void>(
|
||||||
promptOrChatCompletionParams:
|
promptOrChatCompletionParams:
|
||||||
| types.ChatMessageContent<TInput>
|
| types.ChatMessageContent<TInput>
|
||||||
| SetOptional<types.OpenAIChatCompletionParamsInput<TInput>, 'model'>,
|
| SetOptional<types.OpenAIChatCompletionParamsInput<TInput>, 'model'>,
|
||||||
|
@ -148,7 +147,7 @@ export class Agentic {
|
||||||
/**
|
/**
|
||||||
* Shortcut for creating an OpenAI chat completion call with the `gpt-3.5-turbo` model.
|
* Shortcut for creating an OpenAI chat completion call with the `gpt-3.5-turbo` model.
|
||||||
*/
|
*/
|
||||||
gpt3<TInput extends types.TaskInput = any>(
|
gpt3<TInput extends types.TaskInput = void>(
|
||||||
promptOrChatCompletionParams:
|
promptOrChatCompletionParams:
|
||||||
| types.ChatMessageContent<TInput>
|
| types.ChatMessageContent<TInput>
|
||||||
| SetOptional<types.OpenAIChatCompletionParamsInput<TInput>, 'model'>,
|
| SetOptional<types.OpenAIChatCompletionParamsInput<TInput>, 'model'>,
|
||||||
|
@ -194,7 +193,7 @@ export class Agentic {
|
||||||
/**
|
/**
|
||||||
* Shortcut for creating an OpenAI chat completion call with the `gpt-4` model.
|
* Shortcut for creating an OpenAI chat completion call with the `gpt-4` model.
|
||||||
*/
|
*/
|
||||||
gpt4<TInput extends types.TaskInput = any>(
|
gpt4<TInput extends types.TaskInput = void>(
|
||||||
promptOrChatCompletionParams:
|
promptOrChatCompletionParams:
|
||||||
| types.ChatMessageContent<TInput>
|
| types.ChatMessageContent<TInput>
|
||||||
| SetOptional<types.OpenAIChatCompletionParamsInput<TInput>, 'model'>,
|
| SetOptional<types.OpenAIChatCompletionParamsInput<TInput>, 'model'>,
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
export function getEnv(
|
||||||
|
name: string,
|
||||||
|
defaultValue?: string
|
||||||
|
): string | undefined {
|
||||||
|
try {
|
||||||
|
return (
|
||||||
|
(typeof process !== 'undefined'
|
||||||
|
? // eslint-disable-next-line no-process-env
|
||||||
|
process.env?.[name]
|
||||||
|
: undefined) ?? defaultValue
|
||||||
|
)
|
||||||
|
} catch (e) {
|
||||||
|
return defaultValue
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,8 @@
|
||||||
import { pino } from 'pino'
|
import { pino } from 'pino'
|
||||||
import pinoPretty from 'pino-pretty'
|
import pinoPretty from 'pino-pretty'
|
||||||
|
|
||||||
|
import { getEnv } from './env'
|
||||||
|
|
||||||
export type Level = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace'
|
export type Level = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace'
|
||||||
export type LevelWithSilent = Level | 'silent'
|
export type LevelWithSilent = Level | 'silent'
|
||||||
|
|
||||||
|
@ -103,7 +105,7 @@ export interface Logger {
|
||||||
|
|
||||||
export const defaultLogger: Logger = pino(
|
export const defaultLogger: Logger = pino(
|
||||||
{
|
{
|
||||||
level: process.env.LOG_LEVEL || 'info'
|
level: getEnv('LOG_LEVEL', 'info')
|
||||||
},
|
},
|
||||||
pinoPretty({
|
pinoPretty({
|
||||||
sync: true,
|
sync: true,
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import logger from 'debug'
|
import logger from 'debug'
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
|
|
||||||
|
import { getEnv } from './env'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of events that can occur within the library.
|
* List of events that can occur within the library.
|
||||||
*/
|
*/
|
||||||
|
@ -26,14 +28,12 @@ type SeverityType = (typeof Severity)[keyof typeof Severity]
|
||||||
* Define minimum LOG_LEVEL, defaulting to Severity.INFO if not provided or if an invalid value is provided. Any events below that level won't be logged to the console.
|
* Define minimum LOG_LEVEL, defaulting to Severity.INFO if not provided or if an invalid value is provided. Any events below that level won't be logged to the console.
|
||||||
*/
|
*/
|
||||||
let LOG_LEVEL: SeverityType = Severity.INFO
|
let LOG_LEVEL: SeverityType = Severity.INFO
|
||||||
|
const logLevelEnv = getEnv('DEBUG_LOG_LEVEL')
|
||||||
|
|
||||||
if (
|
if (logLevelEnv && Severity[logLevelEnv.toUpperCase()] !== undefined) {
|
||||||
process.env.DEBUG_LOG_LEVEL &&
|
LOG_LEVEL = Severity[logLevelEnv.toUpperCase()]
|
||||||
Severity[process.env.DEBUG_LOG_LEVEL.toUpperCase()] !== undefined
|
} else if (logLevelEnv) {
|
||||||
) {
|
throw new Error(`Invalid value for LOG_LEVEL: ${logLevelEnv}`)
|
||||||
LOG_LEVEL = Severity[process.env.DEBUG_LOG_LEVEL.toUpperCase()]
|
|
||||||
} else if (process.env.DEBUG_LOG_LEVEL) {
|
|
||||||
throw new Error(`Invalid value for LOG_LEVEL: ${process.env.DEBUG_LOG_LEVEL}`)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import defaultKy from 'ky'
|
import defaultKy from 'ky'
|
||||||
|
|
||||||
|
import { getEnv } from '@/env'
|
||||||
|
|
||||||
export const BING_API_BASE_URL = 'https://api.bing.microsoft.com'
|
export const BING_API_BASE_URL = 'https://api.bing.microsoft.com'
|
||||||
|
|
||||||
export interface BingWebSearchQuery {
|
export interface BingWebSearchQuery {
|
||||||
|
@ -241,7 +243,7 @@ export class BingWebSearchClient {
|
||||||
apiBaseUrl: string
|
apiBaseUrl: string
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
apiKey = process.env.BING_API_KEY,
|
apiKey = getEnv('BING_API_KEY'),
|
||||||
apiBaseUrl = BING_API_BASE_URL,
|
apiBaseUrl = BING_API_BASE_URL,
|
||||||
ky = defaultKy
|
ky = defaultKy
|
||||||
}: {
|
}: {
|
||||||
|
|
|
@ -2,6 +2,7 @@ import defaultKy from 'ky'
|
||||||
import { AbortError } from 'p-retry'
|
import { AbortError } from 'p-retry'
|
||||||
import pThrottle from 'p-throttle'
|
import pThrottle from 'p-throttle'
|
||||||
|
|
||||||
|
import { getEnv } from '@/env'
|
||||||
import { throttleKy } from '@/utils'
|
import { throttleKy } from '@/utils'
|
||||||
|
|
||||||
export const DIFFBOT_API_BASE_URL = 'https://api.diffbot.com'
|
export const DIFFBOT_API_BASE_URL = 'https://api.diffbot.com'
|
||||||
|
@ -334,7 +335,7 @@ export class DiffbotClient {
|
||||||
apiKnowledgeGraphBaseUrl: string
|
apiKnowledgeGraphBaseUrl: string
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
apiKey = process.env.DIFFBOT_API_KEY,
|
apiKey = getEnv('DIFFBOT_API_KEY'),
|
||||||
apiBaseUrl = DIFFBOT_API_BASE_URL,
|
apiBaseUrl = DIFFBOT_API_BASE_URL,
|
||||||
apiKnowledgeGraphBaseUrl = DIFFBOT_KNOWLEDGE_GRAPH_API_BASE_URL,
|
apiKnowledgeGraphBaseUrl = DIFFBOT_KNOWLEDGE_GRAPH_API_BASE_URL,
|
||||||
timeoutMs = 30_000,
|
timeoutMs = 30_000,
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import defaultKy from 'ky'
|
import defaultKy from 'ky'
|
||||||
|
|
||||||
|
import { getEnv } from '@/env'
|
||||||
|
|
||||||
export const METAPHOR_API_BASE_URL = 'https://api.metaphor.systems'
|
export const METAPHOR_API_BASE_URL = 'https://api.metaphor.systems'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -119,7 +121,7 @@ export class MetaphorClient {
|
||||||
readonly apiBaseUrl: string
|
readonly apiBaseUrl: string
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
apiKey = process.env.METAPHOR_API_KEY,
|
apiKey = getEnv('METAPHOR_API_KEY'),
|
||||||
apiBaseUrl = METAPHOR_API_BASE_URL,
|
apiBaseUrl = METAPHOR_API_BASE_URL,
|
||||||
ky = defaultKy
|
ky = defaultKy
|
||||||
}: {
|
}: {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import defaultKy from 'ky'
|
import defaultKy from 'ky'
|
||||||
|
|
||||||
|
import { getEnv } from '@/env'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base URL endpoint for the Novu API.
|
* Base URL endpoint for the Novu API.
|
||||||
*/
|
*/
|
||||||
|
@ -110,7 +112,7 @@ export class NovuClient {
|
||||||
* Novu API client constructor.
|
* Novu API client constructor.
|
||||||
*/
|
*/
|
||||||
constructor({
|
constructor({
|
||||||
apiKey = process.env.NOVU_API_KEY,
|
apiKey = getEnv('NOVU_API_KEY'),
|
||||||
apiBaseUrl = NOVU_API_BASE_URL,
|
apiBaseUrl = NOVU_API_BASE_URL,
|
||||||
ky = defaultKy
|
ky = defaultKy
|
||||||
}: {
|
}: {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import defaultKy from 'ky'
|
import defaultKy from 'ky'
|
||||||
|
|
||||||
|
import { getEnv } from '@/env'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All types have been exported from the `serpapi` package, which we're
|
* All types have been exported from the `serpapi` package, which we're
|
||||||
* not using directly because it is bloated and has compatibility issues.
|
* not using directly because it is bloated and has compatibility issues.
|
||||||
|
@ -642,7 +644,7 @@ export class SerpAPIClient {
|
||||||
params: Partial<SerpAPIParams>
|
params: Partial<SerpAPIParams>
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
apiKey = process.env.SERPAPI_API_KEY ?? process.env.SERP_API_KEY,
|
apiKey = getEnv('SERPAPI_API_KEY') ?? getEnv('SERP_API_KEY'),
|
||||||
apiBaseUrl = SERPAPI_BASE_URL,
|
apiBaseUrl = SERPAPI_BASE_URL,
|
||||||
ky = defaultKy,
|
ky = defaultKy,
|
||||||
...params
|
...params
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import defaultKy from 'ky'
|
import defaultKy from 'ky'
|
||||||
|
|
||||||
|
import { getEnv } from '@/env'
|
||||||
import { sleep } from '@/utils'
|
import { sleep } from '@/utils'
|
||||||
|
|
||||||
export const SLACK_API_BASE_URL = 'https://slack.com/api'
|
export const SLACK_API_BASE_URL = 'https://slack.com/api'
|
||||||
|
@ -261,9 +262,9 @@ export class SlackClient {
|
||||||
protected defaultChannel?: string
|
protected defaultChannel?: string
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
apiKey = process.env.SLACK_API_KEY,
|
apiKey = getEnv('SLACK_API_KEY'),
|
||||||
baseUrl = SLACK_API_BASE_URL,
|
baseUrl = SLACK_API_BASE_URL,
|
||||||
defaultChannel = process.env.SLACK_DEFAULT_CHANNEL,
|
defaultChannel = getEnv('SLACK_DEFAULT_CHANNEL'),
|
||||||
ky = defaultKy
|
ky = defaultKy
|
||||||
}: {
|
}: {
|
||||||
apiKey?: string
|
apiKey?: string
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import defaultKy from 'ky'
|
import defaultKy from 'ky'
|
||||||
|
|
||||||
import { DEFAULT_BOT_NAME } from '@/constants'
|
import { DEFAULT_BOT_NAME } from '@/constants'
|
||||||
|
import { getEnv } from '@/env'
|
||||||
import { chunkMultipleStrings, chunkString, sleep } from '@/utils'
|
import { chunkMultipleStrings, chunkString, sleep } from '@/utils'
|
||||||
|
|
||||||
export const TWILIO_CONVERSATION_API_BASE_URL =
|
export const TWILIO_CONVERSATION_API_BASE_URL =
|
||||||
|
@ -208,11 +209,12 @@ export class TwilioConversationClient {
|
||||||
defaultRecipientPhoneNumber?: string
|
defaultRecipientPhoneNumber?: string
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
accountSid = process.env.TWILIO_ACCOUNT_SID,
|
accountSid = getEnv('TWILIO_ACCOUNT_SID'),
|
||||||
authToken = process.env.TWILIO_AUTH_TOKEN,
|
authToken = getEnv('TWILIO_AUTH_TOKEN'),
|
||||||
phoneNumber = process.env.TWILIO_PHONE_NUMBER,
|
phoneNumber = getEnv('TWILIO_PHONE_NUMBER'),
|
||||||
defaultRecipientPhoneNumber = process.env
|
defaultRecipientPhoneNumber = getEnv(
|
||||||
.TWILIO_DEFAULT_RECIPIENT_PHONE_NUMBER,
|
'TWILIO_DEFAULT_RECIPIENT_PHONE_NUMBER'
|
||||||
|
),
|
||||||
apiBaseUrl = TWILIO_CONVERSATION_API_BASE_URL,
|
apiBaseUrl = TWILIO_CONVERSATION_API_BASE_URL,
|
||||||
botName = DEFAULT_BOT_NAME,
|
botName = DEFAULT_BOT_NAME,
|
||||||
ky = defaultKy
|
ky = defaultKy
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import defaultKy from 'ky'
|
import defaultKy from 'ky'
|
||||||
|
|
||||||
|
import { getEnv } from '@/env'
|
||||||
|
|
||||||
export const WEATHER_API_BASE_URL = 'https://api.weatherapi.com/v1'
|
export const WEATHER_API_BASE_URL = 'https://api.weatherapi.com/v1'
|
||||||
|
|
||||||
interface CurrentWeatherResponse {
|
interface CurrentWeatherResponse {
|
||||||
|
@ -75,7 +77,7 @@ export class WeatherClient {
|
||||||
apiBaseUrl: string
|
apiBaseUrl: string
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
apiKey = process.env.WEATHER_API_KEY,
|
apiKey = getEnv('WEATHER_API_KEY'),
|
||||||
apiBaseUrl = WEATHER_API_BASE_URL,
|
apiBaseUrl = WEATHER_API_BASE_URL,
|
||||||
ky = defaultKy
|
ky = defaultKy
|
||||||
}: {
|
}: {
|
||||||
|
|
|
@ -18,8 +18,8 @@ import { defaultIDGeneratorFn, isValidTaskIdentifier } from './utils'
|
||||||
*
|
*
|
||||||
* Examples of tasks include:
|
* Examples of tasks include:
|
||||||
* - LLM calls
|
* - LLM calls
|
||||||
* - Chain of LLM calls
|
* - Chains of LLM calls
|
||||||
* - Retrieval task
|
* - Retrieval tasks
|
||||||
* - API calls
|
* - API calls
|
||||||
* - Native function calls
|
* - Native function calls
|
||||||
* - Invoking sub-agents
|
* - Invoking sub-agents
|
||||||
|
@ -94,6 +94,10 @@ export abstract class BaseTask<
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures that this task is configured correctly. `validate` will be called
|
||||||
|
* automatically before `task.call` or `task.callWithMetadata` are invoked.
|
||||||
|
*/
|
||||||
public validate() {
|
public validate() {
|
||||||
if (!this._agentic) {
|
if (!this._agentic) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
|
@ -241,6 +245,7 @@ export abstract class BaseTask<
|
||||||
(err as any).name === 'TimeoutError'
|
(err as any).name === 'TimeoutError'
|
||||||
) {
|
) {
|
||||||
// TODO
|
// TODO
|
||||||
|
return
|
||||||
} else if ((err.cause as any)?.code === 'UND_ERR_HEADERS_TIMEOUT') {
|
} else if ((err.cause as any)?.code === 'UND_ERR_HEADERS_TIMEOUT') {
|
||||||
// TODO: This is a pretty common OpenAI error, and I think it either has
|
// TODO: This is a pretty common OpenAI error, and I think it either has
|
||||||
// to do with OpenAI's servers being flaky or the combination of Node.js
|
// to do with OpenAI's servers being flaky or the combination of Node.js
|
||||||
|
|
Ładowanie…
Reference in New Issue