CNSeniorious000 / free-chat

forked from @anse-app/chatgpt-demo. Index site at https://free-chat.asia
https://endless-chat.vercel.app
MIT License
174 stars 52 forks source link

Server-side token counting and message trimming #19

Closed sweep-ai[bot] closed 7 months ago

sweep-ai[bot] commented 7 months ago

PR Feedback (click)

Summary

Fixes #17.


πŸŽ‰ Latest improvements to Sweep:


πŸ’‘ To get Sweep to edit this pull request, you can:

sweep-ai[bot] commented 7 months ago

Sandbox Executions

sweep-ai[bot] commented 7 months ago

Apply Sweep Rules to your PR?

netlify[bot] commented 7 months ago

Deploy Preview for endless-chat failed.

Name Link
Latest commit 0b278c6e111249382eb1edf83ce2f19b9e62f9fe
Latest deploy log https://app.netlify.com/sites/endless-chat/deploys/6569aa9c6fed690008602cd7
vercel[bot] commented 7 months ago

The latest updates on your projects. Learn more about Vercel for Git β†—οΈŽ

Name Status Preview Comments Updated (UTC)
44444444444 ❌ Failed (Inspect) Dec 1, 2023 9:44am
emphasize ❌ Failed (Inspect) Dec 1, 2023 9:44am
endless-chat ❌ Failed (Inspect) Dec 1, 2023 9:44am
free-chat ❌ Failed (Inspect) Dec 1, 2023 9:44am
free-chat-personal ❌ Failed (Inspect) Dec 1, 2023 9:44am
senior-dev-bot[bot] commented 7 months ago

Hi there! :wave: Thanks for opening a PR. :tada: To get the most out of Senior Dev, please sign up in our Web App, connect your GitHub account, and add/join your organization CNSeniorious000. After that, you will receive code reviews beginning on your next opened PR. :rocket:

pr-explainer-bot[bot] commented 7 months ago

Pull Request Report

Hey there! πŸ‘‹ Here's a report on the changes made in the src/pages/api/generate.ts file:

Changes

  1. Updated import statements for ProxyAgent and fetch from the undici library. (View Diff)
  2. Updated import statements for generatePayload and parseOpenAIStream from the @/utils/openAI module. (View Diff)
  3. Updated import statements for verifySignature from the @/utils/auth module. (View Diff)
  4. Updated import statement for APIRoute from the astro module. (View Diff)
  5. Updated the value of apiKey using the import.meta.env.OPENAI_API_KEY environment variable. (View Diff)
  6. Updated the value of httpsProxy using the import.meta.env.HTTPS_PROXY environment variable. (View Diff)
  7. Updated the value of baseUrl using the import.meta.env.OPENAI_API_BASE_URL environment variable. If the variable is not defined, the default value is set to 'https://api.openai.com'. (View Diff)
  8. Updated the value of sitePassword using the import.meta.env.SITE_PASSWORD environment variable. (View Diff)
  9. Updated the value of ua using the import.meta.env.UNDICI_UA environment variable. (View Diff)
  10. Added a check for the messages property in the request body. If it is not present, a 400 Bad Request response is returned with an error message. (View Diff)
  11. Added a check for the sitePassword and pass values. If they are not equal, a 401 Unauthorized response is returned with an error message. (View Diff)
  12. Added a check for the import.meta.env.PROD flag and the signature verification. If the signature is invalid, a 401 Unauthorized response is returned with an error message. (View Diff)
  13. Initialized the tiktoken-js library and obtained an encoder instance for the 'en' language. (View Diff)
  14. Defined the minMessages and maxTokens variables for message truncation. Adjusted as needed. (View Diff)
  15. Added a function countTokens to count the tokens for a message using tiktoken-js. (View Diff)
  16. Implemented message truncation logic to ensure the total tokens do not exceed the maxTokens limit. (View Diff)
  17. Updated the initOptions object with the generated payload, headers, and other options. (View Diff)
  18. Added forwarding of specific headers from the request to the headers object. (View Diff)
  19. Added the user-agent header if the ua variable is defined. (View Diff)
  20. Added a check for the httpsProxy variable and set the dispatcher option to a ProxyAgent instance if it is defined. (View Diff)
  21. Handled errors during the fetch request and returned a 500 Internal Server Error response with the error details. (View Diff)
  22. Returned the parsed response from parseOpenAIStream as the API response. (View Diff)

