Load the JS client using pnpm workspaces

This makes it so we're using our own openpipe client for all OpenAI calls from the OpenPipe app.

The client doesn't do anything at the moment beyond proxying to the OpenAI lib. But this infra work should make it easier to quickly iterate on the client and test the changes in our own app.
This commit is contained in:
Kyle Corbitt
2023-08-12 15:19:48 -07:00
parent 8d373ec9b5
commit 344b257db4
29 changed files with 876 additions and 1562 deletions

2
.gitignore vendored
View File

@@ -1,3 +1,5 @@
.env .env
.venv/ .venv/
*.pyc *.pyc
node_modules/
*.tsbuildinfo

View File

@@ -6,7 +6,7 @@ const config = {
overrides: [ overrides: [
{ {
extends: ["plugin:@typescript-eslint/recommended-requiring-type-checking"], extends: ["plugin:@typescript-eslint/recommended-requiring-type-checking"],
files: ["*.ts", "*.tsx"], files: ["*.mts", "*.ts", "*.tsx"],
parserOptions: { parserOptions: {
project: path.join(__dirname, "tsconfig.json"), project: path.join(__dirname, "tsconfig.json"),
}, },

View File

@@ -36,6 +36,8 @@ let config = {
}); });
return config; return config;
}, },
transpilePackages: ["openpipe"],
}; };
config = nextRoutes()(config); config = nextRoutes()(config);

View File

@@ -1,5 +1,6 @@
{ {
"name": "openpipe", "name": "openpipe-app",
"private": true,
"type": "module", "type": "module",
"version": "0.1.0", "version": "0.1.0",
"license": "Apache-2.0", "license": "Apache-2.0",
@@ -16,7 +17,7 @@
"postinstall": "prisma generate", "postinstall": "prisma generate",
"lint": "next lint", "lint": "next lint",
"start": "next start", "start": "next start",
"codegen": "tsx src/server/scripts/client-codegen.ts", "codegen:clients": "tsx src/server/scripts/client-codegen.ts",
"seed": "tsx prisma/seed.ts", "seed": "tsx prisma/seed.ts",
"check": "concurrently 'pnpm lint' 'pnpm tsc' 'pnpm prettier . --check'", "check": "concurrently 'pnpm lint' 'pnpm tsc' 'pnpm prettier . --check'",
"test": "pnpm vitest" "test": "pnpm vitest"
@@ -99,7 +100,8 @@
"uuid": "^9.0.0", "uuid": "^9.0.0",
"vite-tsconfig-paths": "^4.2.0", "vite-tsconfig-paths": "^4.2.0",
"zod": "^3.21.4", "zod": "^3.21.4",
"zustand": "^4.3.9" "zustand": "^4.3.9",
"openpipe": "workspace:*"
}, },
"devDependencies": { "devDependencies": {
"@openapi-contrib/openapi-schema-to-json-schema": "^4.0.5", "@openapi-contrib/openapi-schema-to-json-schema": "^4.0.5",

View File

@@ -4,19 +4,18 @@ import fs from "fs";
import path from "path"; import path from "path";
import { execSync } from "child_process"; import { execSync } from "child_process";
console.log("Exporting public OpenAPI schema to client-libs/schema.json");
const scriptPath = import.meta.url.replace("file://", ""); const scriptPath = import.meta.url.replace("file://", "");
const clientLibsPath = path.join(path.dirname(scriptPath), "../../../../client-libs"); const clientLibsPath = path.join(path.dirname(scriptPath), "../../../../client-libs");
const schemaPath = path.join(clientLibsPath, "schema.json"); const schemaPath = path.join(clientLibsPath, "openapi.json");
console.log(`Exporting public OpenAPI schema to ${schemaPath}`);
console.log("Exporting schema");
fs.writeFileSync(schemaPath, JSON.stringify(openApiDocument, null, 2), "utf-8"); fs.writeFileSync(schemaPath, JSON.stringify(openApiDocument, null, 2), "utf-8");
console.log("Generating Typescript client"); console.log("Generating TypeScript client");
const tsClientPath = path.join(clientLibsPath, "typescript/codegen"); const tsClientPath = path.join(clientLibsPath, "typescript/src/codegen");
fs.rmSync(tsClientPath, { recursive: true, force: true }); fs.rmSync(tsClientPath, { recursive: true, force: true });
@@ -27,6 +26,8 @@ execSync(
}, },
); );
console.log("Done!"); console.log("Generating Python client");
process.exit(0); execSync(path.join(clientLibsPath, "python/codegen.sh"));
console.log("Done!");

