-
Notifications
You must be signed in to change notification settings - Fork 98
Skynet chatGPT #122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Skynet chatGPT #122
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| // This is an NGINX reverse proxy configuration file for the Skynet Middleware | ||
|
|
||
| server { | ||
| // set whatever port you'd like | ||
| listen 9000; | ||
| // replace the server name with yours | ||
| server_name skynet.middleware.com; | ||
|
|
||
| # Custom log locations | ||
| access_log /var/log/nginx/skynet_access.log; | ||
| error_log /var/log/nginx/skynet_error.log; | ||
|
|
||
| location /gpt3 { | ||
| proxy_pass https://api.openai.com/v1/completions; # GPT-3 endpoint | ||
|
|
||
| # Required for SSL verification with the upstream server (OpenAI) | ||
| proxy_ssl_server_name on; | ||
| proxy_ssl_protocols TLSv1 TLSv1.1 TLSv1.2; | ||
| proxy_ssl_session_reuse off; | ||
|
|
||
| # Headers for OpenAI | ||
| // replace the sk-XXXX with your API key | ||
| proxy_set_header Authorization "Bearer sk-XXXX"; | ||
| proxy_set_header Content-Type "application/json"; | ||
|
|
||
| # Standard proxy headers | ||
| proxy_set_header Host api.openai.com; | ||
| proxy_set_header X-Real-IP $remote_addr; | ||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||
| } | ||
|
|
||
| location /chat { | ||
| proxy_pass https://api.openai.com/v1/chat/completions; # ChatGPT endpoint | ||
|
|
||
| # Required for SSL verification with the upstream server (OpenAI) | ||
| proxy_ssl_server_name on; | ||
| proxy_ssl_protocols TLSv1 TLSv1.1 TLSv1.2; | ||
| proxy_ssl_session_reuse off; | ||
|
|
||
| # Headers for OpenAI | ||
| // replace the sk-XXXX with your API key | ||
| proxy_set_header Authorization "Bearer sk-XXXX"; | ||
| proxy_set_header Content-Type "application/json"; | ||
|
|
||
| # Standard proxy headers | ||
| proxy_set_header Host api.openai.com; | ||
| proxy_set_header X-Real-IP $remote_addr; | ||
| proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,170 @@ | ||
| #define SERVER_ADDR "skynet.middleware.com" | ||
| #define SERVER_PORT 9000 | ||
| #define INITIAL_BUF_SIZE 2048 | ||
| #define DEFAULT_SYSTEMPROMPT "You are a helpful assistant but roleplay as skynet from Terminator." | ||
| #include "::/Home/Net/Utilities/JSON/JSON" | ||
| class Message { | ||
| U8 role[10]; // "user" or "assistant" | ||
| U8 content[1024]; | ||
| } history[100]; | ||
| I64 currentHistoryCount = 0; | ||
|
|
||
| U0 AppendToHistory(U8 *role, U8 *content) { | ||
| if (currentHistoryCount < 100) { | ||
| StrCopy(history[currentHistoryCount].role, role); | ||
| StrCopy(history[currentHistoryCount].content, content); | ||
| currentHistoryCount++; | ||
| } | ||
| } | ||
|
|
||
| U8 *StrChr(U8 *Str,U8 Pivot) | ||
| { | ||
| //U8 *Orig=Str; | ||
| while (*Str!=Pivot&&*Str!=0)Str++; | ||
| if (*Str==Pivot) return Str; | ||
| else return 0; | ||
| } | ||
| U8* RemoveBeforeJSON(U8 *input) { | ||
| U8 *jsonStart = StrChr(input, '{'); | ||
|
Comment on lines
+20
to
+28
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. StrChr is only used once here. Just put it in RemoveBeforeJSON.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, why not just use StrFind? |
||
|
|
||
| if (jsonStart != NULL) { | ||
| return jsonStart; | ||
| } | ||
| return NULL; // No JSON detected | ||
| } | ||
|
|
||
| I64 Skynet(U8 *message, U8 *system, U8 *model) | ||
| { | ||
| I64 sock, index, bufferSize = INITIAL_BUF_SIZE; | ||
| U8 *responseBuf = MAlloc(bufferSize); // Dynamic allocation of the buffer | ||
|
|
||
| sock = TCPConnectionCreate(SERVER_ADDR, SERVER_PORT); | ||
| if (sock <= 0) | ||
| { | ||
| PrintErr("Failed to connect to middleware server"); | ||
| return sock; | ||
| } | ||
|
|
||
| U8 *messages = StrPrint(NULL, "{\"role\": \"system\",\"content\": \"%s\"},", system); | ||
|
|
||
| for (index = 0; index < currentHistoryCount; index++) { | ||
| U8 *msg = StrPrint(NULL, "{\"role\": \"%s\",\"content\": \"%s\"},", history[index].role, history[index].content); | ||
| messages = CatPrint(messages, msg); | ||
| Free(msg); | ||
| } | ||
|
|
||
| U8 *currentUserMsg = StrPrint(NULL, "{\"role\": \"user\",\"content\": \"%s\"}", message); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should sanitize the user input. |
||
| messages = CatPrint(messages, currentUserMsg); | ||
| Free(currentUserMsg); | ||
|
|
||
| U8 *payload = StrPrint(NULL, "{\"model\": \"%s\",\"messages\": [%s]}", model, messages); | ||
| Free(messages); | ||
|
|
||
| //SysLog(payload); | ||
|
|
||
|
Comment on lines
+63
to
+64
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove those lines. |
||
| U8 *requestHeader = StrPrint(NULL, | ||
| "POST /chat HTTP/1.1\r\n" | ||
| "Host: %s:%d\r\n" | ||
| "User-Agent: ZealOSClient/1.0\r\n" | ||
| "Accept: */*\r\n" | ||
| "Content-Type: application/json\r\n" | ||
| "Content-Length: %d\r\n" | ||
| "\r\n", | ||
| SERVER_ADDR, | ||
| SERVER_PORT, | ||
| StrLen(payload) | ||
| ); | ||
|
|
||
| U8 *fullRequest = StrPrint(NULL, "%s%s", requestHeader, payload); | ||
| TCPSocketSendString(sock, fullRequest); | ||
|
|
||
| Free(requestHeader); | ||
| Free(payload); | ||
| Free(fullRequest); | ||
|
|
||
| I64 responseLength = TCPSocketReceive(sock, responseBuf, bufferSize - 1); | ||
| responseBuf[responseLength] = 0; // Null-terminate the buffer for safety | ||
|
|
||
| if (responseLength == sizeof(responseBuf) - 1) { | ||
| PrintErr("Warning: responseBuf might be full. Some data could be truncated."); | ||
| } | ||
| // Check if buffer might be full | ||
| while (responseLength == bufferSize - 1) | ||
| { | ||
| // Double the buffer size and reallocate | ||
| bufferSize *= 2; | ||
| Free(responseBuf); | ||
| responseBuf = MAlloc(bufferSize); | ||
|
|
||
| // Continue receiving data from where you left off | ||
| responseLength += TCPSocketReceive(sock, responseBuf + responseLength, bufferSize - responseLength - 1); | ||
| responseBuf[responseLength] = 0; | ||
| } | ||
| //SysLog(responseBuf); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove this line. |
||
|
|
||
| CCompCtrl *cc = CompCtrlNew(MStrPrint("%s", RemoveBeforeJSON(responseBuf))); | ||
| CJSONDataEntry *jsonData = JSONParse(cc); | ||
|
|
||
| // Retrieve the 'choices' array | ||
| CJSONDataEntry *choicesEntry = JSONKeyValueGet(jsonData, "choices"); | ||
| if (!choicesEntry || choicesEntry->type != JSONT_ARRAY) { | ||
| // Handle error: choices key not found or not an array | ||
| return; | ||
| } | ||
|
|
||
| // Retrieve the first object from the 'choices' array | ||
| CJSONDataEntry *firstChoice = JSONIndexValueGet(choicesEntry, 0); | ||
| if (!firstChoice || firstChoice->type != JSONT_OBJ) { | ||
| // Handle error: First choice not found or not an object | ||
| return; | ||
| } | ||
|
|
||
| // Retrieve the 'message' object from the first choice | ||
| CJSONDataEntry *messageEntry = JSONKeyValueGet(firstChoice, "message"); | ||
| if (!messageEntry || messageEntry->type != JSONT_OBJ) { | ||
| // Handle error: message key not found or not an object | ||
| return; | ||
| } | ||
|
|
||
| // Retrieve the 'content' string from the 'message' object | ||
| CJSONDataEntry *contentEntry = JSONKeyValueGet(messageEntry, "content"); | ||
| if (!contentEntry || contentEntry->type != JSONT_STRING) { | ||
| // Handle error: content key not found or not a string | ||
| return; | ||
| } | ||
|
|
||
| U8 *completion = contentEntry->string_data; | ||
| //SysLog(completion); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove this line. |
||
| CompCtrlDel(cc); | ||
|
|
||
| "\n$$RED$$ Skynet: $$YELLOW$$%s$$FG$$\n", completion; | ||
|
|
||
| AppendToHistory("user", message); | ||
| AppendToHistory("assistant", completion); | ||
|
|
||
| TCPSocketClose(sock); | ||
| Free(responseBuf); | ||
| return 0; | ||
| } | ||
|
|
||
| // gpt-3.5-turbo || gpt-4 | ||
| public U0 ChatUI(U8 *system=DEFAULT_SYSTEMPROMPT, U8 *model="gpt-4") { | ||
| U8 *userInput; | ||
| DocClear; | ||
|
|
||
| try{ | ||
| "\t\t\t\t\t\t\t$$LTRED$$Welcome to Skynet$$FG$$\n"; | ||
|
|
||
| while(1) { | ||
| "\n$$LTBLUE$$ You: $$GREEN$$"; | ||
|
|
||
| LBts(&Fs->task_flags, TASKf_CMD_LINE_PROMPT); | ||
| userInput = StrGet(,, SGF_SHIFT_ESC_EXIT); | ||
| LBtr(&Fs->task_flags, TASKf_CMD_LINE_PROMPT); | ||
| Skynet(userInput, system, model); | ||
| } | ||
| } | ||
| catch | ||
| PutExcept; | ||
| } | ||
| ChatUI; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| #define SERVER_ADDR "skynet.middleware.com" | ||
| #define SERVER_PORT 9000 | ||
|
|
||
| // GPT2 - GPT3 version | ||
| U8* ExtractGPTCompletion(U8 *response) { | ||
| U8 *start = StrFind("\"text\": \"", response); | ||
| if (!start) { | ||
| return NULL; // Pattern not found | ||
| } | ||
|
|
||
| start += 10; // Move pointer after '"text": "' | ||
|
|
||
| U8 *end = StrFind("\",", start); // Find the closing double quote | ||
| if (!end) { | ||
| return NULL; | ||
| } | ||
|
|
||
| *end = 0; // Null terminate the completion string | ||
|
|
||
| return start; | ||
| } | ||
|
|
||
| public I64 Skynet3(U8 *prompt) | ||
| { | ||
| U8 responseBuf[8192]; | ||
| I64 sock; | ||
|
|
||
| sock = TCPConnectionCreate(SERVER_ADDR, SERVER_PORT); | ||
| if (sock <= 0) | ||
| { | ||
| PrintErr("Failed to connect to middleware server"); | ||
| return sock; | ||
| } | ||
|
|
||
| U8 *payload = StrPrint(NULL, "{\"model\": \"text-davinci-003\",\"prompt\": \"%s\",\"max_tokens\": 100,\"temperature\": 1}", prompt); | ||
| U8 *requestHeader = StrPrint(NULL, | ||
| "POST /gpt3 HTTP/1.1\r\n" | ||
| "Host: %s:%d\r\n" | ||
| "User-Agent: ZealOSClient/1.0\r\n" | ||
| "Accept: */*\r\n" | ||
| "Content-Type: application/json\r\n" | ||
| "Content-Length: %d\r\n" | ||
| "\r\n", | ||
| SERVER_ADDR, | ||
| SERVER_PORT, | ||
| StrLen(payload) | ||
| ); | ||
| U8 *fullRequest = StrPrint(NULL, "%s%s\n\n", requestHeader, payload); | ||
|
|
||
| TCPSocketSendString(sock, fullRequest); | ||
| Free(requestHeader); | ||
| Free(payload); | ||
| Free(fullRequest); | ||
|
|
||
|
|
||
| I64 responseLength = TCPSocketReceive(sock, responseBuf, sizeof(responseBuf) - 1); // -1 to ensure space for null terminator | ||
|
|
||
| responseBuf[responseLength] = 0; // Null-terminate the response | ||
|
|
||
| // Assuming the headers and payload are separated by two newline sequences (standard HTTP) | ||
| U8 *jsonPayload = StrFind("\r\n\r\n", responseBuf); | ||
| if (!jsonPayload) { | ||
| TCPSocketClose(sock); | ||
| return -1; // or some error code | ||
| } | ||
| jsonPayload += 4; // Move past the header separator | ||
|
|
||
| U8 *completion = ExtractGPTCompletion(jsonPayload); | ||
| Print("$$RED$$Skynet: $$YELLOW$$%s$$FG$$\n", completion); | ||
|
|
||
| TCPSocketClose(sock); | ||
| return 0; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this.