initial code for working with openrouter

This commit is contained in:
JV 2023-08-15 03:35:55 +12:00 committed by Joshua Vial
parent 8c580dd332
commit 041f3a4a38
11 changed files with 99 additions and 26 deletions

7
aider/models/__init__.py Normal file
View file

@ -0,0 +1,7 @@
from .openai import OpenAIModel
from .openrouter import OpenRouterModel
from .model import Model
GPT4 = Model("gpt-4")
GPT35 = Model("gpt-3.5-turbo")
GPT35_16k = Model("gpt-3.5-turbo-16k")

60
aider/models/model.py Normal file
View file

@ -0,0 +1,60 @@
import importlib
using_openrouter = False
class Model:
name = None
edit_format = None
max_context_tokens = 0
tokenizer = None
always_available = False
use_repo_map = False
send_undo_reply = False
prompt_price = None
completion_price = None
def __init__(self, name, openai=None):
global using_openrouter
if (openai and "openrouter.ai" in openai.api_base):
using_openrouter = True
from .openai import OpenAIModel
from .openrouter import OpenRouterModel
model = None
if using_openrouter:
if name == 'gpt-4':
name = 'openai/gpt-4'
elif name == 'gpt-3.5-turbo':
name = 'openai/gpt-3.5-turbo'
elif name == 'gpt-3.5.turbo-16k':
name = 'openai/gpt-3.5-turbo-16k'
model = OpenRouterModel(name, openai)
else:
model = OpenAIModel(name)
self.name = model.name
self.edit_format = model.edit_format
self.max_context_tokens = model.max_context_tokens
self.tokenizer = model.tokenizer
self.prompt_price = model.prompt_price
self.completion_price = model.completion_price
self.always_available = model.always_available
self.use_repo_map = model.use_repo_map
def __str__(self):
return self.name
@staticmethod
def strong_model():
return Model('gpt-4')
@staticmethod
def weak_model():
return Model('gpt-3.5-turbo')
@staticmethod
def commit_message_models():
return [Model('gpt-3.5-turbo'), Model('gpt-3.5-turbo-16k')]

64
aider/models/openai.py Normal file
View file

@ -0,0 +1,64 @@
import tiktoken
import re
from .model import Model
known_tokens = {
"gpt-3.5-turbo": 4,
"gpt-4": 8,
}
class OpenAIModel(Model):
def __init__(self, name):
self.name = name
tokens = None
match = re.search(r"-([0-9]+)k", name)
if match:
tokens = int(match.group(1))
else:
for m, t in known_tokens.items():
if name.startswith(m):
tokens = t
if tokens is None:
raise ValueError(f"Unknown context window size for model: {name}")
self.max_context_tokens = tokens * 1024
self.tokenizer = tiktoken.encoding_for_model(name)
if self.is_gpt4():
self.edit_format = "diff"
self.use_repo_map = True
self.send_undo_reply = True
if tokens == 8:
self.prompt_price = 0.03
self.completion_price = 0.06
elif tokens == 32:
self.prompt_price = 0.06
self.completion_price = 0.12
return
if self.is_gpt35():
self.edit_format = "whole"
self.always_available = True
if tokens == 4:
self.prompt_price = 0.0015
self.completion_price = 0.002
elif tokens == 16:
self.prompt_price = 0.003
self.completion_price = 0.004
return
raise ValueError(f"Unsupported model: {name}")
def is_gpt4(self):
return self.name.startswith("gpt-4")
def is_gpt35(self):
return self.name.startswith("gpt-3.5-turbo")

View file

@ -0,0 +1,13 @@
import tiktoken
from .model import Model
class OpenRouterModel(Model):
def __init__(self, name, openai):
self.name = name
self.edit_format = "diff"
self.use_repo_map = True
self.max_context_tokens = 1024 * 8
# TODO: figure out proper encodings for non openai models
self.tokenizer = tiktoken.get_encoding("cl100k_base")