View File

@@ -1,12 +1,10 @@
import { type ClientOptions, default as OriginalOpenAI } from "openai"; import { type ClientOptions } from "openai";
import fs from "fs"; import fs from "fs";
import path from "path"; import path from "path";
import OpenAI from "openpipe/src/openai";
import { env } from "~/env.mjs"; import { env } from "~/env.mjs";
// TODO: use local dependency
// import { OpenAI } from "openpipe";
let config: ClientOptions; let config: ClientOptions;
try { try {
@@ -23,4 +21,4 @@ try {
// export const openai = env.OPENPIPE_API_KEY ? new OpenAI.OpenAI(config) : new OriginalOpenAI(config); // export const openai = env.OPENPIPE_API_KEY ? new OpenAI.OpenAI(config) : new OriginalOpenAI(config);
export const openai = new OriginalOpenAI(config); export const openai = new OpenAI(config);

View File

@@ -25,11 +25,11 @@
".eslintrc.cjs", ".eslintrc.cjs",
"next-env.d.ts", "next-env.d.ts",
"**/*.ts", "**/*.ts",
"**/*.mts",
"**/*.tsx", "**/*.tsx",
"**/*.cjs", "**/*.cjs",
"**/*.mjs", "**/*.mjs",
"**/*.js", "**/*.js"
"src/pages/api/sentry-example-api.js"
], ],
"exclude": ["node_modules"] "exclude": ["node_modules"]
} }

View File

