Spaces:
Runtime error
Runtime error
Upload 11 files
Browse files- assets/config.json +8 -0
- assets/source/__init__.py +9 -0
- assets/source/addons/__init__.py +12 -0
- assets/source/addons/expose.md +8 -0
- assets/source/addons/expose.py +130 -0
- assets/source/addons/translation.md +10 -0
- assets/source/addons/translation.py +58 -0
- assets/source/api.py +132 -0
- assets/source/headers/__init__.py +3 -0
- assets/source/headers/get_headers.py +21 -0
- assets/templates/index.html +74 -0
assets/config.json
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"HOST": "0.0.0.0",
|
3 |
+
"PORT": 5000,
|
4 |
+
"DEBUG": false,
|
5 |
+
|
6 |
+
"use_global": true,
|
7 |
+
"use_addons": true
|
8 |
+
}
|
assets/source/__init__.py
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from .api import Api, non_streamed_format
|
2 |
+
|
3 |
+
# create api instance
|
4 |
+
api = Api()
|
5 |
+
|
6 |
+
__all__ = [
|
7 |
+
"api",
|
8 |
+
"non_streamed_format"
|
9 |
+
]
|
assets/source/addons/__init__.py
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
All addons should be imported here
|
3 |
+
"""
|
4 |
+
from .translation import translate, message_translation
|
5 |
+
from .expose import create_cloudflare_tunnel
|
6 |
+
|
7 |
+
# here the addons are exported
|
8 |
+
__all__ = [
|
9 |
+
'translate',
|
10 |
+
'message_translation',
|
11 |
+
'create_cloudflare_tunnel'
|
12 |
+
]
|
assets/source/addons/expose.md
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# DeepInfra-Wrapper Addon - Cloudflare Quick-tunnels.
|
2 |
+
|
3 |
+
This addon is needed to globally expose our flask application and create a URL that can be accessed from anywhere.
|
4 |
+
|
5 |
+
## Usage
|
6 |
+
|
7 |
+
To use, call `create_cloudflare_tunnel` function and pass the port as a paremeter. You will then see Cloudflare emit the created ULR inside the console.
|
8 |
+
Remember, you need to have `use_addons` set to `true` in the config.json
|
assets/source/addons/expose.py
ADDED
@@ -0,0 +1,130 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
Code credits: ColabKobold
|
3 |
+
|
4 |
+
https://github.com/lostruins/koboldcpp
|
5 |
+
"""
|
6 |
+
|
7 |
+
import os, sys, threading, time, subprocess, re
|
8 |
+
|
9 |
+
def create_cloudflare_tunnel(port: int):
|
10 |
+
|
11 |
+
"""
|
12 |
+
Create a cloudflare tunnel for the server
|
13 |
+
"""
|
14 |
+
|
15 |
+
try:
|
16 |
+
|
17 |
+
def run_tunnel():
|
18 |
+
|
19 |
+
"""
|
20 |
+
Run the cloudflare tunnel
|
21 |
+
"""
|
22 |
+
|
23 |
+
# variables to be used in the thread
|
24 |
+
tunnel_process = None
|
25 |
+
tunnel_output = ""
|
26 |
+
tunnel_raw_dump = ""
|
27 |
+
|
28 |
+
time.sleep(0.2)
|
29 |
+
if os.name == 'nt':
|
30 |
+
|
31 |
+
print("Starting Cloudflare Tunnel for Windows, please wait...", flush=True)
|
32 |
+
tunnel_process = subprocess.Popen(f"cloudflared.exe tunnel --url localhost:{port}", text=True, encoding='utf-8', shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE)
|
33 |
+
|
34 |
+
elif sys.platform=="darwin":
|
35 |
+
print("Starting Cloudflare Tunnel for MacOS, please wait...", flush=True)
|
36 |
+
tunnel_process = subprocess.Popen(f"./cloudflared tunnel --url http://localhost:{port}", text=True, encoding='utf-8', shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE)
|
37 |
+
|
38 |
+
else:
|
39 |
+
print("Starting Cloudflare Tunnel for Linux, please wait...", flush=True)
|
40 |
+
tunnel_process = subprocess.Popen(f"./cloudflared-linux-amd64 tunnel --url http://localhost:{port}", text=True, encoding='utf-8', shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE)
|
41 |
+
|
42 |
+
# wait for the tunnel to be ready
|
43 |
+
time.sleep(10)
|
44 |
+
|
45 |
+
def tunnel_reader():
|
46 |
+
|
47 |
+
"""
|
48 |
+
Read the stderr of the cloudflare tunnel process
|
49 |
+
"""
|
50 |
+
|
51 |
+
nonlocal tunnel_process, tunnel_output, tunnel_raw_dump
|
52 |
+
|
53 |
+
pattern: str = r'https://[\w\.-]+\.trycloudflare\.com'
|
54 |
+
|
55 |
+
while True:
|
56 |
+
|
57 |
+
line = tunnel_process.stderr.readline() #cloudflare writes to stderr for some reason
|
58 |
+
tunnel_raw_dump += line+"\n"
|
59 |
+
|
60 |
+
if not line:
|
61 |
+
|
62 |
+
# if the line is empty, the tunnel is closed
|
63 |
+
return
|
64 |
+
|
65 |
+
found = re.findall(pattern, line)
|
66 |
+
|
67 |
+
for x in found:
|
68 |
+
|
69 |
+
tunneloutput = x
|
70 |
+
|
71 |
+
return
|
72 |
+
|
73 |
+
tunnel_reader_thread = threading.Thread(target=tunnel_reader)
|
74 |
+
tunnel_reader_thread.start()
|
75 |
+
|
76 |
+
time.sleep(5) # wait for the tunnel to be ready
|
77 |
+
|
78 |
+
if tunnel_output=="":
|
79 |
+
|
80 |
+
print(f"Error: Could not create cloudflare tunnel!\nMore Info:\n{tunnel_raw_dump}", flush=True)
|
81 |
+
|
82 |
+
time.sleep(0.5)
|
83 |
+
tunnel_process.wait()
|
84 |
+
|
85 |
+
# Windows
|
86 |
+
if os.name == 'nt':
|
87 |
+
|
88 |
+
if os.path.exists("cloudflared.exe") and os.path.getsize("cloudflared.exe") > 1000000:
|
89 |
+
|
90 |
+
print("Cloudflared file exists, reusing it...")
|
91 |
+
|
92 |
+
else:
|
93 |
+
|
94 |
+
print("Downloading Cloudflare Tunnel for Windows...")
|
95 |
+
subprocess.run("curl -fL https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-windows-amd64.exe -o cloudflared.exe", shell=True, capture_output=True, text=True, check=True, encoding='utf-8')
|
96 |
+
|
97 |
+
# MacOS
|
98 |
+
elif sys.platform=="darwin":
|
99 |
+
|
100 |
+
if os.path.exists("cloudflared") and os.path.getsize("cloudflared") > 1000000:
|
101 |
+
print("Cloudflared file exists, reusing it...")
|
102 |
+
|
103 |
+
else:
|
104 |
+
|
105 |
+
print("Downloading Cloudflare Tunnel for MacOS...")
|
106 |
+
subprocess.run("curl -fL https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-darwin-amd64.tgz -o cloudflared-darwin-amd64.tgz", shell=True, capture_output=True, text=True, check=True, encoding='utf-8')
|
107 |
+
subprocess.run("tar -xzf cloudflared-darwin-amd64.tgz", shell=True)
|
108 |
+
subprocess.run("chmod +x 'cloudflared'", shell=True)
|
109 |
+
|
110 |
+
else:
|
111 |
+
|
112 |
+
if os.path.exists("cloudflared-linux-amd64") and os.path.getsize("cloudflared-linux-amd64") > 1000000:
|
113 |
+
print("Cloudflared file exists, reusing it...")
|
114 |
+
|
115 |
+
else:
|
116 |
+
|
117 |
+
print("Downloading Cloudflare Tunnel for Linux...")
|
118 |
+
subprocess.run("curl -fL https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 -o cloudflared-linux-amd64", shell=True, capture_output=True, text=True, check=True, encoding='utf-8')
|
119 |
+
subprocess.run("chmod +x 'cloudflared-linux-amd64'", shell=True)
|
120 |
+
|
121 |
+
print("Attempting to start tunnel thread...", flush=True)
|
122 |
+
tunnel_thread = threading.Thread(target=run_tunnel)
|
123 |
+
tunnel_thread.start()
|
124 |
+
|
125 |
+
except Exception as ex:
|
126 |
+
|
127 |
+
print("Remote Tunnel Failed!")
|
128 |
+
print(str(ex))
|
129 |
+
return None
|
130 |
+
|
assets/source/addons/translation.md
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# DeepInfra-Wrapper Addon - Translation
|
2 |
+
|
3 |
+
This addon is used to translate OpenAI model names to the actual model names. The names are semi-random.
|
4 |
+
|
5 |
+
## Usage
|
6 |
+
|
7 |
+
To use this addon, you can call the `translate` function with a model name as the input. The function will return the corresponding actual model name.
|
8 |
+
Remember, you need to have `use_addons` set to `true` in the config.json
|
9 |
+
|
10 |
+
For regular use cases, turn this off.
|
assets/source/addons/translation.py
ADDED
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"""
|
2 |
+
This addon is used to make OpenAI model names point to one of these models. The names are semi-random picked.
|
3 |
+
"""
|
4 |
+
|
5 |
+
model_map = [
|
6 |
+
{"gpt-4-0613": "mistralai/Mistral-7B-Instruct-v0.3"},
|
7 |
+
{"davinci-002": ""},
|
8 |
+
{"gpt-4": "microsoft/WizardLM-2-8x22B"},
|
9 |
+
{"gpt-4o": "mistralai/Mistral-7B-Instruct-v0.2"},
|
10 |
+
{"gpt-4-0125-preview": "mistralai/Mixtral-8x7B-Instruct-v0.1"},
|
11 |
+
{"gpt-4-turbo-preview": "mistralai/Mixtral-8x22B-Instruct-v0.1"},
|
12 |
+
{"gpt-4-1106-preview": "cognitivecomputations/dolphin-2.6-mixtral-8x7b"},
|
13 |
+
{"gpt-3.5-turbo-16k": "meta-llama/Meta-Llama-3-8B-Instruct"},
|
14 |
+
{"gpt-3.5-turbo-instruct-0914": "meta-llama/Meta-Llama-3-70B-Instruct"},
|
15 |
+
]
|
16 |
+
|
17 |
+
def translate(model: str) -> str:
|
18 |
+
|
19 |
+
"""
|
20 |
+
Translate model names to the actual model names
|
21 |
+
"""
|
22 |
+
|
23 |
+
for i in model_map:
|
24 |
+
if model in i:
|
25 |
+
return i[model]
|
26 |
+
|
27 |
+
return model
|
28 |
+
|
29 |
+
def message_translation(messages: list[dict[str, str]]) -> list[dict[str, str]]:
|
30 |
+
|
31 |
+
"""
|
32 |
+
Translate messages
|
33 |
+
|
34 |
+
Current Message format
|
35 |
+
|
36 |
+
messages = [{"role": "user", "content": "Whatever"}]
|
37 |
+
|
38 |
+
Old format:
|
39 |
+
|
40 |
+
messages = [{"role": "user", "content": [{"text": "Whatever"}]}]
|
41 |
+
|
42 |
+
:param messages: list of messages
|
43 |
+
|
44 |
+
:return: list of messages
|
45 |
+
"""
|
46 |
+
translated_messages = []
|
47 |
+
|
48 |
+
for message in messages:
|
49 |
+
# Check if the message content is in the old format
|
50 |
+
if isinstance(message['content'], list):
|
51 |
+
# Extract the text from the old format and assign it to the new format
|
52 |
+
content = message['content'][0]['text']
|
53 |
+
message['content'] = content
|
54 |
+
|
55 |
+
# Append the message to the list of translated messages
|
56 |
+
translated_messages.append(message)
|
57 |
+
|
58 |
+
return translated_messages
|
assets/source/api.py
ADDED
@@ -0,0 +1,132 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# ---------------------------------------- IMPORTS ---------------------------------------- #
|
2 |
+
|
3 |
+
# this module allows us to get the headers from the get_headers function
|
4 |
+
from .headers.get_headers import get_headers
|
5 |
+
|
6 |
+
# this module allows us to get a random user agent
|
7 |
+
from fake_useragent import UserAgent
|
8 |
+
|
9 |
+
# this module allows us to generate random numbers
|
10 |
+
import secrets
|
11 |
+
|
12 |
+
# to make requests
|
13 |
+
import requests
|
14 |
+
|
15 |
+
# type hints
|
16 |
+
from typing import Generator, Any, Dict, List
|
17 |
+
|
18 |
+
# ---------------------------------------- FUNCTIONS ---------------------------------------- #
|
19 |
+
def non_streamed_format(model: str, content: str) -> Dict[str, Any]:
|
20 |
+
|
21 |
+
return {
|
22 |
+
"object": "chat.completion",
|
23 |
+
"model": f"{model}",
|
24 |
+
"choices": [{
|
25 |
+
"index": 0,
|
26 |
+
"message": {
|
27 |
+
"role": "assistant",
|
28 |
+
"content": f"{content}",
|
29 |
+
},
|
30 |
+
"finish_reason": "stop",
|
31 |
+
}],
|
32 |
+
}
|
33 |
+
# ---------------------------------------- API CLASS ---------------------------------------- #
|
34 |
+
|
35 |
+
class Api(object):
|
36 |
+
|
37 |
+
# initialize the class and set some variables here
|
38 |
+
def __init__(self) -> None:
|
39 |
+
|
40 |
+
"""initialize the class"""
|
41 |
+
|
42 |
+
self.url: str = "https://api.deepinfra.com/v1/openai/chat/completions"
|
43 |
+
|
44 |
+
self.headers = get_headers(UserAgent().random, secrets.randbelow(500)) # get random headers
|
45 |
+
|
46 |
+
self.session = requests.Session() # create a session
|
47 |
+
|
48 |
+
# codec for encoding and decoding
|
49 |
+
self.codec = 'utf-8'
|
50 |
+
|
51 |
+
def get_models(self) -> Dict[str, List[Dict[str, str]]]:
|
52 |
+
|
53 |
+
"""get all models"""
|
54 |
+
|
55 |
+
return {'data': [
|
56 |
+
{"id": "meta-llama/Meta-Llama-3-70B-Instruct", "context": 8192},
|
57 |
+
{"id": "meta-llama/Meta-Llama-3-8B-Instruct", "context": 8192},
|
58 |
+
{"id": "codellama/CodeLlama-34b-Instruct-hf", "context": 4096},
|
59 |
+
{"id": "jondurbin/airoboros-l2-70b-gpt4-1.4.1", "context": 4096},
|
60 |
+
{"id": "mistralai/Mistral-7B-Instruct-v0.2", "context": 32768},
|
61 |
+
{"id": "mistralai/Mistral-7B-Instruct-v0.3", "context": 32768},
|
62 |
+
{"id": "mistralai/Mixtral-8x7B-Instruct-v0.1", "context": 32768},
|
63 |
+
{"id": "mistralai/Mixtral-8x22B-Instruct-v0.1", "context": 65536},
|
64 |
+
{"id": "cognitivecomputations/dolphin-2.6-mixtral-8x7b", "context": 32768},
|
65 |
+
{"id": "lizpreciatior/lzlv_70b_fp16_hf", "context": 32768},
|
66 |
+
{"id": "deepinfra/airoboros-70b", "context": 4096},
|
67 |
+
{"id": "HuggingFaceH4/zephyr-orpo-141b-A35b-v0.1", "context": 65536},
|
68 |
+
{"id": "microsoft/WizardLM-2-8x22B", "context": 65536},
|
69 |
+
]}
|
70 |
+
|
71 |
+
|
72 |
+
def chat(
|
73 |
+
self,
|
74 |
+
messages: List[Dict[str, str]],
|
75 |
+
model: str,
|
76 |
+
stream: bool = True,
|
77 |
+
temperature: int = 0.7,
|
78 |
+
max_tokens: int = 150,
|
79 |
+
top_p: float = 1.0,
|
80 |
+
top_k: int = 50,
|
81 |
+
presence_penalty: float = 0.0,
|
82 |
+
frequency_penalty: float = 0.0
|
83 |
+
) -> Generator[str, Any, Any] | Dict[str, Any]:
|
84 |
+
|
85 |
+
"""
|
86 |
+
Chat with the DeepInfra models.
|
87 |
+
|
88 |
+
:param messages: list of messages
|
89 |
+
:param model: model name
|
90 |
+
|
91 |
+
:param stream: stream the response
|
92 |
+
:param temperature: temperature
|
93 |
+
:param max_tokens: max tokens
|
94 |
+
|
95 |
+
:param top_p: top p
|
96 |
+
:param top_k: top k
|
97 |
+
|
98 |
+
:param presence_penalty: presence penalty
|
99 |
+
:param frequency_penalty: frequency penalty
|
100 |
+
|
101 |
+
:return: generator or dict
|
102 |
+
"""
|
103 |
+
|
104 |
+
# compile the data
|
105 |
+
data = {
|
106 |
+
'messages': messages,
|
107 |
+
'model': model,
|
108 |
+
'stream': stream,
|
109 |
+
|
110 |
+
'temperature': temperature,
|
111 |
+
'max_tokens': max_tokens,
|
112 |
+
|
113 |
+
'top_p': top_p,
|
114 |
+
'top_k': top_k,
|
115 |
+
|
116 |
+
'presence_penalty': presence_penalty,
|
117 |
+
'frequency_penalty': frequency_penalty,
|
118 |
+
}
|
119 |
+
|
120 |
+
# make a post request to the api
|
121 |
+
response = self.session.post(self.url, headers=self.headers, json=data, stream=stream)
|
122 |
+
|
123 |
+
# raise for status
|
124 |
+
response.raise_for_status()
|
125 |
+
|
126 |
+
# if stream is False
|
127 |
+
if not stream:
|
128 |
+
return non_streamed_format(model, response.json()['choices'][0]['message']['content'])
|
129 |
+
|
130 |
+
return response.iter_lines()
|
131 |
+
|
132 |
+
# Path: assets/source/api.py
|
assets/source/headers/__init__.py
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
from .get_headers import get_headers
|
2 |
+
|
3 |
+
__all__ = ['get_headers']
|
assets/source/headers/get_headers.py
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
def get_headers(user_agent: str, content_length: int):
|
2 |
+
|
3 |
+
return {
|
4 |
+
'Authority': 'api.deepinfra.com',
|
5 |
+
'Host': 'api.deepinfra.com',
|
6 |
+
'User-Agent': f'{user_agent}',
|
7 |
+
'Accept': 'text/event-stream',
|
8 |
+
'Accept-Language': 'en-US,en;q=0.5',
|
9 |
+
'Accept-Encoding': 'gzip, deflate, br',
|
10 |
+
'Referer': 'https://deepinfra.com/',
|
11 |
+
'Content-Type': 'application/json',
|
12 |
+
'X-Deepinfra-Source': 'web-page',
|
13 |
+
'Content-Length': f'{content_length}',
|
14 |
+
'Origin': 'https://deepinfra.com',
|
15 |
+
'Connection': 'keep-alive',
|
16 |
+
'Sec-Fetch-Dest': 'empty',
|
17 |
+
'Sec-Fetch-Mode': 'cors',
|
18 |
+
'Sec-Fetch-Site': 'same-site'
|
19 |
+
}
|
20 |
+
|
21 |
+
# Path: assets/source/headers/get_headers.py
|
assets/templates/index.html
ADDED
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en">
|
3 |
+
<head>
|
4 |
+
<meta charset="UTF-8">
|
5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6 |
+
<title>DeepInfra Wrapper - Developer Reference</title>
|
7 |
+
<style>
|
8 |
+
body {
|
9 |
+
background-color: #1a1a1a;
|
10 |
+
color: #e0e0e0;
|
11 |
+
font-family: 'Arial', sans-serif;
|
12 |
+
margin: 0;
|
13 |
+
padding: 0;
|
14 |
+
}
|
15 |
+
.container {
|
16 |
+
width: 80%;
|
17 |
+
margin: 0 auto;
|
18 |
+
padding: 20px;
|
19 |
+
}
|
20 |
+
header {
|
21 |
+
text-align: center;
|
22 |
+
padding: 50px 0;
|
23 |
+
}
|
24 |
+
header h1 {
|
25 |
+
color: #00ff00;
|
26 |
+
}
|
27 |
+
.status {
|
28 |
+
text-align: center;
|
29 |
+
padding: 10px;
|
30 |
+
margin-bottom: 20px;
|
31 |
+
background-color: #006400;
|
32 |
+
border-radius: 5px;
|
33 |
+
}
|
34 |
+
.routes {
|
35 |
+
margin-top: 20px;
|
36 |
+
}
|
37 |
+
.routes h2 {
|
38 |
+
color: #00ff00;
|
39 |
+
}
|
40 |
+
.routes ul {
|
41 |
+
list-style: none;
|
42 |
+
padding: 0;
|
43 |
+
}
|
44 |
+
.routes ul li {
|
45 |
+
background-color: #333333;
|
46 |
+
padding: 10px;
|
47 |
+
margin: 5px 0;
|
48 |
+
border-radius: 5px;
|
49 |
+
}
|
50 |
+
.routes ul li a {
|
51 |
+
color: #00ff00;
|
52 |
+
text-decoration: none;
|
53 |
+
}
|
54 |
+
.routes ul li a:hover {
|
55 |
+
text-decoration: underline;
|
56 |
+
}
|
57 |
+
</style>
|
58 |
+
</head>
|
59 |
+
<body>
|
60 |
+
<div class="container">
|
61 |
+
<header>
|
62 |
+
<h1>DeepInfra Wrapper</h1>
|
63 |
+
<div class="status">Status: Active</div>
|
64 |
+
</header>
|
65 |
+
<div class="routes">
|
66 |
+
<h2>Available Routes</h2>
|
67 |
+
<ul>
|
68 |
+
<li><a href="/chat/completions">/chat/completions</a></li>
|
69 |
+
<li><a href="/models">/models</a></li>
|
70 |
+
</ul>
|
71 |
+
</div>
|
72 |
+
</div>
|
73 |
+
</body>
|
74 |
+
</html>
|