Add support for 3rd party openai proxy (#113)

This commit is contained in:
Logan Yang 2023-07-19 18:17:08 -07:00 committed by GitHub
parent 9f27dd3634
commit 6c60863694
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 60 additions and 7 deletions

View file

@ -1,7 +1,7 @@
{
"id": "copilot",
"name": "Copilot",
"version": "2.3.5",
"version": "2.3.6",
"minAppVersion": "0.15.0",
"description": "A ChatGPT Copilot in Obsidian.",
"author": "Logan Yang",

4
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "obsidian-copilot",
"version": "2.3.5",
"version": "2.3.6",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "obsidian-copilot",
"version": "2.3.5",
"version": "2.3.6",
"license": "AGPL-3.0",
"dependencies": {
"@huggingface/inference": "^1.8.0",

View file

@ -1,6 +1,6 @@
{
"name": "obsidian-copilot",
"version": "2.3.5",
"version": "2.3.6",
"description": "ChatGPT integration for Obsidian",
"main": "main.js",
"scripts": {

View file

@ -44,6 +44,7 @@ import { RecursiveCharacterTextSplitter } from "langchain/text_splitter";
import { MemoryVectorStore } from "langchain/vectorstores/memory";
import { Notice } from 'obsidian';
import { useState } from 'react';
import { ProxyChatOpenAI } from './langchainWrappers';
interface ModelConfig {
@ -59,6 +60,7 @@ interface ModelConfig {
azureOpenAIApiInstanceName?: string,
azureOpenAIApiDeploymentName?: string,
azureOpenAIApiVersion?: string,
openAIProxyBaseUrl?: string,
}
export interface LangChainParams {
@ -80,6 +82,7 @@ export interface LangChainParams {
embeddingProvider: string,
chainType: ChainType, // Default ChainType is set in main.ts getAIStateParams
options: SetChainOptions,
openAIProxyBaseUrl?: string,
}
export interface SetChainOptions {
@ -161,6 +164,7 @@ class AIState {
model,
temperature,
maxTokens,
openAIProxyBaseUrl,
} = this.langChainParams;
// Create a base configuration that applies to all models
@ -169,7 +173,7 @@ class AIState {
temperature: temperature,
streaming: true,
maxRetries: 3,
maxConcurrency: 3
maxConcurrency: 3,
};
switch(chatModelProvider) {
@ -178,6 +182,7 @@ class AIState {
...config,
openAIApiKey,
maxTokens,
openAIProxyBaseUrl,
};
break;
case ANTHROPIC:
@ -211,11 +216,14 @@ class AIState {
}
> = {};
const OpenAIChatModel = this.langChainParams.openAIProxyBaseUrl
? ProxyChatOpenAI : ChatOpenAI;
// Build modelMap
for (const modelDisplayNameKey of OPENAI_MODELS) {
modelMap[modelDisplayNameKey] = {
hasApiKey: Boolean(this.langChainParams.openAIApiKey),
AIConstructor: ChatOpenAI,
AIConstructor: OpenAIChatModel,
vendor: OPENAI,
};
}

View file

@ -104,6 +104,7 @@ export const DEFAULT_SETTINGS: CopilotSettings = {
contextTurns: 3,
useNotesAsContext: false,
userSystemPrompt: '',
openAIProxyBaseUrl: '',
stream: true,
embeddingProvider: OPENAI,
debug: false,

18
src/langchainWrappers.ts Normal file
View file

@ -0,0 +1,18 @@
import { ChatOpenAI } from 'langchain/chat_models/openai';
import { Configuration, OpenAIApi } from "openai";
export class ProxyChatOpenAI extends ChatOpenAI {
constructor(
fields?: any,
) {
super(fields ?? {});
const clientConfig = new Configuration({
...this["clientConfig"],
basePath: fields.openAIProxyBaseUrl,
});
// Reinitialize the client with the updated clientConfig
this["client"] = new OpenAIApi(clientConfig);
}
}

View file

@ -32,6 +32,7 @@ export interface CopilotSettings {
contextTurns: number;
useNotesAsContext: boolean;
userSystemPrompt: string;
openAIProxyBaseUrl: string;
stream: boolean;
embeddingProvider: string;
debug: boolean;
@ -471,6 +472,7 @@ export default class CopilotPlugin extends Plugin {
embeddingProvider: embeddingProvider,
chainType: ChainType.LLM_CHAIN, // Set LLM_CHAIN as default ChainType
options: { forceNewCreation: true } as SetChainOptions,
openAIProxyBaseUrl: this.settings.openAIProxyBaseUrl,
};
}
}

View file

@ -422,6 +422,29 @@ export class CopilotSettingTab extends PluginSettingTab {
});
});
new Setting(containerEl)
.setName("OpenAI Proxy Base URL (3rd-party providers)")
.setDesc(
createFragment((frag) => {
frag.createEl(
'strong',
{ text: "CAUTION: This will override the default OpenAI API URL! Use with discretion!" }
);
frag.createEl('br');
frag.appendText("Leave blank to use the official OpenAI API.");
})
)
.addText((text) => {
text.inputEl.style.width = "100%";
text
.setPlaceholder("https://openai.example.com/v1")
.setValue(this.plugin.settings.openAIProxyBaseUrl)
.onChange(async (value) => {
this.plugin.settings.openAIProxyBaseUrl = value;
await this.plugin.saveSettings();
})
});
containerEl.createEl('h4', { text: 'Development mode' });
new Setting(containerEl)

View file

@ -19,5 +19,6 @@
"2.3.2": "0.15.0",
"2.3.3": "0.15.0",
"2.3.4": "0.15.0",
"2.3.5": "0.15.0"
"2.3.5": "0.15.0",
"2.3.6": "0.15.0"
}