Suggestions to Improve Code

Bugs

Improvements

Rating

I would rate the code a 7 out of 10 based on the following criteria:

Keep up the good work! If you have any questions or need further assistance, feel free to ask. πŸ˜„


Code Diffs

Diff-1

- import { ProxyAgent, fetch } from 'undici'
+ import { ProxyAgent, fetch } from 'undici'

Diff-2

- import { generatePayload, parseOpenAIStream } from '@/utils/openAI'
+ import { generatePayload, parseOpenAIStream } from '@/utils/openAI'

Diff-3

- import { verifySignature } from '@/utils/auth'
+ import { verifySignature } from '@/utils/auth'

Diff-4

- import type { APIRoute } from 'astro'
+ import type { APIRoute } from 'astro'

Diff-5

- const apiKey = import.meta.env.OPENAI_API_KEY
+ const apiKey = import.meta.env.OPENAI_API_KEY

Diff-6

- const httpsProxy = import.meta.env.HTTPS_PROXY
+ const httpsProxy = import.meta.env.HTTPS_PROXY

Diff-7

- const baseUrl = ((import.meta.env.OPENAI_API_BASE_URL) || 'https://api.openai.com').trim().replace(/\/$/, '')
+ const baseUrl = ((import.meta.env.OPENAI_API_BASE_URL) || 'https://api.openai.com').trim().replace(/\/$/, '')

Diff-8

- const sitePassword = import.meta.env.SITE_PASSWORD
+ const sitePassword = import.meta.env.SITE_PASSWORD

Diff-9

+ const ua = import.meta.env.UNDICI_UA

Diff-10

+   if (!messages) {
+     return new Response(JSON.stringify({
+       error: {
+         message: 'No input text.',
+       },
+     }), { status: 400 })
+   }

Diff-11

+   if (sitePassword && sitePassword !== pass) {
+     return new Response(JSON.stringify({
+       error: {
+         message: 'Invalid password.',
+       },
+     }), { status: 401 })
+   }

Diff-12

+   if (import.meta.env.PROD && !await verifySignature({ t: time, m: messages?.[messages.length - 1]?.content || '' }, sign)) {
+     return new Response(JSON.stringify({
+       error: {
+         message: 'Invalid signature.',
+       },
+     }), { status: 401 })
+   }

Diff-13

+ const encoder = new Encoder('en');

Diff-14

+ const minMessages = 5;
+ const maxTokens = 1024;

Diff-15

+ function countTokens(message) {
+     return encoder.encode(message).length;
+ }

Diff-16

+ let totalTokens = messages.reduce((sum, msg) => sum + countTokens(msg.content), 0);
+ while (totalTokens > maxTokens && messages.length > minMessages) {
+     totalTokens -= countTokens(messages[0].content);
+     messages.shift();
+ }

Diff-17

+ const initOptions = generatePayload(request.headers.get('Authorization') ?? `Bearer ${apiKey}`, messages, model);

Diff-18


+   if (baseUrl) request.headers.forEach((val, key) => (FORWARD_HEADERS.includes(key) || key.startsWith('sec-') || key
netlify[bot] commented 7 months ago

Deploy Preview for chat-for-free failed.

Name Link
Latest commit 0b278c6e111249382eb1edf83ce2f19b9e62f9fe
Latest deploy log https://app.netlify.com/sites/chat-for-free/deploys/6569aa9ca4c97f00088a2feb