diff --git a/package.json b/package.json index 86e93712..c7296855 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "SECURITY.md" ], "dependencies": { + "@types/axios": "^0.14.0", "axios": "^1.4.0", "typescript": "^5.1.3" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 00000000..af607756 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,97 @@ +lockfileVersion: 5.4 + +specifiers: + '@types/axios': ^0.14.0 + '@types/node': ^20.3.3 + axios: ^1.4.0 + typescript: ^5.1.3 + +dependencies: + '@types/axios': 0.14.0 + axios: 1.4.0 + typescript: 5.1.6 + +devDependencies: + '@types/node': 20.4.5 + +packages: + + /@types/axios/0.14.0: + resolution: {integrity: sha512-KqQnQbdYE54D7oa/UmYVMZKq7CO4l8DEENzOKc4aBRwxCXSlJXGz83flFx5L7AWrOQnmuN3kVsRdt+GZPPjiVQ==} + deprecated: This is a stub types definition for axios (https://github.com/mzabriskie/axios). axios provides its own type definitions, so you don't need @types/axios installed! + dependencies: + axios: 1.4.0 + transitivePeerDependencies: + - debug + dev: false + + /@types/node/20.4.5: + resolution: {integrity: sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg==} + dev: true + + /asynckit/0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: false + + /axios/1.4.0: + resolution: {integrity: sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==} + dependencies: + follow-redirects: 1.15.2 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + dev: false + + /combined-stream/1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: false + + /delayed-stream/1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dev: false + + /follow-redirects/1.15.2: + resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: false + + /form-data/4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: false + + /mime-db/1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + dev: false + + /mime-types/2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: false + + /proxy-from-env/1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + dev: false + + /typescript/5.1.6: + resolution: {integrity: sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==} + engines: {node: '>=14.17'} + hasBin: true + dev: false diff --git a/src/model.ts b/src/model.ts index dc0dafcb..860ad8b1 100644 --- a/src/model.ts +++ b/src/model.ts @@ -1,4 +1,4 @@ -import axios from "axios"; +import axios, { CreateAxiosDefaults } from "axios"; import { Result, success, error } from "./result"; /** @@ -23,6 +23,9 @@ export interface TypeChatLanguageModel { complete(prompt: string): Promise>; } +interface Options { + axiosConfg?: CreateAxiosDefaults +} /** * Creates a language model encapsulation of an OpenAI or Azure OpenAI REST API endpoint * chosen by environment variables. @@ -38,18 +41,18 @@ export interface TypeChatLanguageModel { * If none of these key variables are defined, an exception is thrown. * @returns An instance of `TypeChatLanguageModel`. */ -export function createLanguageModel(env: Record): TypeChatLanguageModel { +export function createLanguageModel(env: Record, options?: Options): TypeChatLanguageModel { if (env.OPENAI_API_KEY) { const apiKey = env.OPENAI_API_KEY ?? missingEnvironmentVariable("OPENAI_API_KEY"); const model = env.OPENAI_MODEL ?? missingEnvironmentVariable("OPENAI_MODEL"); const endPoint = env.OPENAI_ENDPOINT ?? "https://api.openai.com/v1/chat/completions"; const org = env.OPENAI_ORGANIZATION ?? ""; - return createOpenAILanguageModel(apiKey, model, endPoint, org); + return createOpenAILanguageModel(apiKey, model, endPoint, org, options); } if (env.AZURE_OPENAI_API_KEY) { const apiKey = env.AZURE_OPENAI_API_KEY ?? missingEnvironmentVariable("AZURE_OPENAI_API_KEY"); const endPoint = env.AZURE_OPENAI_ENDPOINT ?? missingEnvironmentVariable("AZURE_OPENAI_ENDPOINT"); - return createAzureOpenAILanguageModel(apiKey, endPoint); + return createAzureOpenAILanguageModel(apiKey, endPoint, options); } missingEnvironmentVariable("OPENAI_API_KEY or AZURE_OPENAI_API_KEY"); } @@ -62,13 +65,13 @@ export function createLanguageModel(env: Record): Ty * @param org The OpenAI organization id. * @returns An instance of `TypeChatLanguageModel`. */ -export function createOpenAILanguageModel(apiKey: string, model: string, endPoint = "https://api.openai.com/v1/chat/completions", org = ""): TypeChatLanguageModel { - return createAxiosLanguageModel(endPoint, { +export function createOpenAILanguageModel(apiKey: string, model: string, endPoint = "https://api.openai.com/v1/chat/completions", org = "", options: Options = {}): TypeChatLanguageModel { + return createAxiosLanguageModel(endPoint, Object.assign({ headers: { Authorization: `Bearer ${apiKey}`, "OpenAI-Organization": org - } - }, { model }); + }, + }, options), { model }); } /** @@ -79,8 +82,8 @@ export function createOpenAILanguageModel(apiKey: string, model: string, endPoin * @param apiKey The Azure OpenAI API key. * @returns An instance of `TypeChatLanguageModel`. */ -export function createAzureOpenAILanguageModel(apiKey: string, endPoint: string,): TypeChatLanguageModel { - return createAxiosLanguageModel(endPoint, { headers: { "api-key": apiKey } }, {}); +export function createAzureOpenAILanguageModel(apiKey: string, endPoint: string, options: Options = {}): TypeChatLanguageModel { + return createAxiosLanguageModel(endPoint, Object.assign({ headers: { "api-key": apiKey } }, options), {}); } /**