🔧 fix: Chat Middleware, Zod Conversion, Auto-Save and S3 URL Refresh (#6720)

* 🔧 feat: Add configurable S3 URL refresh expiry time

* fix: Set default width and height for URLIcon component in case container style results in NaN

* refactor: Enhance auto-save functionality with debounced restore methods

* feat: Add support for additionalProperties in JSON schema conversion to Zod

* test: Add tests for additionalProperties handling in JSON schema to Zod conversion

* chore: Reorder import statements for better readability in ask route

* fix: Handle additional successful response status code (200) in SSE error handler

* fix: add missing rate limiting middleware for bedrock and agent chat routes

* fix: update moderation middleware to check feature flag before processing requests

* fix: add moderation middleware to chat routes for text moderation

* Revert "refactor: Enhance auto-save functionality with debounced restore methods"

This reverts commit d2e4134d1f.

* refactor: Move base64 encoding/decoding functions to top-level scope and optimize input handling
This commit is contained in:
Danny Avila 2025-04-03 20:42:56 -04:00 committed by GitHub
parent 95ecd05046
commit 953e9732d9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 300 additions and 73 deletions

View file

@ -11,6 +11,28 @@ const clearDraft = debounce((id?: string | null) => {
localStorage.removeItem(`${LocalStorageKeys.TEXT_DRAFT}${id ?? ''}`);
}, 2500);
const encodeBase64 = (plainText: string): string => {
try {
const textBytes = new TextEncoder().encode(plainText);
return btoa(String.fromCharCode(...textBytes));
} catch (e) {
return '';
}
};
const decodeBase64 = (base64String: string): string => {
try {
const bytes = atob(base64String);
const uint8Array = new Uint8Array(bytes.length);
for (let i = 0; i < bytes.length; i++) {
uint8Array[i] = bytes.charCodeAt(i);
}
return new TextDecoder().decode(uint8Array);
} catch (e) {
return '';
}
};
export const useAutoSave = ({
conversationId,
textAreaRef,
@ -30,28 +52,6 @@ export const useAutoSave = ({
const fileIds = useMemo(() => Array.from(files.keys()), [files]);
const { data: fileList } = useGetFiles<TFile[]>();
const encodeBase64 = (plainText: string): string => {
try {
const textBytes = new TextEncoder().encode(plainText);
return btoa(String.fromCharCode(...textBytes));
} catch (e) {
return '';
}
};
const decodeBase64 = (base64String: string): string => {
try {
const bytes = atob(base64String);
const uint8Array = new Uint8Array(bytes.length);
for (let i = 0; i < bytes.length; i++) {
uint8Array[i] = bytes.charCodeAt(i);
}
return new TextDecoder().decode(uint8Array);
} catch (e) {
return '';
}
};
const restoreFiles = useCallback(
(id: string) => {
const filesDraft = JSON.parse(
@ -126,16 +126,17 @@ export const useAutoSave = ({
return;
}
const handleInput = debounce(() => {
if (textAreaRef?.current && textAreaRef.current.value) {
const handleInput = debounce((e: React.ChangeEvent<HTMLTextAreaElement>) => {
const value = e.target.value;
if (value) {
localStorage.setItem(
`${LocalStorageKeys.TEXT_DRAFT}${conversationId}`,
encodeBase64(textAreaRef.current.value),
encodeBase64(value),
);
} else {
localStorage.removeItem(`${LocalStorageKeys.TEXT_DRAFT}${conversationId}`);
}
}, 1000);
}, 750);
const textArea = textAreaRef?.current;
if (textArea) {