@@ -5,13 +5,21 @@
"description": "The public API for reporting API calls to OpenPipe", "description": "The public API for reporting API calls to OpenPipe",
"version": "0.1.0" "version": "0.1.0"
}, },
"servers": [{ "url": "https://app.openpipe.ai/api" }], "servers": [
{
"url": "https://app.openpipe.ai/api"
}
],
"paths": { "paths": {
"/v1/check-cache": { "/v1/check-cache": {
"post": { "post": {
"operationId": "externalApi-checkCache", "operationId": "externalApi-checkCache",
"description": "Check if a prompt is cached", "description": "Check if a prompt is cached",
"security": [{ "Authorization": [] }], "security": [
{
"Authorization": []
}
],
"requestBody": { "requestBody": {
"required": true, "required": true,
"content": { "content": {
@@ -19,18 +27,24 @@
"schema": { "schema": {
"type": "object", "type": "object",
"properties": { "properties": {
"startTime": { "requestedAt": {
"type": "number", "type": "number",
"description": "Unix timestamp in milliseconds" "description": "Unix timestamp in milliseconds"
}, },
"reqPayload": { "description": "JSON-encoded request payload" }, "reqPayload": {
"description": "JSON-encoded request payload"
},
"tags": { "tags": {
"type": "object", "type": "object",
"additionalProperties": { "type": "string" }, "additionalProperties": {
"type": "string"
},
"description": "Extra tags to attach to the call for filtering. Eg { \"userId\": \"123\", \"promptId\": \"populate-title\" }" "description": "Extra tags to attach to the call for filtering. Eg { \"userId\": \"123\", \"promptId\": \"populate-title\" }"
} }
}, },
"required": ["startTime"], "required": [
"requestedAt"
],
"additionalProperties": false "additionalProperties": false
} }
} }
@@ -45,14 +59,18 @@
"schema": { "schema": {
"type": "object", "type": "object",
"properties": { "properties": {
"respPayload": { "description": "JSON-encoded response payload" } "respPayload": {
"description": "JSON-encoded response payload"
}
}, },
"additionalProperties": false "additionalProperties": false
} }
} }
} }
}, },
"default": { "$ref": "#/components/responses/error" } "default": {
"$ref": "#/components/responses/error"
}
} }
} }
}, },
@@ -60,7 +78,11 @@
"post": { "post": {
"operationId": "externalApi-report", "operationId": "externalApi-report",
"description": "Report an API call", "description": "Report an API call",
"security": [{ "Authorization": [] }], "security": [
{
"Authorization": []
}
],
"requestBody": { "requestBody": {
"required": true, "required": true,
"content": { "content": {
@@ -68,22 +90,40 @@
"schema": { "schema": {
"type": "object", "type": "object",
"properties": { "properties": {
"startTime": { "requestedAt": {
"type": "number", "type": "number",
"description": "Unix timestamp in milliseconds" "description": "Unix timestamp in milliseconds"
}, },
"endTime": { "type": "number", "description": "Unix timestamp in milliseconds" }, "receivedAt": {
"reqPayload": { "description": "JSON-encoded request payload" }, "type": "number",
"respPayload": { "description": "JSON-encoded response payload" }, "description": "Unix timestamp in milliseconds"
"respStatus": { "type": "number", "description": "HTTP status code of response" }, },
"error": { "type": "string", "description": "User-friendly error message" }, "reqPayload": {
"description": "JSON-encoded request payload"
},
"respPayload": {
"description": "JSON-encoded response payload"
},
"statusCode": {
"type": "number",
"description": "HTTP status code of response"
},
"errorMessage": {
"type": "string",
"description": "User-friendly error message"
},
"tags": { "tags": {
"type": "object", "type": "object",
"additionalProperties": { "type": "string" }, "additionalProperties": {
"type": "string"
},
"description": "Extra tags to attach to the call for filtering. Eg { \"userId\": \"123\", \"promptId\": \"populate-title\" }" "description": "Extra tags to attach to the call for filtering. Eg { \"userId\": \"123\", \"promptId\": \"populate-title\" }"
} }
}, },
"required": ["startTime", "endTime"], "required": [
"requestedAt",
"receivedAt"
],
"additionalProperties": false "additionalProperties": false
} }
} }
@@ -93,15 +133,26 @@
"responses": { "responses": {
"200": { "200": {
"description": "Successful response", "description": "Successful response",
"content": { "application/json": { "schema": {} } } "content": {
"application/json": {
"schema": {}
}
}
}, },
"default": { "$ref": "#/components/responses/error" } "default": {
"$ref": "#/components/responses/error"
}
} }
} }
} }
}, },
"components": { "components": {
"securitySchemes": { "Authorization": { "type": "http", "scheme": "bearer" } }, "securitySchemes": {
"Authorization": {
"type": "http",
"scheme": "bearer"
}
},
"responses": { "responses": {
"error": { "error": {
"description": "Error response", "description": "Error response",
@@ -110,19 +161,32 @@
"schema": { "schema": {
"type": "object", "type": "object",
"properties": { "properties": {
"message": { "type": "string" }, "message": {
"code": { "type": "string" }, "type": "string"
},
"code": {
"type": "string"
},
"issues": { "issues": {
"type": "array", "type": "array",
"items": { "items": {
"type": "object", "type": "object",
"properties": { "message": { "type": "string" } }, "properties": {
"required": ["message"], "message": {
"type": "string"
}
},
"required": [
"message"
],
"additionalProperties": false "additionalProperties": false
} }
} }
}, },
"required": ["message", "code"], "required": [
"message",
"code"
],
"additionalProperties": false "additionalProperties": false
} }
} }
@@ -130,4 +194,4 @@
} }
} }
} }
} }

View File

@@ -4,7 +4,7 @@ set -e
cd "$(dirname "$0")" cd "$(dirname "$0")"
poetry run openapi-python-client generate --url http://localhost:3000/api/openapi.json poetry run openapi-python-client generate --path ../openapi.json
rm -rf openpipe/api_client rm -rf openpipe/api_client
mv open-pipe-api-client/open_pipe_api_client openpipe/api_client mv open-pipe-api-client/open_pipe_api_client openpipe/api_client

View File

@@ -1,2 +1,2 @@
node_modules node_modules/
dist dist/

View File

@@ -1,90 +0,0 @@
import * as openPipeClient from "../codegen";
import * as openai from "openai-legacy";
import { version } from "../package.json";
// Anything we don't override we want to pass through to openai directly
export * as openAILegacy from "openai-legacy";
type OPConfigurationParameters = {
apiKey?: string;
basePath?: string;
};
export class Configuration extends openai.Configuration {
public qkConfig?: openPipeClient.Configuration;
constructor(
config: openai.ConfigurationParameters & {
opParameters?: OPConfigurationParameters;
}
) {
super(config);
if (config.opParameters) {
this.qkConfig = new openPipeClient.Configuration(config.opParameters);
}
}
}
type CreateChatCompletion = InstanceType<
typeof openai.OpenAIApi
>["createChatCompletion"];
export class OpenAIApi extends openai.OpenAIApi {
public openPipeApi?: openPipeClient.DefaultApi;
constructor(config: Configuration) {
super(config);
if (config.qkConfig) {
this.openPipeApi = new openPipeClient.DefaultApi(config.qkConfig);
}
}
public async createChatCompletion(
createChatCompletionRequest: Parameters<CreateChatCompletion>[0],
options?: Parameters<CreateChatCompletion>[1]
): ReturnType<CreateChatCompletion> {
const requestedAt = Date.now();
let resp: Awaited<ReturnType<CreateChatCompletion>> | null = null;
let respPayload: openai.CreateChatCompletionResponse | null = null;
let statusCode: number | undefined = undefined;
let errorMessage: string | undefined;
try {
resp = await super.createChatCompletion(
createChatCompletionRequest,
options
);
respPayload = resp.data;
statusCode = resp.status;
} catch (err) {
console.error("Error in createChatCompletion");
if ("isAxiosError" in err && err.isAxiosError) {
errorMessage = err.response?.data?.error?.message;
respPayload = err.response?.data;
statusCode = err.response?.status;
} else if ("message" in err) {
errorMessage = err.message.toString();
}
throw err;
} finally {
this.openPipeApi
?.externalApiReport({
requestedAt,
receivedAt: Date.now(),
reqPayload: createChatCompletionRequest,
respPayload: respPayload,
statusCode: statusCode,
errorMessage,
tags: {
client: "openai-js",
clientVersion: version,
},
})
.catch((err) => {
console.error("Error reporting to OP", err);
});
}
console.log("done");
return resp;
}
}

View File

@@ -1,15 +1,16 @@
{ {
"name": "openpipe", "name": "openpipe",
"version": "0.1.0", "version": "0.1.0",
"type": "module",
"description": "Metrics and auto-evaluation for LLM calls", "description": "Metrics and auto-evaluation for LLM calls",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1" "build": "tsc"
}, },
"main": "dist/index.js", "main": "dist/index.js",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",
"keywords": [], "keywords": [],
"author": "", "author": "",
"license": "ISC", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"axios": "^0.26.0", "axios": "^0.26.0",
"openai-beta": "npm:openai@4.0.0-beta.7", "openai-beta": "npm:openai@4.0.0-beta.7",

View File

@@ -1,548 +0,0 @@
lockfileVersion: '6.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
dependencies:
axios:
specifier: ^0.26.0
version: 0.26.0
openai-beta:
specifier: npm:openai@4.0.0-beta.7
version: /openai@4.0.0-beta.7
openai-legacy:
specifier: npm:openai@3.3.0
version: /openai@3.3.0
devDependencies:
'@types/node':
specifier: ^20.4.8
version: 20.4.8
dotenv:
specifier: ^16.3.1
version: 16.3.1
tsx:
specifier: ^3.12.7
version: 3.12.7
typescript:
specifier: ^5.0.4
version: 5.0.4
packages:
/@esbuild-kit/cjs-loader@2.4.2:
resolution: {integrity: sha512-BDXFbYOJzT/NBEtp71cvsrGPwGAMGRB/349rwKuoxNSiKjPraNNnlK6MIIabViCjqZugu6j+xeMDlEkWdHHJSg==}
dependencies:
'@esbuild-kit/core-utils': 3.1.0
get-tsconfig: 4.6.2
dev: true
/@esbuild-kit/core-utils@3.1.0:
resolution: {integrity: sha512-Uuk8RpCg/7fdHSceR1M6XbSZFSuMrxcePFuGgyvsBn+u339dk5OeL4jv2EojwTN2st/unJGsVm4qHWjWNmJ/tw==}
dependencies:
esbuild: 0.17.19
source-map-support: 0.5.21
dev: true
/@esbuild-kit/esm-loader@2.5.5:
resolution: {integrity: sha512-Qwfvj/qoPbClxCRNuac1Du01r9gvNOT+pMYtJDapfB1eoGN1YlJ1BixLyL9WVENRx5RXgNLdfYdx/CuswlGhMw==}
dependencies:
'@esbuild-kit/core-utils': 3.1.0
get-tsconfig: 4.6.2
dev: true
/@esbuild/android-arm64@0.17.19:
resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==}
engines: {node: '>=12'}
cpu: [arm64]
os: [android]
requiresBuild: true
dev: true
optional: true
/@esbuild/android-arm@0.17.19:
resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==}
engines: {node: '>=12'}
cpu: [arm]
os: [android]
requiresBuild: true
dev: true
optional: true
/@esbuild/android-x64@0.17.19:
resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==}
engines: {node: '>=12'}
cpu: [x64]
os: [android]
requiresBuild: true
dev: true
optional: true
/@esbuild/darwin-arm64@0.17.19:
resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==}
engines: {node: '>=12'}
cpu: [arm64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/@esbuild/darwin-x64@0.17.19:
resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==}
engines: {node: '>=12'}
cpu: [x64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/@esbuild/freebsd-arm64@0.17.19:
resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==}
engines: {node: '>=12'}
cpu: [arm64]
os: [freebsd]
requiresBuild: true
dev: true
optional: true
/@esbuild/freebsd-x64@0.17.19:
resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==}
engines: {node: '>=12'}
cpu: [x64]
os: [freebsd]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-arm64@0.17.19:
resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==}
engines: {node: '>=12'}
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-arm@0.17.19:
resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==}
engines: {node: '>=12'}
cpu: [arm]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-ia32@0.17.19:
resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==}
engines: {node: '>=12'}
cpu: [ia32]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-loong64@0.17.19:
resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==}
engines: {node: '>=12'}
cpu: [loong64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-mips64el@0.17.19:
resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==}
engines: {node: '>=12'}
cpu: [mips64el]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-ppc64@0.17.19:
resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==}
engines: {node: '>=12'}
cpu: [ppc64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-riscv64@0.17.19:
resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==}
engines: {node: '>=12'}
cpu: [riscv64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-s390x@0.17.19:
resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==}
engines: {node: '>=12'}
cpu: [s390x]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/linux-x64@0.17.19:
resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==}
engines: {node: '>=12'}
cpu: [x64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@esbuild/netbsd-x64@0.17.19:
resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==}
engines: {node: '>=12'}
cpu: [x64]
os: [netbsd]
requiresBuild: true
dev: true
optional: true
/@esbuild/openbsd-x64@0.17.19:
resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==}
engines: {node: '>=12'}
cpu: [x64]
os: [openbsd]
requiresBuild: true
dev: true
optional: true
/@esbuild/sunos-x64@0.17.19:
resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==}
engines: {node: '>=12'}
cpu: [x64]
os: [sunos]
requiresBuild: true
dev: true
optional: true
/@esbuild/win32-arm64@0.17.19:
resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==}
engines: {node: '>=12'}
cpu: [arm64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@esbuild/win32-ia32@0.17.19:
resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==}
engines: {node: '>=12'}
cpu: [ia32]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@esbuild/win32-x64@0.17.19:
resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==}
engines: {node: '>=12'}
cpu: [x64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@types/node-fetch@2.6.4:
resolution: {integrity: sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==}
dependencies:
'@types/node': 20.4.8
form-data: 3.0.1
dev: false
/@types/node@18.17.3:
resolution: {integrity: sha512-2x8HWtFk0S99zqVQABU9wTpr8wPoaDHZUcAkoTKH+nL7kPv3WUI9cRi/Kk5Mz4xdqXSqTkKP7IWNoQQYCnDsTA==}
dev: false
/@types/node@20.4.8:
resolution: {integrity: sha512-0mHckf6D2DiIAzh8fM8f3HQCvMKDpK94YQ0DSVkfWTG9BZleYIWudw9cJxX8oCk9bM+vAkDyujDV6dmKHbvQpg==}
/abort-controller@3.0.0:
resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
engines: {node: '>=6.5'}
dependencies:
event-target-shim: 5.0.1
dev: false
/agentkeepalive@4.5.0:
resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==}
engines: {node: '>= 8.0.0'}
dependencies:
humanize-ms: 1.2.1
dev: false
/asynckit@0.4.0:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
dev: false
/axios@0.26.0:
resolution: {integrity: sha512-lKoGLMYtHvFrPVt3r+RBMp9nh34N0M8zEfCWqdWZx6phynIEhQqAdydpyBAAG211zlhX9Rgu08cOamy6XjE5Og==}
dependencies:
follow-redirects: 1.15.2
transitivePeerDependencies:
- debug
dev: false
/base-64@0.1.0:
resolution: {integrity: sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA==}
dev: false
/buffer-from@1.1.2:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
dev: true
/charenc@0.0.2:
resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==}
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
/crypt@0.0.2:
resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==}
dev: false
/delayed-stream@1.0.0:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
engines: {node: '>=0.4.0'}
dev: false
/digest-fetch@1.3.0:
resolution: {integrity: sha512-CGJuv6iKNM7QyZlM2T3sPAdZWd/p9zQiRNS9G+9COUCwzWFTs0Xp8NF5iePx7wtvhDykReiRRrSeNb4oMmB8lA==}
dependencies:
base-64: 0.1.0
md5: 2.3.0
dev: false
/dotenv@16.3.1:
resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==}
engines: {node: '>=12'}
dev: true
/esbuild@0.17.19:
resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==}
engines: {node: '>=12'}
hasBin: true
requiresBuild: true
optionalDependencies:
'@esbuild/android-arm': 0.17.19
'@esbuild/android-arm64': 0.17.19
'@esbuild/android-x64': 0.17.19
'@esbuild/darwin-arm64': 0.17.19
'@esbuild/darwin-x64': 0.17.19
'@esbuild/freebsd-arm64': 0.17.19
'@esbuild/freebsd-x64': 0.17.19
'@esbuild/linux-arm': 0.17.19
'@esbuild/linux-arm64': 0.17.19
'@esbuild/linux-ia32': 0.17.19
'@esbuild/linux-loong64': 0.17.19
'@esbuild/linux-mips64el': 0.17.19
'@esbuild/linux-ppc64': 0.17.19
'@esbuild/linux-riscv64': 0.17.19
'@esbuild/linux-s390x': 0.17.19
'@esbuild/linux-x64': 0.17.19
'@esbuild/netbsd-x64': 0.17.19
'@esbuild/openbsd-x64': 0.17.19
'@esbuild/sunos-x64': 0.17.19
'@esbuild/win32-arm64': 0.17.19
'@esbuild/win32-ia32': 0.17.19
'@esbuild/win32-x64': 0.17.19
dev: true
/event-target-shim@5.0.1:
resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
engines: {node: '>=6'}
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-encoder@1.7.2:
resolution: {integrity: sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==}
dev: false
/form-data@3.0.1:
resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==}
engines: {node: '>= 6'}
dependencies:
asynckit: 0.4.0
combined-stream: 1.0.8
mime-types: 2.1.35
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
/formdata-node@4.4.1:
resolution: {integrity: sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==}
engines: {node: '>= 12.20'}
dependencies:
node-domexception: 1.0.0
web-streams-polyfill: 4.0.0-beta.3
dev: false
/fsevents@2.3.2:
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
requiresBuild: true
dev: true
optional: true
/get-tsconfig@4.6.2:
resolution: {integrity: sha512-E5XrT4CbbXcXWy+1jChlZmrmCwd5KGx502kDCXJJ7y898TtWW9FwoG5HfOLVRKmlmDGkWN2HM9Ho+/Y8F0sJDg==}
dependencies:
resolve-pkg-maps: 1.0.0
dev: true
/humanize-ms@1.2.1:
resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==}
dependencies:
ms: 2.1.3
dev: false
/is-buffer@1.1.6:
resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==}
dev: false
/md5@2.3.0:
resolution: {integrity: sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==}
dependencies:
charenc: 0.0.2
crypt: 0.0.2
is-buffer: 1.1.6
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
/ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
dev: false
/node-domexception@1.0.0:
resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
engines: {node: '>=10.5.0'}
dev: false
/node-fetch@2.6.12:
resolution: {integrity: sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==}
engines: {node: 4.x || >=6.0.0}
peerDependencies:
encoding: ^0.1.0
peerDependenciesMeta:
encoding:
optional: true
dependencies:
whatwg-url: 5.0.0
dev: false
/openai@3.3.0:
resolution: {integrity: sha512-uqxI/Au+aPRnsaQRe8CojU0eCR7I0mBiKjD3sNMzY6DaC1ZVrc85u98mtJW6voDug8fgGN+DIZmTDxTthxb7dQ==}
dependencies:
axios: 0.26.0
form-data: 4.0.0
transitivePeerDependencies:
- debug
dev: false
/openai@4.0.0-beta.7:
resolution: {integrity: sha512-jHjwvpMuGkNxiQ3erwLZsOvPEhcVrMtwtfNeYmGCjhbdB+oStVw/7pIhIPkualu8rlhLwgMR7awknIaN3IQcOA==}
dependencies:
'@types/node': 18.17.3
'@types/node-fetch': 2.6.4
abort-controller: 3.0.0
agentkeepalive: 4.5.0
digest-fetch: 1.3.0
form-data-encoder: 1.7.2
formdata-node: 4.4.1
node-fetch: 2.6.12
transitivePeerDependencies:
- encoding
dev: false
/resolve-pkg-maps@1.0.0:
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
dev: true
/source-map-support@0.5.21:
resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
dependencies:
buffer-from: 1.1.2
source-map: 0.6.1
dev: true
/source-map@0.6.1:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'}
dev: true
/tr46@0.0.3:
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
dev: false
/tsx@3.12.7:
resolution: {integrity: sha512-C2Ip+jPmqKd1GWVQDvz/Eyc6QJbGfE7NrR3fx5BpEHMZsEHoIxHL1j+lKdGobr8ovEyqeNkPLSKp6SCSOt7gmw==}
hasBin: true
dependencies:
'@esbuild-kit/cjs-loader': 2.4.2
'@esbuild-kit/core-utils': 3.1.0
'@esbuild-kit/esm-loader': 2.5.5
optionalDependencies:
fsevents: 2.3.2
dev: true
/typescript@5.0.4:
resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==}
engines: {node: '>=12.20'}
hasBin: true
dev: true
/web-streams-polyfill@4.0.0-beta.3:
resolution: {integrity: sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==}
engines: {node: '>= 14'}
dev: false
/webidl-conversions@3.0.1:
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
dev: false
/whatwg-url@5.0.0:
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
dependencies:
tr46: 0.0.3
webidl-conversions: 3.0.1
dev: false

View File

@@ -176,6 +176,10 @@ export const DefaultApiAxiosParamCreator = function (configuration?: Configurati
const localVarHeaderParameter = {} as any; const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any; const localVarQueryParameter = {} as any;
// authentication Authorization required
// http bearer authentication required
await setBearerAuthToObject(localVarHeaderParameter, configuration)
localVarHeaderParameter['Content-Type'] = 'application/json'; localVarHeaderParameter['Content-Type'] = 'application/json';
@@ -211,6 +215,10 @@ export const DefaultApiAxiosParamCreator = function (configuration?: Configurati
const localVarHeaderParameter = {} as any; const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any; const localVarQueryParameter = {} as any;
// authentication Authorization required
// http bearer authentication required
await setBearerAuthToObject(localVarHeaderParameter, configuration)
localVarHeaderParameter['Content-Type'] = 'application/json'; localVarHeaderParameter['Content-Type'] = 'application/json';

View File

@@ -0,0 +1,90 @@
// import * as openPipeClient from "../codegen";
// import * as openai from "openai-legacy";
// import { version } from "../package.json";
// // Anything we don't override we want to pass through to openai directly
// export * as openAILegacy from "openai-legacy";
// type OPConfigurationParameters = {
// apiKey?: string;
// basePath?: string;
// };
// export class Configuration extends openai.Configuration {
// public qkConfig?: openPipeClient.Configuration;
// constructor(
// config: openai.ConfigurationParameters & {
// opParameters?: OPConfigurationParameters;
// }
// ) {
// super(config);
// if (config.opParameters) {
// this.qkConfig = new openPipeClient.Configuration(config.opParameters);
// }
// }
// }
// type CreateChatCompletion = InstanceType<
// typeof openai.OpenAIApi
// >["createChatCompletion"];
// export class OpenAIApi extends openai.OpenAIApi {
// public openPipeApi?: openPipeClient.DefaultApi;
// constructor(config: Configuration) {
// super(config);
// if (config.qkConfig) {
// this.openPipeApi = new openPipeClient.DefaultApi(config.qkConfig);
// }
// }
// public async createChatCompletion(
// createChatCompletionRequest: Parameters<CreateChatCompletion>[0],
// options?: Parameters<CreateChatCompletion>[1]
// ): ReturnType<CreateChatCompletion> {
// const requestedAt = Date.now();
// let resp: Awaited<ReturnType<CreateChatCompletion>> | null = null;
// let respPayload: openai.CreateChatCompletionResponse | null = null;
// let statusCode: number | undefined = undefined;
// let errorMessage: string | undefined;
// try {
// resp = await super.createChatCompletion(
// createChatCompletionRequest,
// options
// );
// respPayload = resp.data;
// statusCode = resp.status;
// } catch (err) {
// console.error("Error in createChatCompletion");
// if ("isAxiosError" in err && err.isAxiosError) {
// errorMessage = err.response?.data?.error?.message;
// respPayload = err.response?.data;
// statusCode = err.response?.status;
// } else if ("message" in err) {
// errorMessage = err.message.toString();
// }
// throw err;
// } finally {
// this.openPipeApi
// ?.externalApiReport({
// requestedAt,
// receivedAt: Date.now(),
// reqPayload: createChatCompletionRequest,
// respPayload: respPayload,
// statusCode: statusCode,
// errorMessage,
// tags: {
// client: "openai-js",
// clientVersion: version,
// },
// })
// .catch((err) => {
// console.error("Error reporting to OP", err);
// });
// }
// console.log("done");
// return resp;
// }
// }

View File

@@ -3,7 +3,6 @@ import { readEnv, type RequestOptions } from "openai-beta/core";
import { CompletionCreateParams } from "openai-beta/resources/chat/completions"; import { CompletionCreateParams } from "openai-beta/resources/chat/completions";
import axios from "axios"; import axios from "axios";
export * as openai from "openai-beta";
import * as openPipeClient from "../codegen"; import * as openPipeClient from "../codegen";
interface ClientOptions extends openai.ClientOptions { interface ClientOptions extends openai.ClientOptions {
@@ -11,7 +10,7 @@ interface ClientOptions extends openai.ClientOptions {
openPipeBaseUrl?: string; openPipeBaseUrl?: string;
} }
export class OpenAI extends openai.OpenAI { export default class OpenAI extends openai.OpenAI {
public openPipeApi?: openPipeClient.DefaultApi; public openPipeApi?: openPipeClient.DefaultApi;
constructor({ constructor({
@@ -74,37 +73,37 @@ class ExtendedCompletions extends openai.OpenAI.Chat.Completions {
options?: RequestOptions, options?: RequestOptions,
tags?: Record<string, string> tags?: Record<string, string>
): Promise<any> { ): Promise<any> {
// Your pre API call logic here // // Your pre API call logic here
console.log("Doing pre API call..."); // console.log("Doing pre API call...");
// Determine the type of request // // Determine the type of request
if (params.hasOwnProperty("stream") && params.stream === true) { // if (params.hasOwnProperty("stream") && params.stream === true) {
const result = await super.create( // const result = await super.create(
params as CompletionCreateParams.CreateChatCompletionRequestStreaming, // params as CompletionCreateParams.CreateChatCompletionRequestStreaming,
options // options
); // );
// Your post API call logic here // // Your post API call logic here
console.log("Doing post API call for Streaming..."); // console.log("Doing post API call for Streaming...");
return result; // return result;
} else { // } else {
const requestedAt = Date.now(); // const requestedAt = Date.now();
const result = await super.create( const result = await super.create(
params as CompletionCreateParams.CreateChatCompletionRequestNonStreaming, params as CompletionCreateParams.CreateChatCompletionRequestNonStreaming,
options options
); );
await this.openaiInstance.openPipeApi?.externalApiReport({ return result;
requestedAt, // await this.openaiInstance.openPipeApi?.externalApiReport({
receivedAt: Date.now(), // requestedAt,
reqPayload: params, // receivedAt: Date.now(),
respPayload: result, // reqPayload: params,
statusCode: 200, // respPayload: result,
errorMessage: undefined, // statusCode: 200,
tags, // errorMessage: undefined,
}); // tags,
// });
// Your post API call logic here // console.log("GOT RESULT", result);
console.log("Doing post API call for NonStreaming..."); // return result;
return result; // }
}
} }
} }

View File

@@ -1,13 +1,25 @@
{ {
"compilerOptions": { "compilerOptions": {
"declaration": true, "target": "es2017",
"target": "es6", "lib": ["esnext"],
"module": "commonjs", "allowJs": true,
"noImplicitAny": true, "checkJs": true,
"skipLibCheck": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true, "resolveJsonModule": true,
"isolatedModules": true,
"incremental": true,
"noUncheckedIndexedAccess": true,
"baseUrl": ".",
"outDir": "dist", "outDir": "dist",
"rootDir": ".", "paths": {
"skipLibCheck": true "~/*": ["./src/*"]
}
}, },
"exclude": ["dist", "node_modules"], "include": ["src/**/*.ts"],
"exclude": ["node_modules"]
} }

File diff suppressed because it is too large Load Diff

3
pnpm-workspace.yaml Normal file
View File

@@ -0,0 +1,3 @@
packages:
- app
- client-libs/typescript