diff --git a/.gitignore b/.gitignore
index 08d0ab0..2c988d5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -142,7 +142,8 @@ ch0?/0?_user_interface/chainlit.md
ch0?/0?_user_interface/.files
*.lock
-# Temporary OS-related files
+# Temporary and OS-related files
+Untitled.ipynb
.DS_Store
# Byte-compiled / optimized / DLL files
diff --git a/ch05/11_qwen3/qwen3-chat-interface/.chainlit/config.toml b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/config.toml
new file mode 100644
index 0000000..907c898
--- /dev/null
+++ b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/config.toml
@@ -0,0 +1,147 @@
+[project]
+# List of environment variables to be provided by each user to use the app.
+user_env = []
+
+# Duration (in seconds) during which the session is saved when the connection is lost
+session_timeout = 3600
+
+# Duration (in seconds) of the user session expiry
+user_session_timeout = 1296000 # 15 days
+
+# Enable third parties caching (e.g., LangChain cache)
+cache = false
+
+# Whether to persist user environment variables (API keys) to the database
+# Set to true to store user env vars in DB, false to exclude them for security
+persist_user_env = false
+
+# Whether to mask user environment variables (API keys) in the UI with password type
+# Set to true to show API keys as ***, false to show them as plain text
+mask_user_env = false
+
+# Authorized origins
+allow_origins = ["*"]
+
+[features]
+# Process and display HTML in messages. This can be a security risk (see https://stackoverflow.com/questions/19603097/why-is-it-dangerous-to-render-user-generated-html-or-javascript)
+unsafe_allow_html = false
+
+# Process and display mathematical expressions. This can clash with "$" characters in messages.
+latex = false
+
+# Autoscroll new user messages at the top of the window
+user_message_autoscroll = true
+
+# Automatically tag threads with the current chat profile (if a chat profile is used)
+auto_tag_thread = true
+
+# Allow users to edit their own messages
+edit_message = true
+
+[features.slack]
+# Add emoji reaction when message is received (requires reactions:write OAuth scope)
+reaction_on_message_received = false
+
+# Authorize users to spontaneously upload files with messages
+[features.spontaneous_file_upload]
+ enabled = true
+ # Define accepted file types using MIME types
+ # Examples:
+ # 1. For specific file types:
+ # accept = ["image/jpeg", "image/png", "application/pdf"]
+ # 2. For all files of certain type:
+ # accept = ["image/*", "audio/*", "video/*"]
+ # 3. For specific file extensions:
+ # accept = { "application/octet-stream" = [".xyz", ".pdb"] }
+ # Note: Using "*/*" is not recommended as it may cause browser warnings
+ accept = ["*/*"]
+ max_files = 20
+ max_size_mb = 500
+
+[features.audio]
+ # Enable audio features
+ enabled = false
+ # Sample rate of the audio
+ sample_rate = 24000
+
+[features.mcp]
+ # Enable Model Context Protocol (MCP) features
+ enabled = false
+
+[features.mcp.sse]
+ enabled = true
+
+[features.mcp.streamable-http]
+ enabled = true
+
+[features.mcp.stdio]
+ enabled = true
+ # Only the executables in the allow list can be used for MCP stdio server.
+ # Only need the base name of the executable, e.g. "npx", not "/usr/bin/npx".
+ # Please don't comment this line for now, we need it to parse the executable name.
+ allowed_executables = [ "npx", "uvx" ]
+
+[UI]
+# Name of the assistant.
+name = "Assistant"
+
+# default_theme = "dark"
+
+# layout = "wide"
+
+# default_sidebar_state = "open"
+
+# Description of the assistant. This is used for HTML tags.
+# description = ""
+
+# Chain of Thought (CoT) display mode. Can be "hidden", "tool_call" or "full".
+cot = "full"
+
+# Specify a CSS file that can be used to customize the user interface.
+# The CSS file can be served from the public directory or via an external link.
+# custom_css = "/public/test.css"
+
+# Specify additional attributes for a custom CSS file
+# custom_css_attributes = "media=\"print\""
+
+# Specify a JavaScript file that can be used to customize the user interface.
+# The JavaScript file can be served from the public directory.
+# custom_js = "/public/test.js"
+
+# The style of alert boxes. Can be "classic" or "modern".
+alert_style = "classic"
+
+# Specify additional attributes for custom JS file
+# custom_js_attributes = "async type = \"module\""
+
+# Custom login page image, relative to public directory or external URL
+# login_page_image = "/public/custom-background.jpg"
+
+# Custom login page image filter (Tailwind internal filters, no dark/light variants)
+# login_page_image_filter = "brightness-50 grayscale"
+# login_page_image_dark_filter = "contrast-200 blur-sm"
+
+
+# Specify a custom meta image url.
+# custom_meta_image_url = "https://chainlit-cloud.s3.eu-west-3.amazonaws.com/logo/chainlit_banner.png"
+
+# Load assistant logo directly from URL.
+logo_file_url = ""
+
+# Load assistant avatar image directly from URL.
+default_avatar_file_url = ""
+
+# Specify a custom build directory for the frontend.
+# This can be used to customize the frontend code.
+# Be careful: If this is a relative path, it should not start with a slash.
+# custom_build = "./public/build"
+
+# Specify optional one or more custom links in the header.
+# [[UI.header_links]]
+# name = "Issues"
+# display_name = "Report Issue"
+# icon_url = "https://avatars.githubusercontent.com/u/128686189?s=200&v=4"
+# url = "https://github.com/Chainlit/chainlit/issues"
+
+[meta]
+generated_by = "2.7.2"
diff --git a/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/bn.json b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/bn.json
new file mode 100644
index 0000000..e792388
--- /dev/null
+++ b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/bn.json
@@ -0,0 +1,219 @@
+{
+ "common": {
+ "actions": {
+ "cancel": "\u09ac\u09be\u09a4\u09bf\u09b2 \u0995\u09b0\u09c1\u09a8",
+ "confirm": "\u09a8\u09bf\u09b6\u09cd\u099a\u09bf\u09a4 \u0995\u09b0\u09c1\u09a8",
+ "continue": "\u099a\u09be\u09b2\u09bf\u09af\u09bc\u09c7 \u09af\u09be\u09a8",
+ "goBack": "\u09aa\u09bf\u099b\u09a8\u09c7 \u09af\u09be\u09a8",
+ "reset": "\u09b0\u09bf\u09b8\u09c7\u099f \u0995\u09b0\u09c1\u09a8",
+ "submit": "\u099c\u09ae\u09be \u09a6\u09bf\u09a8"
+ },
+ "status": {
+ "loading": "\u09b2\u09cb\u09a1 \u09b9\u099a\u09cd\u099b\u09c7...",
+ "error": {
+ "default": "\u098f\u0995\u099f\u09bf \u09a4\u09cd\u09b0\u09c1\u099f\u09bf \u0998\u099f\u09c7\u099b\u09c7",
+ "serverConnection": "\u09b8\u09be\u09b0\u09cd\u09ad\u09be\u09b0\u09c7\u09b0 \u09b8\u09be\u09a5\u09c7 \u09b8\u0982\u09af\u09cb\u0997 \u0995\u09b0\u09be \u09af\u09be\u099a\u09cd\u099b\u09c7 \u09a8\u09be"
+ }
+ }
+ },
+ "auth": {
+ "login": {
+ "title": "\u0985\u09cd\u09af\u09be\u09aa\u09cd\u09b2\u09bf\u0995\u09c7\u09b6\u09a8 \u09ac\u09cd\u09af\u09ac\u09b9\u09be\u09b0 \u0995\u09b0\u09a4\u09c7 \u09b2\u0997\u0987\u09a8 \u0995\u09b0\u09c1\u09a8",
+ "form": {
+ "email": {
+ "label": "\u0987\u09ae\u09c7\u0987\u09b2 \u09a0\u09bf\u0995\u09be\u09a8\u09be",
+ "required": "\u0987\u09ae\u09c7\u0987\u09b2 \u098f\u0995\u099f\u09bf \u0986\u09ac\u09b6\u09cd\u09af\u0995 \u0995\u09cd\u09b7\u09c7\u09a4\u09cd\u09b0"
+ },
+ "password": {
+ "label": "\u09aa\u09be\u09b8\u0993\u09af\u09bc\u09be\u09b0\u09cd\u09a1",
+ "required": "\u09aa\u09be\u09b8\u0993\u09af\u09bc\u09be\u09b0\u09cd\u09a1 \u098f\u0995\u099f\u09bf \u0986\u09ac\u09b6\u09cd\u09af\u0995 \u0995\u09cd\u09b7\u09c7\u09a4\u09cd\u09b0"
+ },
+ "actions": {
+ "signin": "\u09b8\u09be\u0987\u09a8 \u0987\u09a8 \u0995\u09b0\u09c1\u09a8"
+ },
+ "alternativeText": {
+ "or": "\u0985\u09a5\u09ac\u09be"
+ }
+ },
+ "errors": {
+ "default": "\u09b8\u09be\u0987\u09a8 \u0987\u09a8 \u0995\u09b0\u09be \u09b8\u09ae\u09cd\u09ad\u09ac \u09b9\u099a\u09cd\u099b\u09c7 \u09a8\u09be",
+ "signin": "\u0985\u09a8\u09cd\u09af \u098f\u0995\u099f\u09bf \u0985\u09cd\u09af\u09be\u0995\u09be\u0989\u09a8\u09cd\u099f \u09a6\u09bf\u09af\u09bc\u09c7 \u09b8\u09be\u0987\u09a8 \u0987\u09a8 \u0995\u09b0\u09be\u09b0 \u099a\u09c7\u09b7\u09cd\u099f\u09be \u0995\u09b0\u09c1\u09a8",
+ "oauthSignin": "\u0985\u09a8\u09cd\u09af \u098f\u0995\u099f\u09bf \u0985\u09cd\u09af\u09be\u0995\u09be\u0989\u09a8\u09cd\u099f \u09a6\u09bf\u09af\u09bc\u09c7 \u09b8\u09be\u0987\u09a8 \u0987\u09a8 \u0995\u09b0\u09be\u09b0 \u099a\u09c7\u09b7\u09cd\u099f\u09be \u0995\u09b0\u09c1\u09a8",
+ "redirectUriMismatch": "\u09b0\u09bf\u09a1\u09be\u0987\u09b0\u09c7\u0995\u09cd\u099f URI \u0993\u0986\u09a5 \u0985\u09cd\u09af\u09be\u09aa \u0995\u09a8\u09ab\u09bf\u0997\u09be\u09b0\u09c7\u09b6\u09a8\u09c7\u09b0 \u09b8\u09be\u09a5\u09c7 \u09ae\u09bf\u09b2\u099b\u09c7 \u09a8\u09be",
+ "oauthCallback": "\u0985\u09a8\u09cd\u09af \u098f\u0995\u099f\u09bf \u0985\u09cd\u09af\u09be\u0995\u09be\u0989\u09a8\u09cd\u099f \u09a6\u09bf\u09af\u09bc\u09c7 \u09b8\u09be\u0987\u09a8 \u0987\u09a8 \u0995\u09b0\u09be\u09b0 \u099a\u09c7\u09b7\u09cd\u099f\u09be \u0995\u09b0\u09c1\u09a8",
+ "oauthCreateAccount": "\u0985\u09a8\u09cd\u09af \u098f\u0995\u099f\u09bf \u0985\u09cd\u09af\u09be\u0995\u09be\u0989\u09a8\u09cd\u099f \u09a6\u09bf\u09af\u09bc\u09c7 \u09b8\u09be\u0987\u09a8 \u0987\u09a8 \u0995\u09b0\u09be\u09b0 \u099a\u09c7\u09b7\u09cd\u099f\u09be \u0995\u09b0\u09c1\u09a8",
+ "emailCreateAccount": "\u0985\u09a8\u09cd\u09af \u098f\u0995\u099f\u09bf \u0985\u09cd\u09af\u09be\u0995\u09be\u0989\u09a8\u09cd\u099f \u09a6\u09bf\u09af\u09bc\u09c7 \u09b8\u09be\u0987\u09a8 \u0987\u09a8 \u0995\u09b0\u09be\u09b0 \u099a\u09c7\u09b7\u09cd\u099f\u09be \u0995\u09b0\u09c1\u09a8",
+ "callback": "\u0985\u09a8\u09cd\u09af \u098f\u0995\u099f\u09bf \u0985\u09cd\u09af\u09be\u0995\u09be\u0989\u09a8\u09cd\u099f \u09a6\u09bf\u09af\u09bc\u09c7 \u09b8\u09be\u0987\u09a8 \u0987\u09a8 \u0995\u09b0\u09be\u09b0 \u099a\u09c7\u09b7\u09cd\u099f\u09be \u0995\u09b0\u09c1\u09a8",
+ "oauthAccountNotLinked": "\u0986\u09aa\u09a8\u09be\u09b0 \u09aa\u09b0\u09bf\u099a\u09af\u09bc \u09a8\u09bf\u09b6\u09cd\u099a\u09bf\u09a4 \u0995\u09b0\u09a4\u09c7, \u0986\u09aa\u09a8\u09bf \u09af\u09c7 \u0985\u09cd\u09af\u09be\u0995\u09be\u0989\u09a8\u09cd\u099f\u099f\u09bf \u09ae\u09c2\u09b2\u09a4 \u09ac\u09cd\u09af\u09ac\u09b9\u09be\u09b0 \u0995\u09b0\u09c7\u099b\u09bf\u09b2\u09c7\u09a8 \u09b8\u09c7\u099f\u09bf \u09a6\u09bf\u09af\u09bc\u09c7 \u09b8\u09be\u0987\u09a8 \u0987\u09a8 \u0995\u09b0\u09c1\u09a8",
+ "emailSignin": "\u0987\u09ae\u09c7\u0987\u09b2 \u09aa\u09be\u09a0\u09be\u09a8\u09cb \u09af\u09be\u09af\u09bc\u09a8\u09bf",
+ "emailVerify": "\u0985\u09a8\u09c1\u0997\u09cd\u09b0\u09b9 \u0995\u09b0\u09c7 \u0986\u09aa\u09a8\u09be\u09b0 \u0987\u09ae\u09c7\u0987\u09b2 \u09af\u09be\u099a\u09be\u0987 \u0995\u09b0\u09c1\u09a8, \u098f\u0995\u099f\u09bf \u09a8\u09a4\u09c1\u09a8 \u0987\u09ae\u09c7\u0987\u09b2 \u09aa\u09be\u09a0\u09be\u09a8\u09cb \u09b9\u09af\u09bc\u09c7\u099b\u09c7",
+ "credentialsSignin": "\u09b8\u09be\u0987\u09a8 \u0987\u09a8 \u09ac\u09cd\u09af\u09b0\u09cd\u09a5 \u09b9\u09af\u09bc\u09c7\u099b\u09c7\u0964 \u0986\u09aa\u09a8\u09be\u09b0 \u09a6\u09c7\u0993\u09af\u09bc\u09be \u09a4\u09a5\u09cd\u09af \u09b8\u09a0\u09bf\u0995 \u0995\u09bf\u09a8\u09be \u09af\u09be\u099a\u09be\u0987 \u0995\u09b0\u09c1\u09a8",
+ "sessionRequired": "\u098f\u0987 \u09aa\u09c3\u09b7\u09cd\u09a0\u09be \u09a6\u09c7\u0996\u09a4\u09c7 \u0985\u09a8\u09c1\u0997\u09cd\u09b0\u09b9 \u0995\u09b0\u09c7 \u09b8\u09be\u0987\u09a8 \u0987\u09a8 \u0995\u09b0\u09c1\u09a8"
+ }
+ },
+ "provider": {
+ "continue": "{{provider}} \u09a6\u09bf\u09af\u09bc\u09c7 \u099a\u09be\u09b2\u09bf\u09af\u09bc\u09c7 \u09af\u09be\u09a8"
+ }
+ },
+ "chat": {
+ "input": {
+ "placeholder": "\u0986\u09aa\u09a8\u09be\u09b0 \u09ac\u09be\u09b0\u09cd\u09a4\u09be \u098f\u0996\u09be\u09a8\u09c7 \u099f\u09be\u0987\u09aa \u0995\u09b0\u09c1\u09a8...",
+ "actions": {
+ "send": "\u09ac\u09be\u09b0\u09cd\u09a4\u09be \u09aa\u09be\u09a0\u09be\u09a8",
+ "stop": "\u0995\u09be\u099c \u09ac\u09a8\u09cd\u09a7 \u0995\u09b0\u09c1\u09a8",
+ "attachFiles": "\u09ab\u09be\u0987\u09b2 \u09b8\u0982\u09af\u09c1\u0995\u09cd\u09a4 \u0995\u09b0\u09c1\u09a8"
+ }
+ },
+ "speech": {
+ "start": "\u09b0\u09c7\u0995\u09b0\u09cd\u09a1\u09bf\u0982 \u09b6\u09c1\u09b0\u09c1 \u0995\u09b0\u09c1\u09a8",
+ "stop": "\u09b0\u09c7\u0995\u09b0\u09cd\u09a1\u09bf\u0982 \u09ac\u09a8\u09cd\u09a7 \u0995\u09b0\u09c1\u09a8",
+ "connecting": "\u09b8\u0982\u09af\u09cb\u0997 \u0995\u09b0\u09be \u09b9\u099a\u09cd\u099b\u09c7"
+ },
+ "commands": {
+ "button": "\u099f\u09c1\u09b2\u09b8",
+ "changeTool": "\u099f\u09c1\u09b2 \u09aa\u09b0\u09bf\u09ac\u09b0\u09cd\u09a4\u09a8 \u0995\u09b0\u09c1\u09a8",
+ "availableTools": "\u0989\u09aa\u09b2\u09ac\u09cd\u09a7 \u099f\u09c1\u09b2\u09b8"
+ },
+ "fileUpload": {
+ "dragDrop": "\u098f\u0996\u09be\u09a8\u09c7 \u09ab\u09be\u0987\u09b2 \u099f\u09c7\u09a8\u09c7 \u0986\u09a8\u09c1\u09a8",
+ "browse": "\u09ab\u09be\u0987\u09b2 \u09ac\u09cd\u09b0\u09be\u0989\u099c \u0995\u09b0\u09c1\u09a8",
+ "sizeLimit": "\u09b8\u09c0\u09ae\u09be:",
+ "errors": {
+ "failed": "\u0986\u09aa\u09b2\u09cb\u09a1 \u09ac\u09cd\u09af\u09b0\u09cd\u09a5 \u09b9\u09af\u09bc\u09c7\u099b\u09c7",
+ "cancelled": "\u0986\u09aa\u09b2\u09cb\u09a1 \u09ac\u09be\u09a4\u09bf\u09b2 \u0995\u09b0\u09be \u09b9\u09af\u09bc\u09c7\u099b\u09c7"
+ }
+ },
+ "messages": {
+ "status": {
+ "using": "\u09ac\u09cd\u09af\u09ac\u09b9\u09be\u09b0 \u0995\u09b0\u099b\u09c7",
+ "used": "\u09ac\u09cd\u09af\u09ac\u09b9\u09c3\u09a4"
+ },
+ "actions": {
+ "copy": {
+ "button": "\u0995\u09cd\u09b2\u09bf\u09aa\u09ac\u09cb\u09b0\u09cd\u09a1\u09c7 \u0995\u09aa\u09bf \u0995\u09b0\u09c1\u09a8",
+ "success": "\u0995\u09aa\u09bf \u0995\u09b0\u09be \u09b9\u09af\u09bc\u09c7\u099b\u09c7!"
+ }
+ },
+ "feedback": {
+ "positive": "\u09b8\u09b9\u09be\u09af\u09bc\u0995",
+ "negative": "\u09b8\u09b9\u09be\u09af\u09bc\u0995 \u09a8\u09af\u09bc",
+ "edit": "\u09aa\u09cd\u09b0\u09a4\u09bf\u0995\u09cd\u09b0\u09bf\u09af\u09bc\u09be \u09b8\u09ae\u09cd\u09aa\u09be\u09a6\u09a8\u09be \u0995\u09b0\u09c1\u09a8",
+ "dialog": {
+ "title": "\u09ae\u09a8\u09cd\u09a4\u09ac\u09cd\u09af \u09af\u09cb\u0997 \u0995\u09b0\u09c1\u09a8",
+ "submit": "\u09aa\u09cd\u09b0\u09a4\u09bf\u0995\u09cd\u09b0\u09bf\u09af\u09bc\u09be \u099c\u09ae\u09be \u09a6\u09bf\u09a8"
+ },
+ "status": {
+ "updating": "\u09b9\u09be\u09b2\u09a8\u09be\u0997\u09be\u09a6 \u0995\u09b0\u09be \u09b9\u099a\u09cd\u099b\u09c7",
+ "updated": "\u09aa\u09cd\u09b0\u09a4\u09bf\u0995\u09cd\u09b0\u09bf\u09af\u09bc\u09be \u09b9\u09be\u09b2\u09a8\u09be\u0997\u09be\u09a6 \u0995\u09b0\u09be \u09b9\u09af\u09bc\u09c7\u099b\u09c7"
+ }
+ }
+ },
+ "history": {
+ "title": "\u09b8\u09b0\u09cd\u09ac\u09b6\u09c7\u09b7 \u0987\u09a8\u09aa\u09c1\u099f",
+ "empty": "\u0995\u09cb\u09a8\u09cb \u09a4\u09a5\u09cd\u09af \u09a8\u09c7\u0987...",
+ "show": "\u0987\u09a4\u09bf\u09b9\u09be\u09b8 \u09a6\u09c7\u0996\u09c1\u09a8"
+ },
+ "settings": {
+ "title": "\u09b8\u09c7\u099f\u09bf\u0982\u09b8 \u09aa\u09cd\u09af\u09be\u09a8\u09c7\u09b2"
+ },
+ "watermark": "\u098f\u09b2\u098f\u09b2\u098f\u09ae \u09ad\u09c1\u09b2 \u0995\u09b0\u09a4\u09c7 \u09aa\u09be\u09b0\u09c7\u0964 \u0997\u09c1\u09b0\u09c1\u09a4\u09cd\u09ac\u09aa\u09c2\u09b0\u09cd\u09a3 \u09a4\u09a5\u09cd\u09af \u09af\u09be\u099a\u09be\u0987 \u0995\u09b0\u09be\u09b0 \u0995\u09a5\u09be \u09ac\u09bf\u09ac\u09c7\u099a\u09a8\u09be \u0995\u09b0\u09c1\u09a8\u0964"
+ },
+ "threadHistory": {
+ "sidebar": {
+ "title": "\u09aa\u09c2\u09b0\u09cd\u09ac\u09ac\u09b0\u09cd\u09a4\u09c0 \u099a\u09cd\u09af\u09be\u099f",
+ "filters": {
+ "search": "\u0985\u09a8\u09c1\u09b8\u09a8\u09cd\u09a7\u09be\u09a8",
+ "placeholder": "Search conversations..."
+ },
+ "timeframes": {
+ "today": "\u0986\u099c",
+ "yesterday": "\u0997\u09a4\u0995\u09be\u09b2",
+ "previous7days": "\u0997\u09a4 \u09ed \u09a6\u09bf\u09a8",
+ "previous30days": "\u0997\u09a4 \u09e9\u09e6 \u09a6\u09bf\u09a8"
+ },
+ "empty": "\u0995\u09cb\u09a8\u09cb \u09a5\u09cd\u09b0\u09c7\u09a1 \u09aa\u09be\u0993\u09af\u09bc\u09be \u09af\u09be\u09af\u09bc\u09a8\u09bf",
+ "actions": {
+ "close": "\u09b8\u09be\u0987\u09a1\u09ac\u09be\u09b0 \u09ac\u09a8\u09cd\u09a7 \u0995\u09b0\u09c1\u09a8",
+ "open": "\u09b8\u09be\u0987\u09a1\u09ac\u09be\u09b0 \u0996\u09c1\u09b2\u09c1\u09a8"
+ }
+ },
+ "thread": {
+ "untitled": "\u09b6\u09bf\u09b0\u09cb\u09a8\u09be\u09ae\u09b9\u09c0\u09a8 \u0986\u09b2\u09cb\u099a\u09a8\u09be",
+ "menu": {
+ "rename": "Rename",
+ "delete": "Delete"
+ },
+ "actions": {
+ "delete": {
+ "title": "\u09ae\u09c1\u099b\u09c7 \u09ab\u09c7\u09b2\u09be \u09a8\u09bf\u09b6\u09cd\u099a\u09bf\u09a4 \u0995\u09b0\u09c1\u09a8",
+ "description": "\u098f\u099f\u09bf \u09a5\u09cd\u09b0\u09c7\u09a1 \u098f\u09ac\u0982 \u098f\u09b0 \u09ac\u09be\u09b0\u09cd\u09a4\u09be \u0993 \u0989\u09aa\u09be\u09a6\u09be\u09a8\u0997\u09c1\u09b2\u09bf \u09ae\u09c1\u099b\u09c7 \u09ab\u09c7\u09b2\u09ac\u09c7\u0964 \u098f\u0987 \u0995\u09be\u099c\u099f\u09bf \u09aa\u09c2\u09b0\u09cd\u09ac\u09be\u09ac\u09b8\u09cd\u09a5\u09be\u09af\u09bc \u09ab\u09c7\u09b0\u09be\u09a8\u09cb \u09af\u09be\u09ac\u09c7 \u09a8\u09be",
+ "success": "\u099a\u09cd\u09af\u09be\u099f \u09ae\u09c1\u099b\u09c7 \u09ab\u09c7\u09b2\u09be \u09b9\u09af\u09bc\u09c7\u099b\u09c7",
+ "inProgress": "\u099a\u09cd\u09af\u09be\u099f \u09ae\u09c1\u099b\u09c7 \u09ab\u09c7\u09b2\u09be \u09b9\u099a\u09cd\u099b\u09c7"
+ },
+ "rename": {
+ "title": "\u09a5\u09cd\u09b0\u09c7\u09a1\u09c7\u09b0 \u09a8\u09be\u09ae \u09aa\u09b0\u09bf\u09ac\u09b0\u09cd\u09a4\u09a8 \u0995\u09b0\u09c1\u09a8",
+ "description": "\u098f\u0987 \u09a5\u09cd\u09b0\u09c7\u09a1\u09c7\u09b0 \u099c\u09a8\u09cd\u09af \u098f\u0995\u099f\u09bf \u09a8\u09a4\u09c1\u09a8 \u09a8\u09be\u09ae \u09a6\u09bf\u09a8",
+ "form": {
+ "name": {
+ "label": "\u09a8\u09be\u09ae",
+ "placeholder": "\u09a8\u09a4\u09c1\u09a8 \u09a8\u09be\u09ae \u09b2\u09bf\u0996\u09c1\u09a8"
+ }
+ },
+ "success": "\u09a5\u09cd\u09b0\u09c7\u09a1\u09c7\u09b0 \u09a8\u09be\u09ae \u09aa\u09b0\u09bf\u09ac\u09b0\u09cd\u09a4\u09a8 \u0995\u09b0\u09be \u09b9\u09af\u09bc\u09c7\u099b\u09c7!",
+ "inProgress": "\u09a5\u09cd\u09b0\u09c7\u09a1\u09c7\u09b0 \u09a8\u09be\u09ae \u09aa\u09b0\u09bf\u09ac\u09b0\u09cd\u09a4\u09a8 \u0995\u09b0\u09be \u09b9\u099a\u09cd\u099b\u09c7"
+ }
+ }
+ }
+ },
+ "navigation": {
+ "header": {
+ "chat": "\u099a\u09cd\u09af\u09be\u099f",
+ "readme": "\u09b0\u09bf\u09a1\u09ae\u09bf",
+ "theme": {
+ "light": "Light Theme",
+ "dark": "Dark Theme",
+ "system": "Follow System"
+ }
+ },
+ "newChat": {
+ "button": "\u09a8\u09a4\u09c1\u09a8 \u099a\u09cd\u09af\u09be\u099f",
+ "dialog": {
+ "title": "\u09a8\u09a4\u09c1\u09a8 \u099a\u09cd\u09af\u09be\u099f \u09a4\u09c8\u09b0\u09bf \u0995\u09b0\u09c1\u09a8",
+ "description": "\u098f\u099f\u09bf \u0986\u09aa\u09a8\u09be\u09b0 \u09ac\u09b0\u09cd\u09a4\u09ae\u09be\u09a8 \u099a\u09cd\u09af\u09be\u099f \u0987\u09a4\u09bf\u09b9\u09be\u09b8 \u09ae\u09c1\u099b\u09c7 \u09ab\u09c7\u09b2\u09ac\u09c7\u0964 \u0986\u09aa\u09a8\u09bf \u0995\u09bf \u099a\u09be\u09b2\u09bf\u09af\u09bc\u09c7 \u09af\u09c7\u09a4\u09c7 \u099a\u09be\u09a8?",
+ "tooltip": "\u09a8\u09a4\u09c1\u09a8 \u099a\u09cd\u09af\u09be\u099f"
+ }
+ },
+ "user": {
+ "menu": {
+ "settings": "\u09b8\u09c7\u099f\u09bf\u0982\u09b8",
+ "settingsKey": "S",
+ "apiKeys": "\u098f\u09aa\u09bf\u0986\u0987 \u0995\u09c0",
+ "logout": "\u09b2\u0997\u0986\u0989\u099f"
+ }
+ }
+ },
+ "apiKeys": {
+ "title": "\u09aa\u09cd\u09b0\u09af\u09bc\u09cb\u099c\u09a8\u09c0\u09af\u09bc \u098f\u09aa\u09bf\u0986\u0987 \u0995\u09c0",
+ "description": "\u098f\u0987 \u0985\u09cd\u09af\u09be\u09aa\u09cd\u09b2\u09bf\u0995\u09c7\u09b6\u09a8 \u09ac\u09cd\u09af\u09ac\u09b9\u09be\u09b0 \u0995\u09b0\u09a4\u09c7 \u09a8\u09bf\u09ae\u09cd\u09a8\u09b2\u09bf\u0996\u09bf\u09a4 \u098f\u09aa\u09bf\u0986\u0987 \u0995\u09c0 \u09aa\u09cd\u09b0\u09af\u09bc\u09cb\u099c\u09a8\u0964 \u0995\u09c0\u0997\u09c1\u09b2\u09bf \u0986\u09aa\u09a8\u09be\u09b0 \u09a1\u09bf\u09ad\u09be\u0987\u09b8\u09c7\u09b0 \u09b2\u09cb\u0995\u09be\u09b2 \u09b8\u09cd\u099f\u09cb\u09b0\u09c7\u099c\u09c7 \u09b8\u0982\u09b0\u0995\u09cd\u09b7\u09bf\u09a4 \u09a5\u09be\u0995\u09c7\u0964",
+ "success": {
+ "saved": "\u09b8\u09ab\u09b2\u09ad\u09be\u09ac\u09c7 \u09b8\u0982\u09b0\u0995\u09cd\u09b7\u09bf\u09a4 \u09b9\u09af\u09bc\u09c7\u099b\u09c7"
+ }
+ },
+ "alerts": {
+ "info": "Info",
+ "note": "Note",
+ "tip": "Tip",
+ "important": "Important",
+ "warning": "Warning",
+ "caution": "Caution",
+ "debug": "Debug",
+ "example": "Example",
+ "success": "Success",
+ "help": "Help",
+ "idea": "Idea",
+ "pending": "Pending",
+ "security": "Security",
+ "beta": "Beta",
+ "best-practice": "Best Practice"
+ }
+}
\ No newline at end of file
diff --git a/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/el-GR.json b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/el-GR.json
new file mode 100644
index 0000000..3de1128
--- /dev/null
+++ b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/el-GR.json
@@ -0,0 +1,219 @@
+{
+ "common": {
+ "actions": {
+ "cancel": "\u0386\u03ba\u03c5\u03c1\u03bf",
+ "confirm": "\u0395\u03c0\u03b9\u03b2\u03b5\u03b2\u03b1\u03af\u03c9\u03c3\u03b7",
+ "continue": "\u03a3\u03c5\u03bd\u03ad\u03c7\u03b5\u03b9\u03b1",
+ "goBack": "\u0395\u03c0\u03b9\u03c3\u03c4\u03c1\u03bf\u03c6\u03ae",
+ "reset": "\u0395\u03c0\u03b1\u03bd\u03b1\u03c6\u03bf\u03c1\u03ac",
+ "submit": "\u03a5\u03c0\u03bf\u03b2\u03bf\u03bb\u03ae"
+ },
+ "status": {
+ "loading": "\u03a6\u03cc\u03c1\u03c4\u03c9\u03c3\u03b7...",
+ "error": {
+ "default": "\u03a0\u03b1\u03c1\u03bf\u03c5\u03c3\u03b9\u03ac\u03c3\u03c4\u03b7\u03ba\u03b5 \u03c3\u03c6\u03ac\u03bb\u03bc\u03b1",
+ "serverConnection": "\u0394\u03b5\u03bd \u03ae\u03c4\u03b1\u03bd \u03b4\u03c5\u03bd\u03b1\u03c4\u03ae \u03b7 \u03b5\u03c0\u03b9\u03ba\u03bf\u03b9\u03bd\u03c9\u03bd\u03af\u03b1 \u03bc\u03b5 \u03c4\u03bf\u03bd \u03b4\u03b9\u03b1\u03ba\u03bf\u03bc\u03b9\u03c3\u03c4\u03ae"
+ }
+ }
+ },
+ "auth": {
+ "login": {
+ "title": "\u03a3\u03c5\u03bd\u03b4\u03b5\u03b8\u03b5\u03af\u03c4\u03b5 \u03b3\u03b9\u03b1 \u03bd\u03b1 \u03b1\u03c0\u03bf\u03ba\u03c4\u03ae\u03c3\u03b5\u03c4\u03b5 \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7 \u03c3\u03c4\u03b7\u03bd \u03b5\u03c6\u03b1\u03c1\u03bc\u03bf\u03b3\u03ae",
+ "form": {
+ "email": {
+ "label": "\u0394\u03b9\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7 \u03b7\u03bb\u03b5\u03ba\u03c4\u03c1\u03bf\u03bd\u03b9\u03ba\u03bf\u03cd \u03c4\u03b1\u03c7\u03c5\u03b4\u03c1\u03bf\u03bc\u03b5\u03af\u03bf\u03c5",
+ "required": "\u03a4\u03bf email \u03b5\u03af\u03bd\u03b1\u03b9 \u03c5\u03c0\u03bf\u03c7\u03c1\u03b5\u03c9\u03c4\u03b9\u03ba\u03cc \u03c0\u03b5\u03b4\u03af\u03bf"
+ },
+ "password": {
+ "label": "\u039a\u03c9\u03b4\u03b9\u03ba\u03cc\u03c2 \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2",
+ "required": "\u039f \u03ba\u03c9\u03b4\u03b9\u03ba\u03cc\u03c2 \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2 \u03b5\u03af\u03bd\u03b1\u03b9 \u03c5\u03c0\u03bf\u03c7\u03c1\u03b5\u03c9\u03c4\u03b9\u03ba\u03cc \u03c0\u03b5\u03b4\u03af\u03bf"
+ },
+ "actions": {
+ "signin": "\u03a3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7"
+ },
+ "alternativeText": {
+ "or": "\u03ae"
+ }
+ },
+ "errors": {
+ "default": "\u0394\u03b5\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03b4\u03c5\u03bd\u03b1\u03c4\u03ae \u03b7 \u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7",
+ "signin": "\u0394\u03bf\u03ba\u03b9\u03bc\u03ac\u03c3\u03c4\u03b5 \u03bd\u03b1 \u03c3\u03c5\u03bd\u03b4\u03b5\u03b8\u03b5\u03af\u03c4\u03b5 \u03bc\u03b5 \u03b4\u03b9\u03b1\u03c6\u03bf\u03c1\u03b5\u03c4\u03b9\u03ba\u03cc \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc",
+ "oauthSignin": "\u0394\u03bf\u03ba\u03b9\u03bc\u03ac\u03c3\u03c4\u03b5 \u03bd\u03b1 \u03c3\u03c5\u03bd\u03b4\u03b5\u03b8\u03b5\u03af\u03c4\u03b5 \u03bc\u03b5 \u03b4\u03b9\u03b1\u03c6\u03bf\u03c1\u03b5\u03c4\u03b9\u03ba\u03cc \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc",
+ "redirectUriMismatch": "\u039f \u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03bc\u03bf\u03c2 \u03b1\u03bd\u03b1\u03ba\u03b1\u03c4\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7\u03c2 \u03b4\u03b5\u03bd \u03c4\u03b1\u03b9\u03c1\u03b9\u03ac\u03b6\u03b5\u03b9 \u03bc\u03b5 \u03c4\u03b7 \u03c1\u03cd\u03b8\u03bc\u03b9\u03c3\u03b7 \u03c4\u03b7\u03c2 \u03b1\u03c5\u03b8\u03b5\u03bd\u03c4\u03b9\u03ba\u03bf\u03c0\u03bf\u03b9\u03ae\u03c3\u03b7\u03c2 \u03c4\u03b7\u03c2 \u03b5\u03c6\u03b1\u03c1\u03bc\u03bf\u03b3\u03ae\u03c2",
+ "oauthCallback": "\u0394\u03bf\u03ba\u03b9\u03bc\u03ac\u03c3\u03c4\u03b5 \u03bd\u03b1 \u03c3\u03c5\u03bd\u03b4\u03b5\u03b8\u03b5\u03af\u03c4\u03b5 \u03bc\u03b5 \u03b4\u03b9\u03b1\u03c6\u03bf\u03c1\u03b5\u03c4\u03b9\u03ba\u03cc \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc",
+ "oauthCreateAccount": "\u0394\u03bf\u03ba\u03b9\u03bc\u03ac\u03c3\u03c4\u03b5 \u03bd\u03b1 \u03c3\u03c5\u03bd\u03b4\u03b5\u03b8\u03b5\u03af\u03c4\u03b5 \u03bc\u03b5 \u03b4\u03b9\u03b1\u03c6\u03bf\u03c1\u03b5\u03c4\u03b9\u03ba\u03cc \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc",
+ "emailCreateAccount": "\u0394\u03bf\u03ba\u03b9\u03bc\u03ac\u03c3\u03c4\u03b5 \u03bd\u03b1 \u03c3\u03c5\u03bd\u03b4\u03b5\u03b8\u03b5\u03af\u03c4\u03b5 \u03bc\u03b5 \u03b4\u03b9\u03b1\u03c6\u03bf\u03c1\u03b5\u03c4\u03b9\u03ba\u03cc \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc",
+ "callback": "\u0394\u03bf\u03ba\u03b9\u03bc\u03ac\u03c3\u03c4\u03b5 \u03bd\u03b1 \u03c3\u03c5\u03bd\u03b4\u03b5\u03b8\u03b5\u03af\u03c4\u03b5 \u03bc\u03b5 \u03b4\u03b9\u03b1\u03c6\u03bf\u03c1\u03b5\u03c4\u03b9\u03ba\u03cc \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc",
+ "oauthAccountNotLinked": "\u0393\u03b9\u03b1 \u03bd\u03b1 \u03b5\u03c0\u03b9\u03b2\u03b5\u03b2\u03b1\u03b9\u03ce\u03c3\u03b5\u03c4\u03b5 \u03c4\u03b7\u03bd \u03c4\u03b1\u03c5\u03c4\u03cc\u03c4\u03b7\u03c4\u03ac \u03c3\u03b1\u03c2, \u03c3\u03c5\u03bd\u03b4\u03b5\u03b8\u03b5\u03af\u03c4\u03b5 \u03bc\u03b5 \u03c4\u03bf\u03bd \u03af\u03b4\u03b9\u03bf \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc \u03c0\u03bf\u03c5 \u03c7\u03c1\u03b7\u03c3\u03b9\u03bc\u03bf\u03c0\u03bf\u03b9\u03ae\u03c3\u03b1\u03c4\u03b5 \u03b1\u03c1\u03c7\u03b9\u03ba\u03ac",
+ "emailSignin": "\u0394\u03b5\u03bd \u03ae\u03c4\u03b1\u03bd \u03b4\u03c5\u03bd\u03b1\u03c4\u03ae \u03b7 \u03b1\u03c0\u03bf\u03c3\u03c4\u03bf\u03bb\u03ae \u03c4\u03bf\u03c5 email",
+ "emailVerify": "\u03a0\u03b1\u03c1\u03b1\u03ba\u03b1\u03bb\u03ce \u03b5\u03c0\u03b1\u03bb\u03b7\u03b8\u03b5\u03cd\u03c3\u03c4\u03b5 \u03c4\u03b7\u03bd \u03b4\u03b9\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7 \u03b7\u03bb\u03b5\u03ba\u03c4\u03c1\u03bf\u03bd\u03b9\u03ba\u03bf\u03cd \u03c4\u03b1\u03c7\u03c5\u03b4\u03c1\u03bf\u03bc\u03b5\u03af\u03bf\u03c5 \u03c3\u03b1\u03c2, \u03ad\u03bd\u03b1 \u03bd\u03ad\u03bf email \u03c3\u03b1\u03c2 \u03ad\u03c7\u03b5\u03b9 \u03c3\u03c4\u03b1\u03bb\u03b5\u03af",
+ "credentialsSignin": "\u0397 \u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7 \u03b1\u03c0\u03ad\u03c4\u03c5\u03c7\u03b5. \u0395\u03bb\u03ad\u03b3\u03be\u03c4\u03b5 \u03cc\u03c4\u03b9 \u03c4\u03b1 \u03c3\u03c4\u03bf\u03b9\u03c7\u03b5\u03af\u03b1 \u03c0\u03bf\u03c5 \u03b4\u03ce\u03c3\u03b1\u03c4\u03b5 \u03b5\u03af\u03bd\u03b1\u03b9 \u03c3\u03c9\u03c3\u03c4\u03ac",
+ "sessionRequired": "\u03a0\u03b1\u03c1\u03b1\u03ba\u03b1\u03bb\u03ce \u03c3\u03c5\u03bd\u03b4\u03b5\u03b8\u03b5\u03af\u03c4\u03b5 \u03b3\u03b9\u03b1 \u03bd\u03b1 \u03b1\u03c0\u03bf\u03ba\u03c4\u03ae\u03c3\u03b5\u03c4\u03b5 \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7 \u03c3\u03b5 \u03b1\u03c5\u03c4\u03ae\u03bd \u03c4\u03b7 \u03c3\u03b5\u03bb\u03af\u03b4\u03b1"
+ }
+ },
+ "provider": {
+ "continue": "\u03a3\u03c5\u03bd\u03ad\u03c7\u03b5\u03b9\u03b1 \u03bc\u03b5 {{provider}}"
+ }
+ },
+ "chat": {
+ "input": {
+ "placeholder": "\u03a0\u03bb\u03b7\u03ba\u03c4\u03c1\u03bf\u03bb\u03bf\u03b3\u03ae\u03c3\u03c4\u03b5 \u03c4\u03bf \u03bc\u03ae\u03bd\u03c5\u03bc\u03ac \u03c3\u03b1\u03c2 \u03b5\u03b4\u03ce...",
+ "actions": {
+ "send": "\u0391\u03c0\u03bf\u03c3\u03c4\u03bf\u03bb\u03ae \u03bc\u03b7\u03bd\u03cd\u03bc\u03b1\u03c4\u03bf\u03c2",
+ "stop": "\u0394\u03b9\u03b1\u03ba\u03bf\u03c0\u03ae \u03b5\u03c1\u03b3\u03b1\u03c3\u03af\u03b1\u03c2",
+ "attachFiles": "\u0395\u03c0\u03b9\u03c3\u03cd\u03bd\u03b1\u03c8\u03b7 \u03b1\u03c1\u03c7\u03b5\u03af\u03c9\u03bd"
+ }
+ },
+ "commands": {
+ "button": "\u0395\u03c1\u03b3\u03b1\u03bb\u03b5\u03af\u03b1",
+ "changeTool": "\u0391\u03bb\u03bb\u03b1\u03b3\u03ae \u0395\u03c1\u03b3\u03b1\u03bb\u03b5\u03af\u03bf\u03c5",
+ "availableTools": "\u0394\u03b9\u03b1\u03b8\u03ad\u03c3\u03b9\u03bc\u03b1 \u0395\u03c1\u03b3\u03b1\u03bb\u03b5\u03af\u03b1"
+ },
+ "speech": {
+ "start": "\u0388\u03bd\u03b1\u03c1\u03be\u03b7 \u03b5\u03b3\u03b3\u03c1\u03b1\u03c6\u03ae\u03c2",
+ "stop": "\u0394\u03b9\u03b1\u03ba\u03bf\u03c0\u03ae \u03b5\u03b3\u03b3\u03c1\u03b1\u03c6\u03ae\u03c2",
+ "connecting": "\u03a3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7"
+ },
+ "fileUpload": {
+ "dragDrop": "\u03a3\u03cd\u03c1\u03b5\u03c4\u03b5 \u03b1\u03c1\u03c7\u03b5\u03af\u03b1 \u03b5\u03b4\u03ce",
+ "browse": "\u0391\u03bd\u03b1\u03b6\u03ae\u03c4\u03b7\u03c3\u03b7 \u03b1\u03c1\u03c7\u03b5\u03af\u03c9\u03bd",
+ "sizeLimit": "\u038c\u03c1\u03b9\u03bf:",
+ "errors": {
+ "failed": "\u0397 \u03bc\u03b5\u03c4\u03b1\u03c6\u03cc\u03c1\u03c4\u03c9\u03c3\u03b7 \u03b1\u03c0\u03ad\u03c4\u03c5\u03c7\u03b5",
+ "cancelled": "\u0391\u03ba\u03c5\u03c1\u03ce\u03b8\u03b7\u03ba\u03b5 \u03b7 \u03bc\u03b5\u03c4\u03b1\u03c6\u03cc\u03c1\u03c4\u03c9\u03c3\u03b7 \u03c4\u03bf\u03c5"
+ }
+ },
+ "messages": {
+ "status": {
+ "using": "\u039c\u03b5 \u03c4\u03b7 \u03c7\u03c1\u03ae\u03c3\u03b7",
+ "used": "\u03a7\u03c1\u03b7\u03c3\u03b9\u03bc\u03bf\u03c0\u03bf\u03b9\u03ae\u03b8\u03b7\u03ba\u03b5"
+ },
+ "actions": {
+ "copy": {
+ "button": "\u0391\u03bd\u03c4\u03b9\u03b3\u03c1\u03b1\u03c6\u03ae \u03c3\u03c4\u03bf \u03c0\u03c1\u03cc\u03c7\u03b5\u03b9\u03c1\u03bf",
+ "success": "\u0391\u03bd\u03c4\u03b9\u03b3\u03c1\u03ac\u03c6\u03b7\u03ba\u03b5!"
+ }
+ },
+ "feedback": {
+ "positive": "\u03a7\u03c1\u03ae\u03c3\u03b9\u03bc\u03bf\u03c2",
+ "negative": "\u039c\u03b7 \u03c7\u03c1\u03ae\u03c3\u03b9\u03bc\u03bf\u03c2",
+ "edit": "\u0395\u03c0\u03b5\u03be\u03b5\u03c1\u03b3\u03b1\u03c3\u03af\u03b1 \u03c3\u03c7\u03bf\u03bb\u03af\u03c9\u03bd",
+ "dialog": {
+ "title": "\u03a0\u03c1\u03bf\u03c3\u03b8\u03ae\u03ba\u03b7 \u03c3\u03c7\u03bf\u03bb\u03af\u03bf\u03c5",
+ "submit": "\u03a5\u03c0\u03bf\u03b2\u03bf\u03bb\u03ae \u03c3\u03c7\u03bf\u03bb\u03af\u03c9\u03bd"
+ },
+ "status": {
+ "updating": "\u0395\u03bd\u03b7\u03bc\u03b5\u03c1\u03ce\u03bd\u03b5\u03c4\u03b1\u03b9",
+ "updated": "\u03a4\u03b1 \u03c3\u03c7\u03cc\u03bb\u03b9\u03b1 \u03b5\u03bd\u03b7\u03bc\u03b5\u03c1\u03ce\u03b8\u03b7\u03ba\u03b1\u03bd"
+ }
+ }
+ },
+ "history": {
+ "title": "\u03a4\u03b5\u03bb\u03b5\u03c5\u03c4\u03b1\u03af\u03b5\u03c2 \u03b5\u03b9\u03c3\u03b1\u03b3\u03c9\u03b3\u03ad\u03c2",
+ "empty": "\u03a4\u03cc\u03c3\u03bf \u03ac\u03b4\u03b5\u03b9\u03bf...",
+ "show": "\u03a0\u03c1\u03bf\u03b2\u03bf\u03bb\u03ae \u03b9\u03c3\u03c4\u03bf\u03c1\u03b9\u03ba\u03bf\u03cd"
+ },
+ "settings": {
+ "title": "\u03a0\u03af\u03bd\u03b1\u03ba\u03b1\u03c2 \u03c1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03c9\u03bd"
+ },
+ "watermark": "\u03a4\u03b1 \u039c\u0393\u039c \u03bc\u03c0\u03bf\u03c1\u03b5\u03af \u03bd\u03b1 \u03ba\u03ac\u03bd\u03bf\u03c5\u03bd \u03bb\u03ac\u03b8\u03b7. \u0395\u03bb\u03ad\u03b3\u03be\u03c4\u03b5 \u03c3\u03b7\u03bc\u03b1\u03bd\u03c4\u03b9\u03ba\u03ad\u03c2 \u03c0\u03bb\u03b7\u03c1\u03bf\u03c6\u03bf\u03c1\u03af\u03b5\u03c2."
+ },
+ "threadHistory": {
+ "sidebar": {
+ "title": "\u03a0\u03b1\u03bb\u03b1\u03b9\u03cc\u03c4\u03b5\u03c1\u03b5\u03c2 \u03c3\u03c5\u03bd\u03bf\u03bc\u03b9\u03bb\u03af\u03b5\u03c2",
+ "filters": {
+ "search": "\u0391\u03bd\u03b1\u03b6\u03ae\u03c4\u03b7\u03c3\u03b7",
+ "placeholder": "\u0391\u03bd\u03b1\u03b6\u03ae\u03c4\u03b7\u03c3\u03b7 \u03c3\u03c5\u03bd\u03bf\u03bc\u03b9\u03bb\u03b9\u03ce\u03bd..."
+ },
+ "timeframes": {
+ "today": "\u03a3\u03ae\u03bc\u03b5\u03c1\u03b1",
+ "yesterday": "\u03a7\u03b8\u03b5\u03c2",
+ "previous7days": "\u03a0\u03c1\u03bf\u03b7\u03b3\u03bf\u03cd\u03bc\u03b5\u03bd\u03b5\u03c2 7 \u03b7\u03bc\u03ad\u03c1\u03b5\u03c2",
+ "previous30days": "\u03a0\u03c1\u03bf\u03b7\u03b3\u03bf\u03cd\u03bc\u03b5\u03bd\u03b5\u03c2 30 \u03b7\u03bc\u03ad\u03c1\u03b5\u03c2"
+ },
+ "empty": "\u0394\u03b5\u03bd \u03b2\u03c1\u03ad\u03b8\u03b7\u03ba\u03b1\u03bd \u03bd\u03ae\u03bc\u03b1\u03c4\u03b1",
+ "actions": {
+ "close": "\u039a\u03bb\u03b5\u03af\u03c3\u03b9\u03bc\u03bf \u03c0\u03bb\u03b1\u03ca\u03bd\u03ae\u03c2 \u03b3\u03c1\u03b1\u03bc\u03bc\u03ae\u03c2",
+ "open": "\u0386\u03bd\u03bf\u03b9\u03b3\u03bc\u03b1 \u03c0\u03bb\u03b1\u03ca\u03bd\u03ae\u03c2 \u03b3\u03c1\u03b1\u03bc\u03bc\u03ae\u03c2"
+ }
+ },
+ "thread": {
+ "untitled": "\u03a3\u03c5\u03bd\u03bf\u03bc\u03b9\u03bb\u03af\u03b1 \u03c7\u03c9\u03c1\u03af\u03c2 \u03c4\u03af\u03c4\u03bb\u03bf",
+ "menu": {
+ "rename": "\u039c\u03b5\u03c4\u03bf\u03bd\u03bf\u03bc\u03b1\u03c3\u03af\u03b1",
+ "delete": "\u0394\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae"
+ },
+ "actions": {
+ "delete": {
+ "title": "\u0395\u03c0\u03b9\u03b2\u03b5\u03b2\u03b1\u03af\u03c9\u03c3\u03b7 \u03b4\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae\u03c2",
+ "description": "\u0391\u03c5\u03c4\u03cc \u03b8\u03b1 \u03b4\u03b9\u03b1\u03b3\u03c1\u03ac\u03c8\u03b5\u03b9 \u03c4\u03bf \u03bd\u03ae\u03bc\u03b1 \u03ba\u03b1\u03b8\u03ce\u03c2 \u03ba\u03b1\u03b9 \u03c4\u03b1 \u03bc\u03b7\u03bd\u03cd\u03bc\u03b1\u03c4\u03b1 \u03ba\u03b1\u03b9 \u03c4\u03b1 \u03c3\u03c4\u03bf\u03b9\u03c7\u03b5\u03af\u03b1 \u03c4\u03bf\u03c5. \u0391\u03c5\u03c4\u03ae \u03b7 \u03b5\u03bd\u03ad\u03c1\u03b3\u03b5\u03b9\u03b1 \u03b4\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03b5\u03af \u03bd\u03b1 \u03b1\u03bd\u03b1\u03b9\u03c1\u03b5\u03b8\u03b5\u03af.",
+ "success": "\u0397 \u03c3\u03c5\u03bd\u03bf\u03bc\u03b9\u03bb\u03af\u03b1 \u03b4\u03b9\u03b1\u03b3\u03c1\u03ac\u03c6\u03b7\u03ba\u03b5",
+ "inProgress": "\u0394\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae \u03c3\u03c5\u03bd\u03bf\u03bc\u03b9\u03bb\u03af\u03b1\u03c2"
+ },
+ "rename": {
+ "title": "\u039c\u03b5\u03c4\u03bf\u03bd\u03bf\u03bc\u03b1\u03c3\u03af\u03b1 \u039d\u03ae\u03bc\u03b1\u03c4\u03bf\u03c2",
+ "description": "\u0395\u03b9\u03c3\u03b1\u03b3\u03ac\u03b3\u03b5\u03c4\u03b5 \u03ad\u03bd\u03b1 \u03bd\u03ad\u03bf \u03cc\u03bd\u03bf\u03bc\u03b1 \u03b3\u03b9\u03b1 \u03b1\u03c5\u03c4\u03cc \u03c4\u03bf \u03bd\u03ae\u03bc\u03b1",
+ "form": {
+ "name": {
+ "label": "\u038c\u03bd\u03bf\u03bc\u03b1",
+ "placeholder": "\u0395\u03b9\u03c3\u03b1\u03b3\u03ac\u03b3\u03b5\u03c4\u03b5 \u03bd\u03ad\u03bf \u03cc\u03bd\u03bf\u03bc\u03b1"
+ }
+ },
+ "success": "\u03a4\u03bf \u03bd\u03ae\u03bc\u03b1 \u03bc\u03b5\u03c4\u03bf\u03bd\u03bf\u03bc\u03ac\u03c3\u03c4\u03b7\u03ba\u03b5!",
+ "inProgress": "\u039c\u03b5\u03c4\u03bf\u03bd\u03bf\u03bc\u03b1\u03c3\u03af\u03b1 \u039d\u03ae\u03bc\u03b1\u03c4\u03bf\u03c2"
+ }
+ }
+ }
+ },
+ "navigation": {
+ "header": {
+ "chat": "\u03a3\u03c5\u03bd\u03bf\u03bc\u03b9\u03bb\u03af\u03b1",
+ "readme": "\u0394\u03b9\u03ac\u03b2\u03b1\u03c3\u03ad \u03bc\u03b5",
+ "theme": {
+ "light": "\u03a6\u03c9\u03c4\u03b5\u03b9\u03bd\u03cc \u0398\u03ad\u03bc\u03b1",
+ "dark": "\u03a3\u03ba\u03bf\u03c4\u03b5\u03b9\u03bd\u03cc \u03b8\u03ad\u03bc\u03b1",
+ "system": "\u0391\u03ba\u03bf\u03bb\u03bf\u03c5\u03b8\u03ae\u03c3\u03c4\u03b5 \u03c4\u03bf \u03c3\u03cd\u03c3\u03c4\u03b7\u03bc\u03b1"
+ }
+ },
+ "newChat": {
+ "button": "\u039d\u03ad\u03b1 \u03a3\u03c5\u03bd\u03bf\u03bc\u03b9\u03bb\u03af\u03b1",
+ "dialog": {
+ "title": "\u0394\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03af\u03b1 \u039d\u03ad\u03b1\u03c2 \u03a3\u03c5\u03bd\u03bf\u03bc\u03b9\u03bb\u03af\u03b1\u03c2",
+ "description": "\u0391\u03c5\u03c4\u03cc \u03b8\u03b1 \u03b4\u03b9\u03b1\u03b3\u03c1\u03ac\u03c8\u03b5\u03b9 \u03c4\u03bf \u03c4\u03c1\u03ad\u03c7\u03bf\u03bd \u03b9\u03c3\u03c4\u03bf\u03c1\u03b9\u03ba\u03cc \u03c3\u03c5\u03bd\u03bf\u03bc\u03b9\u03bb\u03af\u03b1\u03c2 \u03c3\u03b1\u03c2. \u0395\u03af\u03c3\u03c4\u03b5 \u03b2\u03ad\u03b2\u03b1\u03b9\u03bf\u03b9 \u03cc\u03c4\u03b9 \u03b8\u03ad\u03bb\u03b5\u03c4\u03b5 \u03bd\u03b1 \u03c3\u03c5\u03bd\u03b5\u03c7\u03af\u03c3\u03b5\u03c4\u03b5;",
+ "tooltip": "\u039d\u03ad\u03b1 \u03a3\u03c5\u03bd\u03bf\u03bc\u03b9\u03bb\u03af\u03b1"
+ }
+ },
+ "user": {
+ "menu": {
+ "settings": "\u03a1\u03c5\u03b8\u03bc\u03af\u03c3\u03b5\u03b9\u03c2",
+ "settingsKey": "S",
+ "apiKeys": "\u039a\u03bb\u03b5\u03b9\u03b4\u03b9\u03ac API",
+ "logout": "\u0391\u03c0\u03bf\u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7"
+ }
+ }
+ },
+ "apiKeys": {
+ "title": "\u0391\u03c0\u03b1\u03b9\u03c4\u03bf\u03cd\u03bc\u03b5\u03bd\u03b1 \u03ba\u03bb\u03b5\u03b9\u03b4\u03b9\u03ac API",
+ "description": "\u0393\u03b9\u03b1 \u03bd\u03b1 \u03c7\u03c1\u03b7\u03c3\u03b9\u03bc\u03bf\u03c0\u03bf\u03b9\u03ae\u03c3\u03b5\u03c4\u03b5 \u03b1\u03c5\u03c4\u03ae\u03bd \u03c4\u03b7\u03bd \u03b5\u03c6\u03b1\u03c1\u03bc\u03bf\u03b3\u03ae, \u03b1\u03c0\u03b1\u03b9\u03c4\u03bf\u03cd\u03bd\u03c4\u03b1\u03b9 \u03c4\u03b1 \u03b1\u03ba\u03cc\u03bb\u03bf\u03c5\u03b8\u03b1 \u03ba\u03bb\u03b5\u03b9\u03b4\u03b9\u03ac API. \u03a4\u03b1 \u03ba\u03bb\u03b5\u03b9\u03b4\u03b9\u03ac \u03b5\u03af\u03bd\u03b1\u03b9 \u03b1\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03c5\u03bc\u03ad\u03bd\u03b1 \u03c3\u03c4\u03bf\u03bd \u03c4\u03bf\u03c0\u03b9\u03ba\u03cc \u03c7\u03ce\u03c1\u03bf \u03b1\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b7\u03c2 \u03c4\u03b7\u03c2 \u03c3\u03c5\u03c3\u03ba\u03b5\u03c5\u03ae\u03c2 \u03c3\u03b1\u03c2.",
+ "success": {
+ "saved": "\u0391\u03c0\u03bf\u03b8\u03b7\u03ba\u03b5\u03cd\u03c4\u03b7\u03ba\u03b5 \u03bc\u03b5 \u03b5\u03c0\u03b9\u03c4\u03c5\u03c7\u03af\u03b1"
+ }
+ },
+ "alerts": {
+ "info": "\u03a0\u03bb\u03b7\u03c1\u03bf\u03c6\u03bf\u03c1\u03af\u03b5\u03c2",
+ "note": "\u03a3\u03b7\u03bc\u03b5\u03af\u03c9\u03c3\u03b7",
+ "tip": "\u03a3\u03c5\u03bc\u03b2\u03bf\u03c5\u03bb\u03ae",
+ "important": "\u03a3\u03b7\u03bc\u03b1\u03bd\u03c4\u03b9\u03ba\u03cc",
+ "warning": "\u03a0\u03c1\u03bf\u03b5\u03b9\u03b4\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03b7",
+ "caution": "\u03a0\u03c1\u03bf\u03c3\u03bf\u03c7\u03ae",
+ "debug": "\u0395\u03bd\u03c4\u03bf\u03c0\u03b9\u03c3\u03bc\u03cc\u03c2 \u03c3\u03c6\u03b1\u03bb\u03bc\u03ac\u03c4\u03c9\u03bd",
+ "example": "\u03a0\u03b1\u03c1\u03ac\u03b4\u03b5\u03b9\u03b3\u03bc\u03b1",
+ "success": "\u0395\u03c0\u03b9\u03c4\u03c5\u03c7\u03af\u03b1",
+ "help": "\u0392\u03bf\u03ae\u03b8\u03b5\u03b9\u03b1",
+ "idea": "\u0399\u03b4\u03ad\u03b1",
+ "pending": "\u03a3\u03b5 \u03b5\u03ba\u03ba\u03c1\u03b5\u03bc\u03cc\u03c4\u03b7\u03c4\u03b1",
+ "security": "\u0391\u03c3\u03c6\u03ac\u03bb\u03b5\u03b9\u03b1",
+ "beta": "Beta",
+ "best-practice": "\u0392\u03ad\u03bb\u03c4\u03b9\u03c3\u03c4\u03b7 \u03a0\u03c1\u03b1\u03ba\u03c4\u03b9\u03ba\u03ae"
+ }
+}
\ No newline at end of file
diff --git a/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/en-US.json b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/en-US.json
new file mode 100644
index 0000000..038c9a0
--- /dev/null
+++ b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/en-US.json
@@ -0,0 +1,219 @@
+{
+ "common": {
+ "actions": {
+ "cancel": "Cancel",
+ "confirm": "Confirm",
+ "continue": "Continue",
+ "goBack": "Go Back",
+ "reset": "Reset",
+ "submit": "Submit"
+ },
+ "status": {
+ "loading": "Loading...",
+ "error": {
+ "default": "An error occurred",
+ "serverConnection": "Could not reach the server"
+ }
+ }
+ },
+ "auth": {
+ "login": {
+ "title": "Login to access the app",
+ "form": {
+ "email": {
+ "label": "Email address",
+ "required": "email is a required field"
+ },
+ "password": {
+ "label": "Password",
+ "required": "password is a required field"
+ },
+ "actions": {
+ "signin": "Sign In"
+ },
+ "alternativeText": {
+ "or": "OR"
+ }
+ },
+ "errors": {
+ "default": "Unable to sign in",
+ "signin": "Try signing in with a different account",
+ "oauthSignin": "Try signing in with a different account",
+ "redirectUriMismatch": "The redirect URI is not matching the oauth app configuration",
+ "oauthCallback": "Try signing in with a different account",
+ "oauthCreateAccount": "Try signing in with a different account",
+ "emailCreateAccount": "Try signing in with a different account",
+ "callback": "Try signing in with a different account",
+ "oauthAccountNotLinked": "To confirm your identity, sign in with the same account you used originally",
+ "emailSignin": "The e-mail could not be sent",
+ "emailVerify": "Please verify your email, a new email has been sent",
+ "credentialsSignin": "Sign in failed. Check the details you provided are correct",
+ "sessionRequired": "Please sign in to access this page"
+ }
+ },
+ "provider": {
+ "continue": "Continue with {{provider}}"
+ }
+ },
+ "chat": {
+ "input": {
+ "placeholder": "Type your message here...",
+ "actions": {
+ "send": "Send message",
+ "stop": "Stop Task",
+ "attachFiles": "Attach files"
+ }
+ },
+ "commands": {
+ "button": "Tools",
+ "changeTool": "Change Tool",
+ "availableTools": "Available Tools"
+ },
+ "speech": {
+ "start": "Start recording",
+ "stop": "Stop recording",
+ "connecting": "Connecting"
+ },
+ "fileUpload": {
+ "dragDrop": "Drag and drop files here",
+ "browse": "Browse Files",
+ "sizeLimit": "Limit:",
+ "errors": {
+ "failed": "Failed to upload",
+ "cancelled": "Cancelled upload of"
+ }
+ },
+ "messages": {
+ "status": {
+ "using": "Using",
+ "used": "Used"
+ },
+ "actions": {
+ "copy": {
+ "button": "Copy to clipboard",
+ "success": "Copied!"
+ }
+ },
+ "feedback": {
+ "positive": "Helpful",
+ "negative": "Not helpful",
+ "edit": "Edit feedback",
+ "dialog": {
+ "title": "Add a comment",
+ "submit": "Submit feedback"
+ },
+ "status": {
+ "updating": "Updating",
+ "updated": "Feedback updated"
+ }
+ }
+ },
+ "history": {
+ "title": "Last Inputs",
+ "empty": "Such empty...",
+ "show": "Show history"
+ },
+ "settings": {
+ "title": "Settings panel"
+ },
+ "watermark": "LLMs can make mistakes. Check important info."
+ },
+ "threadHistory": {
+ "sidebar": {
+ "title": "Past Chats",
+ "filters": {
+ "search": "Search",
+ "placeholder": "Search conversations..."
+ },
+ "timeframes": {
+ "today": "Today",
+ "yesterday": "Yesterday",
+ "previous7days": "Previous 7 days",
+ "previous30days": "Previous 30 days"
+ },
+ "empty": "No threads found",
+ "actions": {
+ "close": "Close sidebar",
+ "open": "Open sidebar"
+ }
+ },
+ "thread": {
+ "untitled": "Untitled Conversation",
+ "menu": {
+ "rename": "Rename",
+ "delete": "Delete"
+ },
+ "actions": {
+ "delete": {
+ "title": "Confirm deletion",
+ "description": "This will delete the thread as well as its messages and elements. This action cannot be undone",
+ "success": "Chat deleted",
+ "inProgress": "Deleting chat"
+ },
+ "rename": {
+ "title": "Rename Thread",
+ "description": "Enter a new name for this thread",
+ "form": {
+ "name": {
+ "label": "Name",
+ "placeholder": "Enter new name"
+ }
+ },
+ "success": "Thread renamed!",
+ "inProgress": "Renaming thread"
+ }
+ }
+ }
+ },
+ "navigation": {
+ "header": {
+ "chat": "Chat",
+ "readme": "Readme",
+ "theme": {
+ "light": "Light Theme",
+ "dark": "Dark Theme",
+ "system": "Follow System"
+ }
+ },
+ "newChat": {
+ "button": "New Chat",
+ "dialog": {
+ "title": "Create New Chat",
+ "description": "This will clear your current chat history. Are you sure you want to continue?",
+ "tooltip": "New Chat"
+ }
+ },
+ "user": {
+ "menu": {
+ "settings": "Settings",
+ "settingsKey": "S",
+ "apiKeys": "API Keys",
+ "logout": "Logout"
+ }
+ }
+ },
+ "apiKeys": {
+ "title": "Required API Keys",
+ "description": "To use this app, the following API keys are required. The keys are stored on your device's local storage.",
+ "success": {
+ "saved": "Saved successfully"
+ }
+ },
+ "alerts": {
+ "info": "Info",
+ "note": "Note",
+ "tip": "Tip",
+ "important": "Important",
+ "warning": "Warning",
+ "caution": "Caution",
+ "debug": "Debug",
+ "example": "Example",
+ "success": "Success",
+ "help": "Help",
+ "idea": "Idea",
+ "pending": "Pending",
+ "security": "Security",
+ "beta": "Beta",
+ "best-practice": "Best Practice"
+ }
+}
\ No newline at end of file
diff --git a/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/fr-FR.json b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/fr-FR.json
new file mode 100644
index 0000000..60069b4
--- /dev/null
+++ b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/fr-FR.json
@@ -0,0 +1,219 @@
+{
+ "common": {
+ "actions": {
+ "cancel": "Annuler",
+ "confirm": "Confirmer",
+ "continue": "Continuer",
+ "goBack": "Retour",
+ "reset": "R\u00e9initialiser",
+ "submit": "Envoyer"
+ },
+ "status": {
+ "loading": "Chargement...",
+ "error": {
+ "default": "Une erreur est survenue",
+ "serverConnection": "Impossible de joindre le serveur"
+ }
+ }
+ },
+ "auth": {
+ "login": {
+ "title": "Connectez-vous pour acc\u00e9der \u00e0 l'application",
+ "form": {
+ "email": {
+ "label": "Adresse e-mail",
+ "required": "l'e-mail est un champ obligatoire"
+ },
+ "password": {
+ "label": "Mot de passe",
+ "required": "le mot de passe est un champ obligatoire"
+ },
+ "actions": {
+ "signin": "Se connecter"
+ },
+ "alternativeText": {
+ "or": "OU"
+ }
+ },
+ "errors": {
+ "default": "Impossible de se connecter",
+ "signin": "Essayez de vous connecter avec un autre compte",
+ "oauthSignin": "Essayez de vous connecter avec un autre compte",
+ "redirectUriMismatch": "L'URI de redirection ne correspond pas \u00e0 la configuration de l'application oauth",
+ "oauthCallback": "Essayez de vous connecter avec un autre compte",
+ "oauthCreateAccount": "Essayez de vous connecter avec un autre compte",
+ "emailCreateAccount": "Essayez de vous connecter avec un autre compte",
+ "callback": "Essayez de vous connecter avec un autre compte",
+ "oauthAccountNotLinked": "Pour confirmer votre identit\u00e9, connectez-vous avec le m\u00eame compte que vous avez utilis\u00e9 \u00e0 l'origine",
+ "emailSignin": "L'e-mail n'a pas pu \u00eatre envoy\u00e9",
+ "emailVerify": "Veuillez v\u00e9rifier votre e-mail, un nouvel e-mail a \u00e9t\u00e9 envoy\u00e9",
+ "credentialsSignin": "La connexion a \u00e9chou\u00e9. V\u00e9rifiez que les informations que vous avez fournies sont correctes",
+ "sessionRequired": "Veuillez vous connecter pour acc\u00e9der \u00e0 cette page"
+ }
+ },
+ "provider": {
+ "continue": "Continuer avec {{provider}}"
+ }
+ },
+ "chat": {
+ "input": {
+ "placeholder": "Tapez votre message ici...",
+ "actions": {
+ "send": "Envoyer le message",
+ "stop": "Arr\u00eater la t\u00e2che",
+ "attachFiles": "Joindre des fichiers"
+ }
+ },
+ "commands": {
+ "button": "Outils",
+ "changeTool": "Changer d'outil",
+ "availableTools": "Outils disponibles"
+ },
+ "speech": {
+ "start": "D\u00e9marrer l'enregistrement",
+ "stop": "Arr\u00eater l'enregistrement",
+ "connecting": "Connexion en cours"
+ },
+ "fileUpload": {
+ "dragDrop": "Glissez et d\u00e9posez des fichiers ici",
+ "browse": "Parcourir les fichiers",
+ "sizeLimit": "Limite :",
+ "errors": {
+ "failed": "\u00c9chec du t\u00e9l\u00e9versement",
+ "cancelled": "T\u00e9l\u00e9versement annul\u00e9 de"
+ }
+ },
+ "messages": {
+ "status": {
+ "using": "Utilise",
+ "used": "Utilis\u00e9"
+ },
+ "actions": {
+ "copy": {
+ "button": "Copier dans le presse-papiers",
+ "success": "Copi\u00e9 !"
+ }
+ },
+ "feedback": {
+ "positive": "Utile",
+ "negative": "Pas utile",
+ "edit": "Modifier le commentaire",
+ "dialog": {
+ "title": "Ajouter un commentaire",
+ "submit": "Envoyer le commentaire"
+ },
+ "status": {
+ "updating": "Mise \u00e0 jour",
+ "updated": "Commentaire mis \u00e0 jour"
+ }
+ }
+ },
+ "history": {
+ "title": "Derni\u00e8res entr\u00e9es",
+ "empty": "Tellement vide...",
+ "show": "Afficher l'historique"
+ },
+ "settings": {
+ "title": "Panneau des param\u00e8tres"
+ },
+ "watermark": "Construit avec"
+ },
+ "threadHistory": {
+ "sidebar": {
+ "title": "Discussions pass\u00e9es",
+ "filters": {
+ "search": "Rechercher",
+ "placeholder": "Rechercher des conversations..."
+ },
+ "timeframes": {
+ "today": "Aujourd'hui",
+ "yesterday": "Hier",
+ "previous7days": "Les 7 derniers jours",
+ "previous30days": "Les 30 derniers jours"
+ },
+ "empty": "Aucun fil de discussion trouv\u00e9",
+ "actions": {
+ "close": "Fermer la barre lat\u00e9rale",
+ "open": "Ouvrir la barre lat\u00e9rale"
+ }
+ },
+ "thread": {
+ "untitled": "Conversation sans titre",
+ "menu": {
+ "rename": "Renommer",
+ "delete": "Supprimer"
+ },
+ "actions": {
+ "delete": {
+ "title": "Confirmer la suppression",
+ "description": "Cela supprimera le fil de discussion ainsi que ses messages et \u00e9l\u00e9ments. Cette action ne peut pas \u00eatre annul\u00e9e",
+ "success": "Discussion supprim\u00e9e",
+ "inProgress": "Suppression de la discussion"
+ },
+ "rename": {
+ "title": "Renommer le fil de discussion",
+ "description": "Entrez un nouveau nom pour ce fil de discussion",
+ "form": {
+ "name": {
+ "label": "Nom",
+ "placeholder": "Entrez le nouveau nom"
+ }
+ },
+ "success": "Fil de discussion renomm\u00e9 !",
+ "inProgress": "Renommage du fil de discussion"
+ }
+ }
+ }
+ },
+ "navigation": {
+ "header": {
+ "chat": "Discussion",
+ "readme": "Lisez-moi",
+ "theme": {
+ "light": "Th\u00e8me clair",
+ "dark": "Th\u00e8me sombre",
+ "system": "Suivre le syst\u00e8me"
+ }
+ },
+ "newChat": {
+ "button": "Nouvelle discussion",
+ "dialog": {
+ "title": "Cr\u00e9er une nouvelle discussion",
+ "description": "Cela effacera votre historique de discussion actuel. \u00cates-vous s\u00fbr de vouloir continuer ?",
+ "tooltip": "Nouvelle discussion"
+ }
+ },
+ "user": {
+ "menu": {
+ "settings": "Param\u00e8tres",
+ "settingsKey": "S",
+ "apiKeys": "Cl\u00e9s API",
+ "logout": "Se d\u00e9connecter"
+ }
+ }
+ },
+ "apiKeys": {
+ "title": "Cl\u00e9s API requises",
+ "description": "Pour utiliser cette application, les cl\u00e9s API suivantes sont requises. Les cl\u00e9s sont stock\u00e9es dans le stockage local de votre appareil.",
+ "success": {
+ "saved": "Enregistr\u00e9 avec succ\u00e8s"
+ }
+ },
+ "alerts": {
+ "info": "Info",
+ "note": "Note",
+ "tip": "Astuce",
+ "important": "Important",
+ "warning": "Avertissement",
+ "caution": "Attention",
+ "debug": "D\u00e9bogage",
+ "example": "Exemple",
+ "success": "Succ\u00e8s",
+ "help": "Aide",
+ "idea": "Id\u00e9e",
+ "pending": "En attente",
+ "security": "S\u00e9curit\u00e9",
+ "beta": "B\u00eata",
+ "best-practice": "Meilleure pratique"
+ }
+}
\ No newline at end of file
diff --git a/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/gu.json b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/gu.json
new file mode 100644
index 0000000..b86f5d8
--- /dev/null
+++ b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/gu.json
@@ -0,0 +1,219 @@
+{
+ "common": {
+ "actions": {
+ "cancel": "\u0ab0\u0aa6 \u0a95\u0ab0\u0acb",
+ "confirm": "\u0aaa\u0ac1\u0ab7\u0acd\u0a9f\u0abf \u0a95\u0ab0\u0acb",
+ "continue": "\u0a9a\u0abe\u0ab2\u0ac1 \u0ab0\u0abe\u0a96\u0acb",
+ "goBack": "\u0aaa\u0abe\u0a9b\u0abe \u0a9c\u0abe\u0a93",
+ "reset": "\u0ab0\u0ac0\u0ab8\u0ac7\u0a9f \u0a95\u0ab0\u0acb",
+ "submit": "\u0ab8\u0aac\u0aae\u0abf\u0a9f \u0a95\u0ab0\u0acb"
+ },
+ "status": {
+ "loading": "\u0ab2\u0acb\u0aa1 \u0aa5\u0a88 \u0ab0\u0ab9\u0acd\u0aaf\u0ac1\u0a82 \u0a9b\u0ac7...",
+ "error": {
+ "default": "\u0a8f\u0a95 \u0aad\u0ac2\u0ab2 \u0aa5\u0a88",
+ "serverConnection": "\u0ab8\u0ab0\u0acd\u0ab5\u0ab0 \u0ab8\u0ac1\u0aa7\u0ac0 \u0aaa\u0ab9\u0acb\u0a82\u0a9a\u0ac0 \u0ab6\u0a95\u0abe\u0aaf\u0ac1\u0a82 \u0aa8\u0aa5\u0ac0"
+ }
+ }
+ },
+ "auth": {
+ "login": {
+ "title": "\u0a8f\u0aaa\u0acd\u0ab2\u0abf\u0a95\u0ac7\u0ab6\u0aa8 \u0a8d\u0a95\u0acd\u0ab8\u0ac7\u0ab8 \u0a95\u0ab0\u0ab5\u0abe \u0aae\u0abe\u0a9f\u0ac7 \u0ab2\u0ac9\u0a97\u0abf\u0aa8 \u0a95\u0ab0\u0acb",
+ "form": {
+ "email": {
+ "label": "\u0a88\u0aae\u0ac7\u0ab2 \u0a8f\u0aa1\u0acd\u0ab0\u0ac7\u0ab8",
+ "required": "\u0a88\u0aae\u0ac7\u0ab2 \u0a86\u0ab5\u0ab6\u0acd\u0aaf\u0a95 \u0a9b\u0ac7"
+ },
+ "password": {
+ "label": "\u0aaa\u0abe\u0ab8\u0ab5\u0ab0\u0acd\u0aa1",
+ "required": "\u0aaa\u0abe\u0ab8\u0ab5\u0ab0\u0acd\u0aa1 \u0a86\u0ab5\u0ab6\u0acd\u0aaf\u0a95 \u0a9b\u0ac7"
+ },
+ "actions": {
+ "signin": "\u0ab8\u0abe\u0a87\u0aa8 \u0a87\u0aa8 \u0a95\u0ab0\u0acb"
+ },
+ "alternativeText": {
+ "or": "\u0a85\u0aa5\u0ab5\u0abe"
+ }
+ },
+ "errors": {
+ "default": "\u0ab8\u0abe\u0a87\u0aa8 \u0a87\u0aa8 \u0a95\u0ab0\u0ac0 \u0ab6\u0a95\u0abe\u0aaf\u0ac1\u0a82 \u0aa8\u0aa5\u0ac0",
+ "signin": "\u0a85\u0ab2\u0a97 \u0a8f\u0a95\u0abe\u0a89\u0aa8\u0acd\u0a9f\u0aa5\u0ac0 \u0ab8\u0abe\u0a87\u0aa8 \u0a87\u0aa8 \u0a95\u0ab0\u0ab5\u0abe\u0aa8\u0acb \u0aaa\u0acd\u0ab0\u0aaf\u0abe\u0ab8 \u0a95\u0ab0\u0acb",
+ "oauthSignin": "\u0a85\u0ab2\u0a97 \u0a8f\u0a95\u0abe\u0a89\u0aa8\u0acd\u0a9f\u0aa5\u0ac0 \u0ab8\u0abe\u0a87\u0aa8 \u0a87\u0aa8 \u0a95\u0ab0\u0ab5\u0abe\u0aa8\u0acb \u0aaa\u0acd\u0ab0\u0aaf\u0abe\u0ab8 \u0a95\u0ab0\u0acb",
+ "redirectUriMismatch": "\u0ab0\u0ac0\u0aa1\u0abe\u0aaf\u0ab0\u0ac7\u0a95\u0acd\u0a9f URI oauth \u0a8d\u0aaa \u0a95\u0aa8\u0acd\u0aab\u0abf\u0a97\u0ab0\u0ac7\u0ab6\u0aa8 \u0ab8\u0abe\u0aa5\u0ac7 \u0aae\u0ac7\u0ab3 \u0a96\u0abe\u0aa4\u0acb \u0aa8\u0aa5\u0ac0",
+ "oauthCallback": "\u0a85\u0ab2\u0a97 \u0a8f\u0a95\u0abe\u0a89\u0aa8\u0acd\u0a9f\u0aa5\u0ac0 \u0ab8\u0abe\u0a87\u0aa8 \u0a87\u0aa8 \u0a95\u0ab0\u0ab5\u0abe\u0aa8\u0acb \u0aaa\u0acd\u0ab0\u0aaf\u0abe\u0ab8 \u0a95\u0ab0\u0acb",
+ "oauthCreateAccount": "\u0a85\u0ab2\u0a97 \u0a8f\u0a95\u0abe\u0a89\u0aa8\u0acd\u0a9f\u0aa5\u0ac0 \u0ab8\u0abe\u0a87\u0aa8 \u0a87\u0aa8 \u0a95\u0ab0\u0ab5\u0abe\u0aa8\u0acb \u0aaa\u0acd\u0ab0\u0aaf\u0abe\u0ab8 \u0a95\u0ab0\u0acb",
+ "emailCreateAccount": "\u0a85\u0ab2\u0a97 \u0a8f\u0a95\u0abe\u0a89\u0aa8\u0acd\u0a9f\u0aa5\u0ac0 \u0ab8\u0abe\u0a87\u0aa8 \u0a87\u0aa8 \u0a95\u0ab0\u0ab5\u0abe\u0aa8\u0acb \u0aaa\u0acd\u0ab0\u0aaf\u0abe\u0ab8 \u0a95\u0ab0\u0acb",
+ "callback": "\u0a85\u0ab2\u0a97 \u0a8f\u0a95\u0abe\u0a89\u0aa8\u0acd\u0a9f\u0aa5\u0ac0 \u0ab8\u0abe\u0a87\u0aa8 \u0a87\u0aa8 \u0a95\u0ab0\u0ab5\u0abe\u0aa8\u0acb \u0aaa\u0acd\u0ab0\u0aaf\u0abe\u0ab8 \u0a95\u0ab0\u0acb",
+ "oauthAccountNotLinked": "\u0aa4\u0aae\u0abe\u0ab0\u0ac0 \u0a93\u0ab3\u0a96\u0aa8\u0ac0 \u0aaa\u0ac1\u0ab7\u0acd\u0a9f\u0abf \u0a95\u0ab0\u0ab5\u0abe \u0aae\u0abe\u0a9f\u0ac7, \u0aae\u0ac2\u0ab3 \u0ab0\u0ac2\u0aaa\u0ac7 \u0ab5\u0abe\u0aaa\u0ab0\u0ac7\u0ab2\u0abe \u0a8f\u0a95\u0abe\u0a89\u0aa8\u0acd\u0a9f\u0aa5\u0ac0 \u0ab8\u0abe\u0a87\u0aa8 \u0a87\u0aa8 \u0a95\u0ab0\u0acb",
+ "emailSignin": "\u0a88\u0aae\u0ac7\u0ab2 \u0aae\u0acb\u0a95\u0ab2\u0ac0 \u0ab6\u0a95\u0abe\u0aaf\u0acb \u0aa8\u0aa5\u0ac0",
+ "emailVerify": "\u0a95\u0ac3\u0aaa\u0abe \u0a95\u0ab0\u0ac0 \u0aa4\u0aae\u0abe\u0ab0\u0acb \u0a88\u0aae\u0ac7\u0ab2 \u0a9a\u0a95\u0abe\u0ab8\u0acb, \u0aa8\u0ab5\u0acb \u0a88\u0aae\u0ac7\u0ab2 \u0aae\u0acb\u0a95\u0ab2\u0ab5\u0abe\u0aae\u0abe\u0a82 \u0a86\u0ab5\u0acd\u0aaf\u0acb \u0a9b\u0ac7",
+ "credentialsSignin": "\u0ab8\u0abe\u0a87\u0aa8 \u0a87\u0aa8 \u0aa8\u0abf\u0ab7\u0acd\u0aab\u0ab3. \u0a86\u0aaa\u0ac7\u0ab2\u0ac0 \u0ab5\u0abf\u0a97\u0aa4\u0acb \u0ab8\u0abe\u0a9a\u0ac0 \u0a9b\u0ac7 \u0a95\u0ac7 \u0aa8\u0ab9\u0ac0\u0a82 \u0aa4\u0ac7 \u0a9a\u0a95\u0abe\u0ab8\u0acb",
+ "sessionRequired": "\u0a86 \u0aaa\u0ac7\u0a9c\u0aa8\u0ac7 \u0a8d\u0a95\u0acd\u0ab8\u0ac7\u0ab8 \u0a95\u0ab0\u0ab5\u0abe \u0aae\u0abe\u0a9f\u0ac7 \u0a95\u0ac3\u0aaa\u0abe \u0a95\u0ab0\u0ac0 \u0ab8\u0abe\u0a87\u0aa8 \u0a87\u0aa8 \u0a95\u0ab0\u0acb"
+ }
+ },
+ "provider": {
+ "continue": "{{provider}} \u0ab8\u0abe\u0aa5\u0ac7 \u0a9a\u0abe\u0ab2\u0ac1 \u0ab0\u0abe\u0a96\u0acb"
+ }
+ },
+ "chat": {
+ "input": {
+ "placeholder": "\u0a85\u0ab9\u0ac0\u0a82 \u0aa4\u0aae\u0abe\u0ab0\u0acb \u0ab8\u0a82\u0aa6\u0ac7\u0ab6 \u0ab2\u0a96\u0acb...",
+ "actions": {
+ "send": "\u0ab8\u0a82\u0aa6\u0ac7\u0ab6 \u0aae\u0acb\u0a95\u0ab2\u0acb",
+ "stop": "\u0a95\u0abe\u0ab0\u0acd\u0aaf \u0ab0\u0acb\u0a95\u0acb",
+ "attachFiles": "\u0aab\u0abe\u0a87\u0ab2\u0acd\u0ab8 \u0a9c\u0acb\u0aa1\u0acb"
+ }
+ },
+ "speech": {
+ "start": "\u0ab0\u0ac7\u0a95\u0acb\u0ab0\u0acd\u0aa1\u0abf\u0a82\u0a97 \u0ab6\u0ab0\u0ac2 \u0a95\u0ab0\u0acb",
+ "stop": "\u0ab0\u0ac7\u0a95\u0acb\u0ab0\u0acd\u0aa1\u0abf\u0a82\u0a97 \u0aac\u0a82\u0aa7 \u0a95\u0ab0\u0acb",
+ "connecting": "\u0a95\u0aa8\u0ac7\u0a95\u0acd\u0a9f \u0aa5\u0a88 \u0ab0\u0ab9\u0acd\u0aaf\u0ac1\u0a82 \u0a9b\u0ac7"
+ },
+ "commands": {
+ "button": "\u0a9f\u0ac2\u0ab2\u0acd\u0ab8",
+ "changeTool": "\u0a9f\u0ac2\u0ab2 \u0aac\u0aa6\u0ab2\u0acb",
+ "availableTools": "\u0a89\u0aaa\u0ab2\u0aac\u0acd\u0aa7 \u0a9f\u0ac2\u0ab2\u0acd\u0ab8"
+ },
+ "fileUpload": {
+ "dragDrop": "\u0a85\u0ab9\u0ac0\u0a82 \u0aab\u0abe\u0a87\u0ab2\u0acd\u0ab8 \u0a96\u0ac7\u0a82\u0a9a\u0acb \u0a85\u0aa8\u0ac7 \u0a9b\u0acb\u0aa1\u0acb",
+ "browse": "\u0aab\u0abe\u0a87\u0ab2\u0acd\u0ab8 \u0aac\u0acd\u0ab0\u0abe\u0a89\u0a9d \u0a95\u0ab0\u0acb",
+ "sizeLimit": "\u0aae\u0ab0\u0acd\u0aaf\u0abe\u0aa6\u0abe:",
+ "errors": {
+ "failed": "\u0a85\u0aaa\u0ab2\u0acb\u0aa1 \u0a95\u0ab0\u0ab5\u0abe\u0aae\u0abe\u0a82 \u0aa8\u0abf\u0ab7\u0acd\u0aab\u0ab3",
+ "cancelled": "\u0a85\u0aaa\u0ab2\u0acb\u0aa1 \u0ab0\u0aa6 \u0a95\u0ab0\u0acd\u0aaf\u0ac1\u0a82"
+ }
+ },
+ "messages": {
+ "status": {
+ "using": "\u0ab5\u0abe\u0aaa\u0ab0\u0ac0 \u0ab0\u0ab9\u0acd\u0aaf\u0abe \u0a9b\u0ac7",
+ "used": "\u0ab5\u0aaa\u0ab0\u0abe\u0aaf\u0ac7\u0ab2"
+ },
+ "actions": {
+ "copy": {
+ "button": "\u0a95\u0acd\u0ab2\u0abf\u0aaa\u0aac\u0acb\u0ab0\u0acd\u0aa1 \u0aaa\u0ab0 \u0a95\u0ac9\u0aaa\u0abf \u0a95\u0ab0\u0acb",
+ "success": "\u0a95\u0ac9\u0aaa\u0abf \u0aa5\u0aaf\u0ac1\u0a82!"
+ }
+ },
+ "feedback": {
+ "positive": "\u0a89\u0aaa\u0aaf\u0acb\u0a97\u0ac0",
+ "negative": "\u0aac\u0abf\u0aa8\u0a89\u0aaa\u0aaf\u0acb\u0a97\u0ac0",
+ "edit": "\u0aaa\u0acd\u0ab0\u0aa4\u0abf\u0ab8\u0abe\u0aa6 \u0ab8\u0a82\u0aaa\u0abe\u0aa6\u0abf\u0aa4 \u0a95\u0ab0\u0acb",
+ "dialog": {
+ "title": "\u0a9f\u0abf\u0aaa\u0acd\u0aaa\u0aa3\u0ac0 \u0a89\u0aae\u0ac7\u0ab0\u0acb",
+ "submit": "\u0aaa\u0acd\u0ab0\u0aa4\u0abf\u0ab8\u0abe\u0aa6 \u0ab8\u0aac\u0aae\u0abf\u0a9f \u0a95\u0ab0\u0acb"
+ },
+ "status": {
+ "updating": "\u0a85\u0aaa\u0aa1\u0ac7\u0a9f \u0aa5\u0a88 \u0ab0\u0ab9\u0acd\u0aaf\u0ac1\u0a82 \u0a9b\u0ac7",
+ "updated": "\u0aaa\u0acd\u0ab0\u0aa4\u0abf\u0ab8\u0abe\u0aa6 \u0a85\u0aaa\u0aa1\u0ac7\u0a9f \u0aa5\u0aaf\u0acb"
+ }
+ }
+ },
+ "history": {
+ "title": "\u0a9b\u0ac7\u0ab2\u0acd\u0ab2\u0abe \u0a87\u0aa8\u0aaa\u0ac1\u0a9f\u0acd\u0ab8",
+ "empty": "\u0a96\u0abe\u0ab2\u0ac0 \u0a9b\u0ac7...",
+ "show": "\u0a87\u0aa4\u0abf\u0ab9\u0abe\u0ab8 \u0aac\u0aa4\u0abe\u0ab5\u0acb"
+ },
+ "settings": {
+ "title": "\u0ab8\u0ac7\u0a9f\u0abf\u0a82\u0a97\u0acd\u0ab8 \u0aaa\u0ac7\u0aa8\u0ab2"
+ },
+ "watermark": "LLM \u0aad\u0ac2\u0ab2\u0acb \u0a95\u0ab0\u0ac0 \u0ab6\u0a95\u0ac7 \u0a9b\u0ac7. \u0aae\u0ab9\u0aa4\u0acd\u0ab5\u0aaa\u0ac2\u0ab0\u0acd\u0aa3 \u0aae\u0abe\u0ab9\u0abf\u0aa4\u0ac0 \u0aa4\u0aaa\u0abe\u0ab8\u0ab5\u0abe\u0aa8\u0ac1\u0a82 \u0ab5\u0abf\u0a9a\u0abe\u0ab0\u0acb."
+ },
+ "threadHistory": {
+ "sidebar": {
+ "title": "\u0aaa\u0abe\u0a9b\u0ab2\u0ac0 \u0a9a\u0ac7\u0a9f\u0acd\u0ab8",
+ "filters": {
+ "search": "\u0ab6\u0acb\u0aa7\u0acb",
+ "placeholder": "Search conversations..."
+ },
+ "timeframes": {
+ "today": "\u0a86\u0a9c\u0ac7",
+ "yesterday": "\u0a97\u0a88\u0a95\u0abe\u0ab2\u0ac7",
+ "previous7days": "\u0aaa\u0abe\u0a9b\u0ab2\u0abe 7 \u0aa6\u0abf\u0ab5\u0ab8",
+ "previous30days": "\u0aaa\u0abe\u0a9b\u0ab2\u0abe 30 \u0aa6\u0abf\u0ab5\u0ab8"
+ },
+ "empty": "\u0a95\u0acb\u0a88 \u0aa5\u0acd\u0ab0\u0ac7\u0aa1\u0acd\u0ab8 \u0aae\u0ab3\u0acd\u0aaf\u0abe \u0aa8\u0aa5\u0ac0",
+ "actions": {
+ "close": "\u0ab8\u0abe\u0a87\u0aa1\u0aac\u0abe\u0ab0 \u0aac\u0a82\u0aa7 \u0a95\u0ab0\u0acb",
+ "open": "\u0ab8\u0abe\u0a87\u0aa1\u0aac\u0abe\u0ab0 \u0a96\u0acb\u0ab2\u0acb"
+ }
+ },
+ "thread": {
+ "untitled": "\u0ab6\u0ac0\u0ab0\u0acd\u0ab7\u0a95 \u0ab5\u0a97\u0ab0\u0aa8\u0ac0 \u0ab5\u0abe\u0aa4\u0a9a\u0ac0\u0aa4",
+ "menu": {
+ "rename": "Rename",
+ "delete": "Delete"
+ },
+ "actions": {
+ "delete": {
+ "title": "\u0a95\u0abe\u0aa2\u0ac0 \u0aa8\u0abe\u0a96\u0ab5\u0abe\u0aa8\u0ac0 \u0aaa\u0ac1\u0ab7\u0acd\u0a9f\u0abf \u0a95\u0ab0\u0acb",
+ "description": "\u0a86 \u0aa5\u0acd\u0ab0\u0ac7\u0aa1 \u0a85\u0aa8\u0ac7 \u0aa4\u0ac7\u0aa8\u0abe \u0ab8\u0a82\u0aa6\u0ac7\u0ab6\u0abe\u0a93 \u0a85\u0aa8\u0ac7 \u0aa4\u0aa4\u0acd\u0ab5\u0acb\u0aa8\u0ac7 \u0a95\u0abe\u0aa2\u0ac0 \u0aa8\u0abe\u0a96\u0ab6\u0ac7. \u0a86 \u0a95\u0acd\u0ab0\u0abf\u0aaf\u0abe \u0aaa\u0abe\u0a9b\u0ac0 \u0aab\u0ac7\u0ab0\u0ab5\u0ac0 \u0ab6\u0a95\u0abe\u0ab6\u0ac7 \u0aa8\u0ab9\u0ac0\u0a82",
+ "success": "\u0a9a\u0ac7\u0a9f \u0a95\u0abe\u0aa2\u0ac0 \u0aa8\u0abe\u0a96\u0ac0",
+ "inProgress": "\u0a9a\u0ac7\u0a9f \u0a95\u0abe\u0aa2\u0ac0 \u0aa8\u0abe\u0a96\u0ac0 \u0ab0\u0ab9\u0acd\u0aaf\u0abe \u0a9b\u0ac0\u0a8f"
+ },
+ "rename": {
+ "title": "\u0aa5\u0acd\u0ab0\u0ac7\u0aa1\u0aa8\u0ac1\u0a82 \u0aa8\u0abe\u0aae \u0aac\u0aa6\u0ab2\u0acb",
+ "description": "\u0a86 \u0aa5\u0acd\u0ab0\u0ac7\u0aa1 \u0aae\u0abe\u0a9f\u0ac7 \u0aa8\u0ab5\u0ac1\u0a82 \u0aa8\u0abe\u0aae \u0aa6\u0abe\u0a96\u0ab2 \u0a95\u0ab0\u0acb",
+ "form": {
+ "name": {
+ "label": "\u0aa8\u0abe\u0aae",
+ "placeholder": "\u0aa8\u0ab5\u0ac1\u0a82 \u0aa8\u0abe\u0aae \u0aa6\u0abe\u0a96\u0ab2 \u0a95\u0ab0\u0acb"
+ }
+ },
+ "success": "\u0aa5\u0acd\u0ab0\u0ac7\u0aa1\u0aa8\u0ac1\u0a82 \u0aa8\u0abe\u0aae \u0aac\u0aa6\u0ab2\u0abe\u0aaf\u0ac1\u0a82!",
+ "inProgress": "\u0aa5\u0acd\u0ab0\u0ac7\u0aa1\u0aa8\u0ac1\u0a82 \u0aa8\u0abe\u0aae \u0aac\u0aa6\u0ab2\u0ac0 \u0ab0\u0ab9\u0acd\u0aaf\u0abe \u0a9b\u0ac0\u0a8f"
+ }
+ }
+ }
+ },
+ "navigation": {
+ "header": {
+ "chat": "\u0a9a\u0ac7\u0a9f",
+ "readme": "\u0ab5\u0abe\u0a82\u0a9a\u0acb",
+ "theme": {
+ "light": "Light Theme",
+ "dark": "Dark Theme",
+ "system": "Follow System"
+ }
+ },
+ "newChat": {
+ "button": "\u0aa8\u0ab5\u0ac0 \u0a9a\u0ac7\u0a9f",
+ "dialog": {
+ "title": "\u0aa8\u0ab5\u0ac0 \u0a9a\u0ac7\u0a9f \u0aac\u0aa8\u0abe\u0ab5\u0acb",
+ "description": "\u0a86 \u0aa4\u0aae\u0abe\u0ab0\u0acb \u0ab5\u0ab0\u0acd\u0aa4\u0aae\u0abe\u0aa8 \u0a9a\u0ac7\u0a9f \u0a87\u0aa4\u0abf\u0ab9\u0abe\u0ab8 \u0ab8\u0abe\u0aab \u0a95\u0ab0\u0ab6\u0ac7. \u0ab6\u0ac1\u0a82 \u0aa4\u0aae\u0ac7 \u0a9a\u0abe\u0ab2\u0ac1 \u0ab0\u0abe\u0a96\u0ab5\u0abe \u0aae\u0abe\u0a82\u0a97\u0acb \u0a9b\u0acb?",
+ "tooltip": "\u0aa8\u0ab5\u0ac0 \u0a9a\u0ac7\u0a9f"
+ }
+ },
+ "user": {
+ "menu": {
+ "settings": "\u0ab8\u0ac7\u0a9f\u0abf\u0a82\u0a97\u0acd\u0ab8",
+ "settingsKey": "S",
+ "apiKeys": "API \u0a95\u0ac0",
+ "logout": "\u0ab2\u0ac9\u0a97\u0a86\u0a89\u0a9f"
+ }
+ }
+ },
+ "apiKeys": {
+ "title": "\u0a9c\u0ab0\u0ac2\u0ab0\u0ac0 API \u0a95\u0ac0",
+ "description": "\u0a86 \u0a8f\u0aaa\u0acd\u0ab2\u0abf\u0a95\u0ac7\u0ab6\u0aa8 \u0ab5\u0abe\u0aaa\u0ab0\u0ab5\u0abe \u0aae\u0abe\u0a9f\u0ac7, \u0aa8\u0ac0\u0a9a\u0ac7\u0aa8\u0ac0 API \u0a95\u0ac0 \u0a9c\u0ab0\u0ac2\u0ab0\u0ac0 \u0a9b\u0ac7. \u0a95\u0ac0 \u0aa4\u0aae\u0abe\u0ab0\u0abe \u0aa1\u0abf\u0ab5\u0abe\u0a87\u0ab8\u0aa8\u0abe \u0ab2\u0acb\u0a95\u0ab2 \u0ab8\u0acd\u0a9f\u0acb\u0ab0\u0ac7\u0a9c\u0aae\u0abe\u0a82 \u0ab8\u0a82\u0a97\u0acd\u0ab0\u0ab9\u0abf\u0aa4 \u0aa5\u0ab6\u0ac7.",
+ "success": {
+ "saved": "\u0ab8\u0aab\u0ab3\u0aa4\u0abe\u0aaa\u0ac2\u0ab0\u0acd\u0ab5\u0a95 \u0ab8\u0abe\u0a9a\u0ab5\u0acd\u0aaf\u0ac1\u0a82"
+ }
+ },
+ "alerts": {
+ "info": "Info",
+ "note": "Note",
+ "tip": "Tip",
+ "important": "Important",
+ "warning": "Warning",
+ "caution": "Caution",
+ "debug": "Debug",
+ "example": "Example",
+ "success": "Success",
+ "help": "Help",
+ "idea": "Idea",
+ "pending": "Pending",
+ "security": "Security",
+ "beta": "Beta",
+ "best-practice": "Best Practice"
+ }
+}
\ No newline at end of file
diff --git a/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/he-IL.json b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/he-IL.json
new file mode 100644
index 0000000..c7487d9
--- /dev/null
+++ b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/he-IL.json
@@ -0,0 +1,219 @@
+{
+ "common": {
+ "actions": {
+ "cancel": "\u05d1\u05d9\u05d8\u05d5\u05dc",
+ "confirm": "\u05d0\u05d9\u05e9\u05d5\u05e8",
+ "continue": "\u05d4\u05de\u05e9\u05da",
+ "goBack": "\u05d7\u05d6\u05d5\u05e8",
+ "reset": "\u05d0\u05d9\u05e4\u05d5\u05e1",
+ "submit": "\u05e9\u05dc\u05d7"
+ },
+ "status": {
+ "loading": "\u05d8\u05d5\u05e2\u05df...",
+ "error": {
+ "default": "\u05d0\u05d9\u05e8\u05e2\u05d4 \u05e9\u05d2\u05d9\u05d0\u05d4",
+ "serverConnection": "\u05dc\u05d0 \u05e0\u05d9\u05ea\u05df \u05dc\u05d4\u05ea\u05d7\u05d1\u05e8 \u05dc\u05e9\u05e8\u05ea"
+ }
+ }
+ },
+ "auth": {
+ "login": {
+ "title": "\u05d4\u05ea\u05d7\u05d1\u05e8 \u05db\u05d3\u05d9 \u05dc\u05d2\u05e9\u05ea \u05dc\u05d0\u05e4\u05dc\u05d9\u05e7\u05e6\u05d9\u05d4",
+ "form": {
+ "email": {
+ "label": "\u05db\u05ea\u05d5\u05d1\u05ea \u05d0\u05d9\u05de\u05d9\u05d9\u05dc",
+ "required": "\u05e9\u05d3\u05d4 \u05d4\u05d0\u05d9\u05de\u05d9\u05d9\u05dc \u05d4\u05d5\u05d0 \u05e9\u05d3\u05d4 \u05d7\u05d5\u05d1\u05d4"
+ },
+ "password": {
+ "label": "\u05e1\u05d9\u05e1\u05de\u05d4",
+ "required": "\u05e9\u05d3\u05d4 \u05d4\u05e1\u05d9\u05e1\u05de\u05d4 \u05d4\u05d5\u05d0 \u05e9\u05d3\u05d4 \u05d7\u05d5\u05d1\u05d4"
+ },
+ "actions": {
+ "signin": "\u05d4\u05ea\u05d7\u05d1\u05e8"
+ },
+ "alternativeText": {
+ "or": "\u05d0\u05d5"
+ }
+ },
+ "errors": {
+ "default": "\u05dc\u05d0 \u05e0\u05d9\u05ea\u05df \u05dc\u05d4\u05ea\u05d7\u05d1\u05e8",
+ "signin": "\u05e0\u05e1\u05d4 \u05dc\u05d4\u05ea\u05d7\u05d1\u05e8 \u05e2\u05dd \u05d7\u05e9\u05d1\u05d5\u05df \u05d0\u05d7\u05e8",
+ "oauthSignin": "\u05e0\u05e1\u05d4 \u05dc\u05d4\u05ea\u05d7\u05d1\u05e8 \u05e2\u05dd \u05d7\u05e9\u05d1\u05d5\u05df \u05d0\u05d7\u05e8",
+ "redirectUriMismatch": "\u05db\u05ea\u05d5\u05d1\u05ea \u05d4\u05d4\u05e4\u05e0\u05d9\u05d4 \u05d0\u05d9\u05e0\u05d4 \u05ea\u05d5\u05d0\u05de\u05ea \u05d0\u05ea \u05ea\u05e6\u05d5\u05e8\u05ea \u05d0\u05e4\u05dc\u05d9\u05e7\u05e6\u05d9\u05d9\u05ea OAuth",
+ "oauthCallback": "\u05e0\u05e1\u05d4 \u05dc\u05d4\u05ea\u05d7\u05d1\u05e8 \u05e2\u05dd \u05d7\u05e9\u05d1\u05d5\u05df \u05d0\u05d7\u05e8",
+ "oauthCreateAccount": "\u05e0\u05e1\u05d4 \u05dc\u05d4\u05ea\u05d7\u05d1\u05e8 \u05e2\u05dd \u05d7\u05e9\u05d1\u05d5\u05df \u05d0\u05d7\u05e8",
+ "emailCreateAccount": "\u05e0\u05e1\u05d4 \u05dc\u05d4\u05ea\u05d7\u05d1\u05e8 \u05e2\u05dd \u05d7\u05e9\u05d1\u05d5\u05df \u05d0\u05d7\u05e8",
+ "callback": "\u05e0\u05e1\u05d4 \u05dc\u05d4\u05ea\u05d7\u05d1\u05e8 \u05e2\u05dd \u05d7\u05e9\u05d1\u05d5\u05df \u05d0\u05d7\u05e8",
+ "oauthAccountNotLinked": "\u05db\u05d3\u05d9 \u05dc\u05d0\u05de\u05ea \u05d0\u05ea \u05d6\u05d4\u05d5\u05ea\u05da, \u05d4\u05ea\u05d7\u05d1\u05e8 \u05e2\u05dd \u05d0\u05d5\u05ea\u05d5 \u05d7\u05e9\u05d1\u05d5\u05df \u05d1\u05d5 \u05d4\u05e9\u05ea\u05de\u05e9\u05ea \u05d1\u05de\u05e7\u05d5\u05e8",
+ "emailSignin": "\u05dc\u05d0 \u05e0\u05d9\u05ea\u05df \u05d4\u05d9\u05d4 \u05dc\u05e9\u05dc\u05d5\u05d7 \u05d0\u05ea \u05d4\u05d0\u05d9\u05de\u05d9\u05d9\u05dc",
+ "emailVerify": "\u05d0\u05e0\u05d0 \u05d0\u05de\u05ea \u05d0\u05ea \u05d4\u05d0\u05d9\u05de\u05d9\u05d9\u05dc \u05e9\u05dc\u05da, \u05e0\u05e9\u05dc\u05d7 \u05d0\u05d9\u05de\u05d9\u05d9\u05dc \u05d7\u05d3\u05e9",
+ "credentialsSignin": "\u05d4\u05d4\u05ea\u05d7\u05d1\u05e8\u05d5\u05ea \u05e0\u05db\u05e9\u05dc\u05d4. \u05d1\u05d3\u05d5\u05e7 \u05e9\u05d4\u05e4\u05e8\u05d8\u05d9\u05dd \u05e9\u05d4\u05d6\u05e0\u05ea \u05e0\u05db\u05d5\u05e0\u05d9\u05dd",
+ "sessionRequired": "\u05d0\u05e0\u05d0 \u05d4\u05ea\u05d7\u05d1\u05e8 \u05db\u05d3\u05d9 \u05dc\u05d2\u05e9\u05ea \u05dc\u05d3\u05e3 \u05d6\u05d4"
+ }
+ },
+ "provider": {
+ "continue": "\u05d4\u05de\u05e9\u05da \u05e2\u05dd {{provider}}"
+ }
+ },
+ "chat": {
+ "input": {
+ "placeholder": "\u05d4\u05e7\u05dc\u05d3 \u05d0\u05ea \u05d4\u05d4\u05d5\u05d3\u05e2\u05d4 \u05e9\u05dc\u05da \u05db\u05d0\u05df...",
+ "actions": {
+ "send": "\u05e9\u05dc\u05d7 \u05d4\u05d5\u05d3\u05e2\u05d4",
+ "stop": "\u05e2\u05e6\u05d5\u05e8 \u05de\u05e9\u05d9\u05de\u05d4",
+ "attachFiles": "\u05e6\u05e8\u05e3 \u05e7\u05d1\u05e6\u05d9\u05dd"
+ }
+ },
+ "speech": {
+ "start": "\u05d4\u05ea\u05d7\u05dc \u05d4\u05e7\u05dc\u05d8\u05d4",
+ "stop": "\u05e2\u05e6\u05d5\u05e8 \u05d4\u05e7\u05dc\u05d8\u05d4",
+ "connecting": "\u05de\u05ea\u05d7\u05d1\u05e8"
+ },
+ "commands": {
+ "button": "\u05db\u05dc\u05d9\u05dd",
+ "changeTool": "\u05e9\u05e0\u05d4 \u05db\u05dc\u05d9",
+ "availableTools": "\u05db\u05dc\u05d9\u05dd \u05d6\u05de\u05d9\u05e0\u05d9\u05dd"
+ },
+ "fileUpload": {
+ "dragDrop": "\u05d2\u05e8\u05d5\u05e8 \u05d5\u05e9\u05d7\u05e8\u05e8 \u05e7\u05d1\u05e6\u05d9\u05dd \u05db\u05d0\u05df",
+ "browse": "\u05e2\u05d9\u05d9\u05df \u05d1\u05e7\u05d1\u05e6\u05d9\u05dd",
+ "sizeLimit": "\u05de\u05d2\u05d1\u05dc\u05d4:",
+ "errors": {
+ "failed": "\u05d4\u05e2\u05dc\u05d0\u05d4 \u05e0\u05db\u05e9\u05dc\u05d4",
+ "cancelled": "\u05d4\u05e2\u05dc\u05d0\u05d4 \u05d1\u05d5\u05d8\u05dc\u05d4 \u05e9\u05dc"
+ }
+ },
+ "messages": {
+ "status": {
+ "using": "\u05de\u05e9\u05ea\u05de\u05e9 \u05d1",
+ "used": "\u05d4\u05e9\u05ea\u05de\u05e9 \u05d1"
+ },
+ "actions": {
+ "copy": {
+ "button": "\u05d4\u05e2\u05ea\u05e7 \u05dc\u05dc\u05d5\u05d7",
+ "success": "\u05d4\u05d5\u05e2\u05ea\u05e7!"
+ }
+ },
+ "feedback": {
+ "positive": "\u05de\u05d5\u05e2\u05d9\u05dc",
+ "negative": "\u05dc\u05d0 \u05de\u05d5\u05e2\u05d9\u05dc",
+ "edit": "\u05e2\u05e8\u05d5\u05da \u05de\u05e9\u05d5\u05d1",
+ "dialog": {
+ "title": "\u05d4\u05d5\u05e1\u05e3 \u05ea\u05d2\u05d5\u05d1\u05d4",
+ "submit": "\u05e9\u05dc\u05d7 \u05de\u05e9\u05d5\u05d1"
+ },
+ "status": {
+ "updating": "\u05de\u05e2\u05d3\u05db\u05df",
+ "updated": "\u05d4\u05de\u05e9\u05d5\u05d1 \u05e2\u05d5\u05d3\u05db\u05df"
+ }
+ }
+ },
+ "history": {
+ "title": "\u05e7\u05dc\u05d8\u05d9\u05dd \u05d0\u05d7\u05e8\u05d5\u05e0\u05d9\u05dd",
+ "empty": "\u05db\u05dc \u05db\u05da \u05e8\u05d9\u05e7...",
+ "show": "\u05d4\u05e6\u05d2 \u05d4\u05d9\u05e1\u05d8\u05d5\u05e8\u05d9\u05d4"
+ },
+ "settings": {
+ "title": "\u05e4\u05d0\u05e0\u05dc \u05d4\u05d2\u05d3\u05e8\u05d5\u05ea"
+ },
+ "watermark": "\u05de\u05d5\u05d3\u05dc\u05d9 \u05e9\u05e4\u05d4 \u05d2\u05d3\u05d5\u05dc\u05d9\u05dd \u05e2\u05dc\u05d5\u05dc\u05d9\u05dd \u05dc\u05e2\u05e9\u05d5\u05ea \u05d8\u05e2\u05d5\u05d9\u05d5\u05ea. \u05db\u05d3\u05d0\u05d9 \u05dc\u05d1\u05d3\u05d5\u05e7 \u05de\u05d9\u05d3\u05e2 \u05d7\u05e9\u05d5\u05d1."
+ },
+ "threadHistory": {
+ "sidebar": {
+ "title": "\u05e6'\u05d0\u05d8\u05d9\u05dd \u05e7\u05d5\u05d3\u05de\u05d9\u05dd",
+ "filters": {
+ "search": "\u05d7\u05d9\u05e4\u05d5\u05e9",
+ "placeholder": "Search conversations..."
+ },
+ "timeframes": {
+ "today": "\u05d4\u05d9\u05d5\u05dd",
+ "yesterday": "\u05d0\u05ea\u05de\u05d5\u05dc",
+ "previous7days": "7 \u05d9\u05de\u05d9\u05dd \u05d0\u05d7\u05e8\u05d5\u05e0\u05d9\u05dd",
+ "previous30days": "30 \u05d9\u05de\u05d9\u05dd \u05d0\u05d7\u05e8\u05d5\u05e0\u05d9\u05dd"
+ },
+ "empty": "\u05dc\u05d0 \u05e0\u05de\u05e6\u05d0\u05d5 \u05e9\u05d9\u05d7\u05d5\u05ea",
+ "actions": {
+ "close": "\u05e1\u05d2\u05d5\u05e8 \u05e1\u05e8\u05d2\u05dc \u05e6\u05d3",
+ "open": "\u05e4\u05ea\u05d7 \u05e1\u05e8\u05d2\u05dc \u05e6\u05d3"
+ }
+ },
+ "thread": {
+ "untitled": "\u05e9\u05d9\u05d7\u05d4 \u05dc\u05dc\u05d0 \u05db\u05d5\u05ea\u05e8\u05ea",
+ "menu": {
+ "rename": "Rename",
+ "delete": "Delete"
+ },
+ "actions": {
+ "delete": {
+ "title": "\u05d0\u05e9\u05e8 \u05de\u05d7\u05d9\u05e7\u05d4",
+ "description": "\u05e4\u05e2\u05d5\u05dc\u05d4 \u05d6\u05d5 \u05ea\u05de\u05d7\u05e7 \u05d0\u05ea \u05d4\u05e9\u05d9\u05d7\u05d4 \u05d5\u05db\u05df \u05d0\u05ea \u05d4\u05d4\u05d5\u05d3\u05e2\u05d5\u05ea \u05d5\u05d4\u05d0\u05dc\u05de\u05e0\u05d8\u05d9\u05dd \u05e9\u05dc\u05d4. \u05dc\u05d0 \u05e0\u05d9\u05ea\u05df \u05dc\u05d1\u05d8\u05dc \u05e4\u05e2\u05d5\u05dc\u05d4 \u05d6\u05d5",
+ "success": "\u05d4\u05e6'\u05d0\u05d8 \u05e0\u05de\u05d7\u05e7",
+ "inProgress": "\u05de\u05d5\u05d7\u05e7 \u05e6'\u05d0\u05d8"
+ },
+ "rename": {
+ "title": "\u05e9\u05e0\u05d4 \u05e9\u05dd \u05e9\u05d9\u05d7\u05d4",
+ "description": "\u05d4\u05d6\u05df \u05e9\u05dd \u05d7\u05d3\u05e9 \u05dc\u05e9\u05d9\u05d7\u05d4 \u05d6\u05d5",
+ "form": {
+ "name": {
+ "label": "\u05e9\u05dd",
+ "placeholder": "\u05d4\u05d6\u05df \u05e9\u05dd \u05d7\u05d3\u05e9"
+ }
+ },
+ "success": "\u05e9\u05dd \u05d4\u05e9\u05d9\u05d7\u05d4 \u05e9\u05d5\u05e0\u05d4!",
+ "inProgress": "\u05de\u05e9\u05e0\u05d4 \u05e9\u05dd \u05e9\u05d9\u05d7\u05d4"
+ }
+ }
+ }
+ },
+ "navigation": {
+ "header": {
+ "chat": "\u05e6'\u05d0\u05d8",
+ "readme": "\u05e7\u05e8\u05d0 \u05d0\u05d5\u05ea\u05d9",
+ "theme": {
+ "light": "Light Theme",
+ "dark": "Dark Theme",
+ "system": "Follow System"
+ }
+ },
+ "newChat": {
+ "button": "\u05e6'\u05d0\u05d8 \u05d7\u05d3\u05e9",
+ "dialog": {
+ "title": "\u05e6\u05d5\u05e8 \u05e6'\u05d0\u05d8 \u05d7\u05d3\u05e9",
+ "description": "\u05e4\u05e2\u05d5\u05dc\u05d4 \u05d6\u05d5 \u05ea\u05e0\u05e7\u05d4 \u05d0\u05ea \u05d4\u05d9\u05e1\u05d8\u05d5\u05e8\u05d9\u05d9\u05ea \u05d4\u05e6'\u05d0\u05d8 \u05d4\u05e0\u05d5\u05db\u05d7\u05d9\u05ea \u05e9\u05dc\u05da. \u05d4\u05d0\u05dd \u05d0\u05ea\u05d4 \u05d1\u05d8\u05d5\u05d7 \u05e9\u05d1\u05e8\u05e6\u05d5\u05e0\u05da \u05dc\u05d4\u05de\u05e9\u05d9\u05da?",
+ "tooltip": "\u05e6'\u05d0\u05d8 \u05d7\u05d3\u05e9"
+ }
+ },
+ "user": {
+ "menu": {
+ "settings": "\u05d4\u05d2\u05d3\u05e8\u05d5\u05ea",
+ "settingsKey": "\u05d4",
+ "apiKeys": "\u05de\u05e4\u05ea\u05d7\u05d5\u05ea API",
+ "logout": "\u05d4\u05ea\u05e0\u05ea\u05e7"
+ }
+ }
+ },
+ "apiKeys": {
+ "title": "\u05de\u05e4\u05ea\u05d7\u05d5\u05ea API \u05e0\u05d3\u05e8\u05e9\u05d9\u05dd",
+ "description": "\u05db\u05d3\u05d9 \u05dc\u05d4\u05e9\u05ea\u05de\u05e9 \u05d1\u05d0\u05e4\u05dc\u05d9\u05e7\u05e6\u05d9\u05d4 \u05d6\u05d5, \u05e0\u05d3\u05e8\u05e9\u05d9\u05dd \u05de\u05e4\u05ea\u05d7\u05d5\u05ea API \u05d4\u05d1\u05d0\u05d9\u05dd. \u05d4\u05de\u05e4\u05ea\u05d7\u05d5\u05ea \u05de\u05d0\u05d5\u05d7\u05e1\u05e0\u05d9\u05dd \u05d1\u05d0\u05d7\u05e1\u05d5\u05df \u05d4\u05de\u05e7\u05d5\u05de\u05d9 \u05e9\u05dc \u05d4\u05de\u05db\u05e9\u05d9\u05e8 \u05e9\u05dc\u05da.",
+ "success": {
+ "saved": "\u05e0\u05e9\u05de\u05e8 \u05d1\u05d4\u05e6\u05dc\u05d7\u05d4"
+ }
+ },
+ "alerts": {
+ "info": "Info",
+ "note": "Note",
+ "tip": "Tip",
+ "important": "Important",
+ "warning": "Warning",
+ "caution": "Caution",
+ "debug": "Debug",
+ "example": "Example",
+ "success": "Success",
+ "help": "Help",
+ "idea": "Idea",
+ "pending": "Pending",
+ "security": "Security",
+ "beta": "Beta",
+ "best-practice": "Best Practice"
+ }
+}
\ No newline at end of file
diff --git a/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/hi.json b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/hi.json
new file mode 100644
index 0000000..f4e5b97
--- /dev/null
+++ b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/hi.json
@@ -0,0 +1,219 @@
+{
+ "common": {
+ "actions": {
+ "cancel": "\u0930\u0926\u094d\u0926 \u0915\u0930\u0947\u0902",
+ "confirm": "\u092a\u0941\u0937\u094d\u091f\u093f \u0915\u0930\u0947\u0902",
+ "continue": "\u091c\u093e\u0930\u0940 \u0930\u0916\u0947\u0902",
+ "goBack": "\u0935\u093e\u092a\u0938 \u091c\u093e\u090f\u0902",
+ "reset": "\u0930\u0940\u0938\u0947\u091f \u0915\u0930\u0947\u0902",
+ "submit": "\u091c\u092e\u093e \u0915\u0930\u0947\u0902"
+ },
+ "status": {
+ "loading": "\u0932\u094b\u0921 \u0939\u094b \u0930\u0939\u093e \u0939\u0948...",
+ "error": {
+ "default": "\u090f\u0915 \u0924\u094d\u0930\u0941\u091f\u093f \u0939\u0941\u0908",
+ "serverConnection": "\u0938\u0930\u094d\u0935\u0930 \u0938\u0947 \u0938\u0902\u092a\u0930\u094d\u0915 \u0928\u0939\u0940\u0902 \u0939\u094b \u092a\u093e \u0930\u0939\u093e"
+ }
+ }
+ },
+ "auth": {
+ "login": {
+ "title": "\u0910\u092a \u0915\u093e \u0909\u092a\u092f\u094b\u0917 \u0915\u0930\u0928\u0947 \u0915\u0947 \u0932\u093f\u090f \u0932\u0949\u0917\u093f\u0928 \u0915\u0930\u0947\u0902",
+ "form": {
+ "email": {
+ "label": "\u0908\u092e\u0947\u0932 \u092a\u0924\u093e",
+ "required": "\u0908\u092e\u0947\u0932 \u090f\u0915 \u0906\u0935\u0936\u094d\u092f\u0915 \u092b\u093c\u0940\u0932\u094d\u0921 \u0939\u0948"
+ },
+ "password": {
+ "label": "\u092a\u093e\u0938\u0935\u0930\u094d\u0921",
+ "required": "\u092a\u093e\u0938\u0935\u0930\u094d\u0921 \u090f\u0915 \u0906\u0935\u0936\u094d\u092f\u0915 \u092b\u093c\u0940\u0932\u094d\u0921 \u0939\u0948"
+ },
+ "actions": {
+ "signin": "\u0938\u093e\u0907\u0928 \u0907\u0928 \u0915\u0930\u0947\u0902"
+ },
+ "alternativeText": {
+ "or": "\u092f\u093e"
+ }
+ },
+ "errors": {
+ "default": "\u0938\u093e\u0907\u0928 \u0907\u0928 \u0915\u0930\u0928\u0947 \u092e\u0947\u0902 \u0905\u0938\u092e\u0930\u094d\u0925",
+ "signin": "\u0915\u093f\u0938\u0940 \u0926\u0942\u0938\u0930\u0947 \u0916\u093e\u0924\u0947 \u0938\u0947 \u0938\u093e\u0907\u0928 \u0907\u0928 \u0915\u0930\u0928\u0947 \u0915\u093e \u092a\u094d\u0930\u092f\u093e\u0938 \u0915\u0930\u0947\u0902",
+ "oauthSignin": "\u0915\u093f\u0938\u0940 \u0926\u0942\u0938\u0930\u0947 \u0916\u093e\u0924\u0947 \u0938\u0947 \u0938\u093e\u0907\u0928 \u0907\u0928 \u0915\u0930\u0928\u0947 \u0915\u093e \u092a\u094d\u0930\u092f\u093e\u0938 \u0915\u0930\u0947\u0902",
+ "redirectUriMismatch": "\u0930\u0940\u0921\u093e\u092f\u0930\u0947\u0915\u094d\u091f URI oauth \u0910\u092a \u0915\u0949\u0928\u094d\u092b\u093c\u093f\u0917\u0930\u0947\u0936\u0928 \u0938\u0947 \u092e\u0947\u0932 \u0928\u0939\u0940\u0902 \u0916\u093e \u0930\u0939\u093e",
+ "oauthCallback": "\u0915\u093f\u0938\u0940 \u0926\u0942\u0938\u0930\u0947 \u0916\u093e\u0924\u0947 \u0938\u0947 \u0938\u093e\u0907\u0928 \u0907\u0928 \u0915\u0930\u0928\u0947 \u0915\u093e \u092a\u094d\u0930\u092f\u093e\u0938 \u0915\u0930\u0947\u0902",
+ "oauthCreateAccount": "\u0915\u093f\u0938\u0940 \u0926\u0942\u0938\u0930\u0947 \u0916\u093e\u0924\u0947 \u0938\u0947 \u0938\u093e\u0907\u0928 \u0907\u0928 \u0915\u0930\u0928\u0947 \u0915\u093e \u092a\u094d\u0930\u092f\u093e\u0938 \u0915\u0930\u0947\u0902",
+ "emailCreateAccount": "\u0915\u093f\u0938\u0940 \u0926\u0942\u0938\u0930\u0947 \u0916\u093e\u0924\u0947 \u0938\u0947 \u0938\u093e\u0907\u0928 \u0907\u0928 \u0915\u0930\u0928\u0947 \u0915\u093e \u092a\u094d\u0930\u092f\u093e\u0938 \u0915\u0930\u0947\u0902",
+ "callback": "\u0915\u093f\u0938\u0940 \u0926\u0942\u0938\u0930\u0947 \u0916\u093e\u0924\u0947 \u0938\u0947 \u0938\u093e\u0907\u0928 \u0907\u0928 \u0915\u0930\u0928\u0947 \u0915\u093e \u092a\u094d\u0930\u092f\u093e\u0938 \u0915\u0930\u0947\u0902",
+ "oauthAccountNotLinked": "\u0905\u092a\u0928\u0940 \u092a\u0939\u091a\u093e\u0928 \u0915\u0940 \u092a\u0941\u0937\u094d\u091f\u093f \u0915\u0930\u0928\u0947 \u0915\u0947 \u0932\u093f\u090f, \u0909\u0938\u0940 \u0916\u093e\u0924\u0947 \u0938\u0947 \u0938\u093e\u0907\u0928 \u0907\u0928 \u0915\u0930\u0947\u0902 \u091c\u093f\u0938\u0915\u093e \u0909\u092a\u092f\u094b\u0917 \u0906\u092a\u0928\u0947 \u092e\u0942\u0932 \u0930\u0942\u092a \u0938\u0947 \u0915\u093f\u092f\u093e \u0925\u093e",
+ "emailSignin": "\u0908\u092e\u0947\u0932 \u0928\u0939\u0940\u0902 \u092d\u0947\u091c\u093e \u091c\u093e \u0938\u0915\u093e",
+ "emailVerify": "\u0915\u0943\u092a\u092f\u093e \u0905\u092a\u0928\u093e \u0908\u092e\u0947\u0932 \u0938\u0924\u094d\u092f\u093e\u092a\u093f\u0924 \u0915\u0930\u0947\u0902, \u090f\u0915 \u0928\u092f\u093e \u0908\u092e\u0947\u0932 \u092d\u0947\u091c\u093e \u0917\u092f\u093e \u0939\u0948",
+ "credentialsSignin": "\u0938\u093e\u0907\u0928 \u0907\u0928 \u0935\u093f\u092b\u0932\u0964 \u0906\u092a\u0915\u0947 \u0926\u094d\u0935\u093e\u0930\u093e \u092a\u094d\u0930\u0926\u093e\u0928 \u0915\u093f\u090f \u0917\u090f \u0935\u093f\u0935\u0930\u0923 \u0915\u0940 \u091c\u093e\u0902\u091a \u0915\u0930\u0947\u0902",
+ "sessionRequired": "\u0907\u0938 \u092a\u0943\u0937\u094d\u0920 \u0924\u0915 \u092a\u0939\u0941\u0902\u091a\u0928\u0947 \u0915\u0947 \u0932\u093f\u090f \u0915\u0943\u092a\u092f\u093e \u0938\u093e\u0907\u0928 \u0907\u0928 \u0915\u0930\u0947\u0902"
+ }
+ },
+ "provider": {
+ "continue": "{{provider}} \u0915\u0947 \u0938\u093e\u0925 \u091c\u093e\u0930\u0940 \u0930\u0916\u0947\u0902"
+ }
+ },
+ "chat": {
+ "input": {
+ "placeholder": "\u0905\u092a\u0928\u093e \u0938\u0902\u0926\u0947\u0936 \u092f\u0939\u093e\u0902 \u091f\u093e\u0907\u092a \u0915\u0930\u0947\u0902...",
+ "actions": {
+ "send": "\u0938\u0902\u0926\u0947\u0936 \u092d\u0947\u091c\u0947\u0902",
+ "stop": "\u0915\u093e\u0930\u094d\u092f \u0930\u094b\u0915\u0947\u0902",
+ "attachFiles": "\u092b\u093c\u093e\u0907\u0932\u0947\u0902 \u0938\u0902\u0932\u0917\u094d\u0928 \u0915\u0930\u0947\u0902"
+ }
+ },
+ "speech": {
+ "start": "\u0930\u093f\u0915\u0949\u0930\u094d\u0921\u093f\u0902\u0917 \u0936\u0941\u0930\u0942 \u0915\u0930\u0947\u0902",
+ "stop": "\u0930\u093f\u0915\u0949\u0930\u094d\u0921\u093f\u0902\u0917 \u0930\u094b\u0915\u0947\u0902",
+ "connecting": "\u0915\u0928\u0947\u0915\u094d\u091f \u0939\u094b \u0930\u0939\u093e \u0939\u0948"
+ },
+ "fileUpload": {
+ "dragDrop": "\u092b\u093c\u093e\u0907\u0932\u094b\u0902 \u0915\u094b \u092f\u0939\u093e\u0902 \u0916\u0940\u0902\u091a\u0947\u0902 \u0914\u0930 \u091b\u094b\u0921\u093c\u0947\u0902",
+ "browse": "\u092b\u093c\u093e\u0907\u0932\u0947\u0902 \u092c\u094d\u0930\u093e\u0909\u091c\u093c \u0915\u0930\u0947\u0902",
+ "sizeLimit": "\u0938\u0940\u092e\u093e:",
+ "errors": {
+ "failed": "\u0905\u092a\u0932\u094b\u0921 \u0915\u0930\u0928\u0947 \u092e\u0947\u0902 \u0935\u093f\u092b\u0932",
+ "cancelled": "\u0915\u093e \u0905\u092a\u0932\u094b\u0921 \u0930\u0926\u094d\u0926 \u0915\u093f\u092f\u093e \u0917\u092f\u093e"
+ }
+ },
+ "commands": {
+ "button": "\u0909\u092a\u0915\u0930\u0923",
+ "changeTool": "\u0909\u092a\u0915\u0930\u0923 \u092c\u0926\u0932\u0947\u0902",
+ "availableTools": "\u0909\u092a\u0932\u092c\u094d\u0927 \u0909\u092a\u0915\u0930\u0923"
+ },
+ "messages": {
+ "status": {
+ "using": "\u0909\u092a\u092f\u094b\u0917 \u0915\u0930 \u0930\u0939\u0947 \u0939\u0948\u0902",
+ "used": "\u0909\u092a\u092f\u094b\u0917 \u0915\u093f\u092f\u093e"
+ },
+ "actions": {
+ "copy": {
+ "button": "\u0915\u094d\u0932\u093f\u092a\u092c\u094b\u0930\u094d\u0921 \u092a\u0930 \u0915\u0949\u092a\u0940 \u0915\u0930\u0947\u0902",
+ "success": "\u0915\u0949\u092a\u0940 \u0915\u093f\u092f\u093e \u0917\u092f\u093e!"
+ }
+ },
+ "feedback": {
+ "positive": "\u0938\u0939\u093e\u092f\u0915",
+ "negative": "\u0938\u0939\u093e\u092f\u0915 \u0928\u0939\u0940\u0902",
+ "edit": "\u092a\u094d\u0930\u0924\u093f\u0915\u094d\u0930\u093f\u092f\u093e \u0938\u0902\u092a\u093e\u0926\u093f\u0924 \u0915\u0930\u0947\u0902",
+ "dialog": {
+ "title": "\u091f\u093f\u092a\u094d\u092a\u0923\u0940 \u091c\u094b\u0921\u093c\u0947\u0902",
+ "submit": "\u092a\u094d\u0930\u0924\u093f\u0915\u094d\u0930\u093f\u092f\u093e \u091c\u092e\u093e \u0915\u0930\u0947\u0902"
+ },
+ "status": {
+ "updating": "\u0905\u092a\u0921\u0947\u091f \u0939\u094b \u0930\u0939\u093e \u0939\u0948",
+ "updated": "\u092a\u094d\u0930\u0924\u093f\u0915\u094d\u0930\u093f\u092f\u093e \u0905\u092a\u0921\u0947\u091f \u0915\u0940 \u0917\u0908"
+ }
+ }
+ },
+ "history": {
+ "title": "\u092a\u093f\u091b\u0932\u0947 \u0907\u0928\u092a\u0941\u091f",
+ "empty": "\u0915\u0941\u091b \u092d\u0940 \u0928\u0939\u0940\u0902 \u0939\u0948...",
+ "show": "\u0907\u0924\u093f\u0939\u093e\u0938 \u0926\u093f\u0916\u093e\u090f\u0902"
+ },
+ "settings": {
+ "title": "\u0938\u0947\u091f\u093f\u0902\u0917\u094d\u0938 \u092a\u0948\u0928\u0932"
+ },
+ "watermark": "\u090f\u0932\u090f\u0932\u090f\u092e \u0917\u0932\u0924\u093f\u092f\u093e\u0902 \u0915\u0930 \u0938\u0915\u0924\u0947 \u0939\u0948\u0902\u0964 \u092e\u0939\u0924\u094d\u0935\u092a\u0942\u0930\u094d\u0923 \u091c\u093e\u0928\u0915\u093e\u0930\u0940 \u0915\u0940 \u091c\u093e\u0902\u091a \u0915\u0930\u0928\u0947 \u092a\u0930 \u0935\u093f\u091a\u093e\u0930 \u0915\u0930\u0947\u0902\u0964"
+ },
+ "threadHistory": {
+ "sidebar": {
+ "title": "\u092a\u093f\u091b\u0932\u0940 \u091a\u0948\u091f",
+ "filters": {
+ "search": "\u0916\u094b\u091c\u0947\u0902",
+ "placeholder": "Search conversations..."
+ },
+ "timeframes": {
+ "today": "\u0906\u091c",
+ "yesterday": "\u0915\u0932",
+ "previous7days": "\u092a\u093f\u091b\u0932\u0947 7 \u0926\u093f\u0928",
+ "previous30days": "\u092a\u093f\u091b\u0932\u0947 30 \u0926\u093f\u0928"
+ },
+ "empty": "\u0915\u094b\u0908 \u0925\u094d\u0930\u0947\u0921 \u0928\u0939\u0940\u0902 \u092e\u093f\u0932\u093e",
+ "actions": {
+ "close": "\u0938\u093e\u0907\u0921\u092c\u093e\u0930 \u092c\u0902\u0926 \u0915\u0930\u0947\u0902",
+ "open": "\u0938\u093e\u0907\u0921\u092c\u093e\u0930 \u0916\u094b\u0932\u0947\u0902"
+ }
+ },
+ "thread": {
+ "untitled": "\u0936\u0940\u0930\u094d\u0937\u0915\u0939\u0940\u0928 \u0935\u093e\u0930\u094d\u0924\u093e\u0932\u093e\u092a",
+ "menu": {
+ "rename": "Rename",
+ "delete": "Delete"
+ },
+ "actions": {
+ "delete": {
+ "title": "\u0939\u091f\u093e\u0928\u0947 \u0915\u0940 \u092a\u0941\u0937\u094d\u091f\u093f \u0915\u0930\u0947\u0902",
+ "description": "\u092f\u0939 \u0925\u094d\u0930\u0947\u0921 \u0914\u0930 \u0907\u0938\u0915\u0947 \u0938\u0902\u0926\u0947\u0936\u094b\u0902 \u0914\u0930 \u0924\u0924\u094d\u0935\u094b\u0902 \u0915\u094b \u0939\u091f\u093e \u0926\u0947\u0917\u093e\u0964 \u092f\u0939 \u0915\u094d\u0930\u093f\u092f\u093e \u0935\u093e\u092a\u0938 \u0928\u0939\u0940\u0902 \u0915\u0940 \u091c\u093e \u0938\u0915\u0924\u0940",
+ "success": "\u091a\u0948\u091f \u0939\u091f\u093e \u0926\u0940 \u0917\u0908",
+ "inProgress": "\u091a\u0948\u091f \u0939\u091f\u093e\u0908 \u091c\u093e \u0930\u0939\u0940 \u0939\u0948"
+ },
+ "rename": {
+ "title": "\u0925\u094d\u0930\u0947\u0921 \u0915\u093e \u0928\u093e\u092e \u092c\u0926\u0932\u0947\u0902",
+ "description": "\u0907\u0938 \u0925\u094d\u0930\u0947\u0921 \u0915\u0947 \u0932\u093f\u090f \u090f\u0915 \u0928\u092f\u093e \u0928\u093e\u092e \u0926\u0930\u094d\u091c \u0915\u0930\u0947\u0902",
+ "form": {
+ "name": {
+ "label": "\u0928\u093e\u092e",
+ "placeholder": "\u0928\u092f\u093e \u0928\u093e\u092e \u0926\u0930\u094d\u091c \u0915\u0930\u0947\u0902"
+ }
+ },
+ "success": "\u0925\u094d\u0930\u0947\u0921 \u0915\u093e \u0928\u093e\u092e \u092c\u0926\u0932 \u0926\u093f\u092f\u093e \u0917\u092f\u093e!",
+ "inProgress": "\u0925\u094d\u0930\u0947\u0921 \u0915\u093e \u0928\u093e\u092e \u092c\u0926\u0932\u093e \u091c\u093e \u0930\u0939\u093e \u0939\u0948"
+ }
+ }
+ }
+ },
+ "navigation": {
+ "header": {
+ "chat": "\u091a\u0948\u091f",
+ "readme": "\u0930\u0940\u0921\u092e\u0940",
+ "theme": {
+ "light": "Light Theme",
+ "dark": "Dark Theme",
+ "system": "Follow System"
+ }
+ },
+ "newChat": {
+ "button": "\u0928\u0908 \u091a\u0948\u091f",
+ "dialog": {
+ "title": "\u0928\u0908 \u091a\u0948\u091f \u092c\u0928\u093e\u090f\u0902",
+ "description": "\u092f\u0939 \u0906\u092a\u0915\u093e \u0935\u0930\u094d\u0924\u092e\u093e\u0928 \u091a\u0948\u091f \u0907\u0924\u093f\u0939\u093e\u0938 \u0938\u093e\u092b\u093c \u0915\u0930 \u0926\u0947\u0917\u093e\u0964 \u0915\u094d\u092f\u093e \u0906\u092a \u091c\u093e\u0930\u0940 \u0930\u0916\u0928\u093e \u091a\u093e\u0939\u0924\u0947 \u0939\u0948\u0902?",
+ "tooltip": "\u0928\u0908 \u091a\u0948\u091f"
+ }
+ },
+ "user": {
+ "menu": {
+ "settings": "\u0938\u0947\u091f\u093f\u0902\u0917\u094d\u0938",
+ "settingsKey": "S",
+ "apiKeys": "API \u0915\u0941\u0902\u091c\u093f\u092f\u093e\u0902",
+ "logout": "\u0932\u0949\u0917\u0906\u0909\u091f"
+ }
+ }
+ },
+ "apiKeys": {
+ "title": "\u0906\u0935\u0936\u094d\u092f\u0915 API \u0915\u0941\u0902\u091c\u093f\u092f\u093e\u0902",
+ "description": "\u0907\u0938 \u0910\u092a \u0915\u093e \u0909\u092a\u092f\u094b\u0917 \u0915\u0930\u0928\u0947 \u0915\u0947 \u0932\u093f\u090f, \u0928\u093f\u092e\u094d\u0928\u0932\u093f\u0916\u093f\u0924 API \u0915\u0941\u0902\u091c\u093f\u092f\u093e\u0902 \u0906\u0935\u0936\u094d\u092f\u0915 \u0939\u0948\u0902\u0964 \u0915\u0941\u0902\u091c\u093f\u092f\u093e\u0902 \u0906\u092a\u0915\u0947 \u0921\u093f\u0935\u093e\u0907\u0938 \u0915\u0947 \u0938\u094d\u0925\u093e\u0928\u0940\u092f \u0938\u0902\u0917\u094d\u0930\u0939\u0923 \u092e\u0947\u0902 \u0938\u0902\u0917\u094d\u0930\u0939\u0940\u0924 \u0915\u0940 \u091c\u093e\u0924\u0940 \u0939\u0948\u0902\u0964",
+ "success": {
+ "saved": "\u0938\u092b\u0932\u0924\u093e\u092a\u0942\u0930\u094d\u0935\u0915 \u0938\u0939\u0947\u091c\u093e \u0917\u092f\u093e"
+ }
+ },
+ "alerts": {
+ "info": "Info",
+ "note": "Note",
+ "tip": "Tip",
+ "important": "Important",
+ "warning": "Warning",
+ "caution": "Caution",
+ "debug": "Debug",
+ "example": "Example",
+ "success": "Success",
+ "help": "Help",
+ "idea": "Idea",
+ "pending": "Pending",
+ "security": "Security",
+ "beta": "Beta",
+ "best-practice": "Best Practice"
+ }
+}
\ No newline at end of file
diff --git a/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/ja.json b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/ja.json
new file mode 100644
index 0000000..5e4922d
--- /dev/null
+++ b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/ja.json
@@ -0,0 +1,218 @@
+{
+ "common": {
+ "actions": {
+ "cancel": "\u30ad\u30e3\u30f3\u30bb\u30eb",
+ "confirm": "\u78ba\u8a8d",
+ "continue": "\u7d9a\u3051\u308b",
+ "goBack": "\u623b\u308b",
+ "reset": "\u30ea\u30bb\u30c3\u30c8",
+ "submit": "\u9001\u4fe1"
+ },
+ "status": {
+ "loading": "\u8aad\u307f\u8fbc\u307f\u4e2d...",
+ "error": {
+ "default": "\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f",
+ "serverConnection": "\u30b5\u30fc\u30d0\u30fc\u306b\u63a5\u7d9a\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f"
+ }
+ }
+ },
+ "auth": {
+ "login": {
+ "title": "\u30a2\u30d7\u30ea\u306b\u30ed\u30b0\u30a4\u30f3",
+ "form": {
+ "email": {
+ "label": "\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9",
+ "required": "\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u306f\u5fc5\u9808\u9805\u76ee\u3067\u3059"
+ },
+ "password": {
+ "label": "\u30d1\u30b9\u30ef\u30fc\u30c9",
+ "required": "\u30d1\u30b9\u30ef\u30fc\u30c9\u306f\u5fc5\u9808\u9805\u76ee\u3067\u3059"
+ },
+ "actions": {
+ "signin": "\u30b5\u30a4\u30f3\u30a4\u30f3"
+ },
+ "alternativeText": {
+ "or": "\u307e\u305f\u306f"
+ }
+ },
+ "errors": {
+ "default": "\u30b5\u30a4\u30f3\u30a4\u30f3\u3067\u304d\u307e\u305b\u3093",
+ "signin": "\u5225\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u3067\u30b5\u30a4\u30f3\u30a4\u30f3\u3057\u3066\u304f\u3060\u3055\u3044",
+ "oauthSignin": "\u5225\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u3067\u30b5\u30a4\u30f3\u30a4\u30f3\u3057\u3066\u304f\u3060\u3055\u3044",
+ "redirectUriMismatch": "\u30ea\u30c0\u30a4\u30ec\u30af\u30c8URI\u304cOAuth\u30a2\u30d7\u30ea\u306e\u8a2d\u5b9a\u3068\u4e00\u81f4\u3057\u307e\u305b\u3093",
+ "oauthCallback": "\u5225\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u3067\u30b5\u30a4\u30f3\u30a4\u30f3\u3057\u3066\u304f\u3060\u3055\u3044",
+ "oauthCreateAccount": "\u5225\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u3067\u30b5\u30a4\u30f3\u30a4\u30f3\u3057\u3066\u304f\u3060\u3055\u3044",
+ "emailCreateAccount": "\u5225\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u3067\u30b5\u30a4\u30f3\u30a4\u30f3\u3057\u3066\u304f\u3060\u3055\u3044",
+ "callback": "\u5225\u306e\u30a2\u30ab\u30a6\u30f3\u30c8\u3067\u30b5\u30a4\u30f3\u30a4\u30f3\u3057\u3066\u304f\u3060\u3055\u3044",
+ "oauthAccountNotLinked": "\u672c\u4eba\u78ba\u8a8d\u306e\u305f\u3081\u3001\u6700\u521d\u306b\u4f7f\u7528\u3057\u305f\u306e\u3068\u540c\u3058\u30a2\u30ab\u30a6\u30f3\u30c8\u3067\u30b5\u30a4\u30f3\u30a4\u30f3\u3057\u3066\u304f\u3060\u3055\u3044",
+ "emailSignin": "\u30e1\u30fc\u30eb\u3092\u9001\u4fe1\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f",
+ "emailVerify": "\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u3092\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u65b0\u3057\u3044\u30e1\u30fc\u30eb\u304c\u9001\u4fe1\u3055\u308c\u307e\u3057\u305f",
+ "credentialsSignin": "\u30b5\u30a4\u30f3\u30a4\u30f3\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002\u5165\u529b\u3057\u305f\u60c5\u5831\u304c\u6b63\u3057\u3044\u304b\u78ba\u8a8d\u3057\u3066\u304f\u3060\u3055\u3044",
+ "sessionRequired": "\u3053\u306e\u30da\u30fc\u30b8\u306b\u30a2\u30af\u30bb\u30b9\u3059\u308b\u306b\u306f\u30b5\u30a4\u30f3\u30a4\u30f3\u3057\u3066\u304f\u3060\u3055\u3044"
+ }
+ },
+ "provider": {
+ "continue": "{{provider}}\u3067\u7d9a\u3051\u308b"
+ }
+ },
+ "chat": {
+ "input": {
+ "placeholder": "\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044...",
+ "actions": {
+ "send": "\u30e1\u30c3\u30bb\u30fc\u30b8\u3092\u9001\u4fe1",
+ "stop": "\u30bf\u30b9\u30af\u3092\u505c\u6b62",
+ "attachFiles": "\u30d5\u30a1\u30a4\u30eb\u3092\u6dfb\u4ed8"
+ }
+ },
+ "speech": {
+ "start": "\u9332\u97f3\u958b\u59cb",
+ "stop": "\u9332\u97f3\u505c\u6b62",
+ "connecting": "\u63a5\u7d9a\u4e2d"
+ },
+ "commands": {
+ "button": "\u30c4\u30fc\u30eb",
+ "changeTool": "\u30c4\u30fc\u30eb\u3092\u5909\u66f4",
+ "availableTools": "\u5229\u7528\u53ef\u80fd\u306a\u30c4\u30fc\u30eb"
+ },
+ "fileUpload": {
+ "dragDrop": "\u3053\u3053\u306b\u30d5\u30a1\u30a4\u30eb\u3092\u30c9\u30e9\u30c3\u30b0\uff06\u30c9\u30ed\u30c3\u30d7",
+ "sizeLimit": "\u5236\u9650\uff1a",
+ "errors": {
+ "failed": "\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u306b\u5931\u6557\u3057\u307e\u3057\u305f",
+ "cancelled": "\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3092\u30ad\u30e3\u30f3\u30bb\u30eb\u3057\u307e\u3057\u305f\uff1a"
+ }
+ },
+ "messages": {
+ "status": {
+ "using": "\u4f7f\u7528\u4e2d",
+ "used": "\u4f7f\u7528\u6e08\u307f"
+ },
+ "actions": {
+ "copy": {
+ "button": "\u30af\u30ea\u30c3\u30d7\u30dc\u30fc\u30c9\u306b\u30b3\u30d4\u30fc",
+ "success": "\u30b3\u30d4\u30fc\u3057\u307e\u3057\u305f\uff01"
+ }
+ },
+ "feedback": {
+ "positive": "\u5f79\u306b\u7acb\u3063\u305f",
+ "negative": "\u5f79\u306b\u7acb\u305f\u306a\u304b\u3063\u305f",
+ "edit": "\u30d5\u30a3\u30fc\u30c9\u30d0\u30c3\u30af\u3092\u7de8\u96c6",
+ "dialog": {
+ "title": "\u30b3\u30e1\u30f3\u30c8\u3092\u8ffd\u52a0",
+ "submit": "\u30d5\u30a3\u30fc\u30c9\u30d0\u30c3\u30af\u3092\u9001\u4fe1"
+ },
+ "status": {
+ "updating": "\u66f4\u65b0\u4e2d",
+ "updated": "\u30d5\u30a3\u30fc\u30c9\u30d0\u30c3\u30af\u3092\u66f4\u65b0\u3057\u307e\u3057\u305f"
+ }
+ }
+ },
+ "history": {
+ "title": "\u6700\u8fd1\u306e\u5165\u529b",
+ "empty": "\u4f55\u3082\u3042\u308a\u307e\u305b\u3093...",
+ "show": "\u5c65\u6b74\u3092\u8868\u793a"
+ },
+ "settings": {
+ "title": "\u8a2d\u5b9a\u30d1\u30cd\u30eb"
+ },
+ "watermark": "\u5927\u898f\u6a21\u8a00\u8a9e\u30e2\u30c7\u30eb\u306f\u9593\u9055\u3044\u3092\u72af\u3059\u53ef\u80fd\u6027\u304c\u3042\u308a\u307e\u3059\u3002\u91cd\u8981\u306a\u60c5\u5831\u306b\u3064\u3044\u3066\u306f\u78ba\u8a8d\u3092\u691c\u8a0e\u3057\u3066\u304f\u3060\u3055\u3044\u3002"
+ },
+ "threadHistory": {
+ "sidebar": {
+ "title": "\u904e\u53bb\u306e\u30c1\u30e3\u30c3\u30c8",
+ "filters": {
+ "search": "\u691c\u7d22",
+ "placeholder": "Search conversations..."
+ },
+ "timeframes": {
+ "today": "\u4eca\u65e5",
+ "yesterday": "\u6628\u65e5",
+ "previous7days": "\u904e\u53bb7\u65e5\u9593",
+ "previous30days": "\u904e\u53bb30\u65e5\u9593"
+ },
+ "empty": "\u30b9\u30ec\u30c3\u30c9\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093",
+ "actions": {
+ "close": "\u30b5\u30a4\u30c9\u30d0\u30fc\u3092\u9589\u3058\u308b",
+ "open": "\u30b5\u30a4\u30c9\u30d0\u30fc\u3092\u958b\u304f"
+ }
+ },
+ "thread": {
+ "untitled": "\u7121\u984c\u306e\u4f1a\u8a71",
+ "menu": {
+ "rename": "Rename",
+ "delete": "Delete"
+ },
+ "actions": {
+ "delete": {
+ "title": "\u524a\u9664\u306e\u78ba\u8a8d",
+ "description": "\u3053\u306e\u30b9\u30ec\u30c3\u30c9\u3068\u305d\u306e\u30e1\u30c3\u30bb\u30fc\u30b8\u3001\u8981\u7d20\u304c\u524a\u9664\u3055\u308c\u307e\u3059\u3002\u3053\u306e\u64cd\u4f5c\u306f\u53d6\u308a\u6d88\u305b\u307e\u305b\u3093",
+ "success": "\u30c1\u30e3\u30c3\u30c8\u3092\u524a\u9664\u3057\u307e\u3057\u305f",
+ "inProgress": "\u30c1\u30e3\u30c3\u30c8\u3092\u524a\u9664\u4e2d"
+ },
+ "rename": {
+ "title": "\u30b9\u30ec\u30c3\u30c9\u306e\u540d\u524d\u3092\u5909\u66f4",
+ "description": "\u3053\u306e\u30b9\u30ec\u30c3\u30c9\u306e\u65b0\u3057\u3044\u540d\u524d\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044",
+ "form": {
+ "name": {
+ "label": "\u540d\u524d",
+ "placeholder": "\u65b0\u3057\u3044\u540d\u524d\u3092\u5165\u529b"
+ }
+ },
+ "success": "\u30b9\u30ec\u30c3\u30c9\u540d\u3092\u5909\u66f4\u3057\u307e\u3057\u305f\uff01",
+ "inProgress": "\u30b9\u30ec\u30c3\u30c9\u540d\u3092\u5909\u66f4\u4e2d"
+ }
+ }
+ }
+ },
+ "navigation": {
+ "header": {
+ "chat": "\u30c1\u30e3\u30c3\u30c8",
+ "readme": "\u8aac\u660e\u66f8",
+ "theme": {
+ "light": "Light Theme",
+ "dark": "Dark Theme",
+ "system": "Follow System"
+ }
+ },
+ "newChat": {
+ "button": "\u65b0\u898f\u30c1\u30e3\u30c3\u30c8",
+ "dialog": {
+ "title": "\u65b0\u898f\u30c1\u30e3\u30c3\u30c8\u306e\u4f5c\u6210",
+ "description": "\u73fe\u5728\u306e\u30c1\u30e3\u30c3\u30c8\u5c65\u6b74\u304c\u30af\u30ea\u30a2\u3055\u308c\u307e\u3059\u3002\u7d9a\u884c\u3057\u307e\u3059\u304b\uff1f",
+ "tooltip": "\u65b0\u898f\u30c1\u30e3\u30c3\u30c8"
+ }
+ },
+ "user": {
+ "menu": {
+ "settings": "\u8a2d\u5b9a",
+ "settingsKey": "S",
+ "apiKeys": "API\u30ad\u30fc",
+ "logout": "\u30ed\u30b0\u30a2\u30a6\u30c8"
+ }
+ }
+ },
+ "apiKeys": {
+ "title": "\u5fc5\u8981\u306aAPI\u30ad\u30fc",
+ "description": "\u3053\u306e\u30a2\u30d7\u30ea\u3092\u4f7f\u7528\u3059\u308b\u306b\u306f\u3001\u4ee5\u4e0b\u306eAPI\u30ad\u30fc\u304c\u5fc5\u8981\u3067\u3059\u3002\u30ad\u30fc\u306f\u304a\u4f7f\u3044\u306e\u30c7\u30d0\u30a4\u30b9\u306e\u30ed\u30fc\u30ab\u30eb\u30b9\u30c8\u30ec\u30fc\u30b8\u306b\u4fdd\u5b58\u3055\u308c\u307e\u3059\u3002",
+ "success": {
+ "saved": "\u4fdd\u5b58\u304c\u5b8c\u4e86\u3057\u307e\u3057\u305f"
+ }
+ },
+ "alerts": {
+ "info": "Info",
+ "note": "Note",
+ "tip": "Tip",
+ "important": "Important",
+ "warning": "Warning",
+ "caution": "Caution",
+ "debug": "Debug",
+ "example": "Example",
+ "success": "Success",
+ "help": "Help",
+ "idea": "Idea",
+ "pending": "Pending",
+ "security": "Security",
+ "beta": "Beta",
+ "best-practice": "Best Practice"
+ }
+}
\ No newline at end of file
diff --git a/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/kn.json b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/kn.json
new file mode 100644
index 0000000..434c52b
--- /dev/null
+++ b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/kn.json
@@ -0,0 +1,219 @@
+{
+ "common": {
+ "actions": {
+ "cancel": "\u0cb0\u0ca6\u0ccd\u0ca6\u0cc1\u0cae\u0cbe\u0ca1\u0cbf",
+ "confirm": "\u0ca6\u0cc3\u0ca2\u0cc0\u0c95\u0cb0\u0cbf\u0cb8\u0cbf",
+ "continue": "\u0cae\u0cc1\u0c82\u0ca6\u0cc1\u0cb5\u0cb0\u0cbf\u0cb8\u0cbf",
+ "goBack": "\u0cb9\u0cbf\u0c82\u0ca6\u0cc6 \u0cb9\u0ccb\u0c97\u0cbf",
+ "reset": "\u0cae\u0cb0\u0cc1\u0cb9\u0cca\u0c82\u0ca6\u0cbf\u0cb8\u0cbf",
+ "submit": "\u0cb8\u0cb2\u0ccd\u0cb2\u0cbf\u0cb8\u0cbf"
+ },
+ "status": {
+ "loading": "\u0cb2\u0ccb\u0ca1\u0ccd \u0c86\u0c97\u0cc1\u0ca4\u0ccd\u0ca4\u0cbf\u0ca6\u0cc6...",
+ "error": {
+ "default": "\u0ca6\u0ccb\u0cb7 \u0cb8\u0c82\u0cad\u0cb5\u0cbf\u0cb8\u0cbf\u0ca6\u0cc6",
+ "serverConnection": "\u0cb8\u0cb0\u0ccd\u0cb5\u0cb0\u0ccd\u200c \u0c85\u0ca8\u0ccd\u0ca8\u0cc1 \u0ca4\u0cb2\u0cc1\u0caa\u0cb2\u0cc1 \u0cb8\u0cbe\u0ca7\u0ccd\u0caf\u0cb5\u0cbe\u0c97\u0cb2\u0cbf\u0cb2\u0ccd\u0cb2"
+ }
+ }
+ },
+ "auth": {
+ "login": {
+ "title": "\u0c85\u0caa\u0ccd\u0cb2\u0cbf\u0c95\u0cc7\u0cb6\u0ca8\u0ccd\u200c\u0c97\u0cc6 \u0caa\u0ccd\u0cb0\u0cb5\u0cc7\u0cb6\u0cbf\u0cb8\u0cb2\u0cc1 \u0cb2\u0cbe\u0c97\u0cbf\u0ca8\u0ccd \u0cae\u0cbe\u0ca1\u0cbf",
+ "form": {
+ "email": {
+ "label": "\u0c87\u0cae\u0cc7\u0cb2\u0ccd \u0cb5\u0cbf\u0cb3\u0cbe\u0cb8",
+ "required": "\u0c87\u0cae\u0cc7\u0cb2\u0ccd \u0c85\u0c97\u0ca4\u0ccd\u0caf\u0cb5\u0cbf\u0cb0\u0cc1\u0cb5 \u0c95\u0ccd\u0cb7\u0cc7\u0ca4\u0ccd\u0cb0"
+ },
+ "password": {
+ "label": "\u0caa\u0cbe\u0cb8\u0ccd\u200c\u0cb5\u0cb0\u0ccd\u0ca1\u0ccd",
+ "required": "\u0caa\u0cbe\u0cb8\u0ccd\u200c\u0cb5\u0cb0\u0ccd\u0ca1\u0ccd \u0c85\u0c97\u0ca4\u0ccd\u0caf\u0cb5\u0cbf\u0cb0\u0cc1\u0cb5 \u0c95\u0ccd\u0cb7\u0cc7\u0ca4\u0ccd\u0cb0"
+ },
+ "actions": {
+ "signin": "\u0cb8\u0cc8\u0ca8\u0ccd \u0c87\u0ca8\u0ccd \u0cae\u0cbe\u0ca1\u0cbf"
+ },
+ "alternativeText": {
+ "or": "\u0c85\u0ca5\u0cb5\u0cbe"
+ }
+ },
+ "errors": {
+ "default": "\u0cb8\u0cc8\u0ca8\u0ccd \u0c87\u0ca8\u0ccd \u0cae\u0cbe\u0ca1\u0cb2\u0cc1 \u0cb8\u0cbe\u0ca7\u0ccd\u0caf\u0cb5\u0cbe\u0c97\u0cb2\u0cbf\u0cb2\u0ccd\u0cb2",
+ "signin": "\u0cac\u0cc7\u0cb0\u0cc6 \u0c96\u0cbe\u0ca4\u0cc6\u0caf\u0cca\u0c82\u0ca6\u0cbf\u0c97\u0cc6 \u0cb8\u0cc8\u0ca8\u0ccd \u0c87\u0ca8\u0ccd \u0cae\u0cbe\u0ca1\u0cb2\u0cc1 \u0caa\u0ccd\u0cb0\u0caf\u0ca4\u0ccd\u0ca8\u0cbf\u0cb8\u0cbf",
+ "oauthSignin": "\u0cac\u0cc7\u0cb0\u0cc6 \u0c96\u0cbe\u0ca4\u0cc6\u0caf\u0cca\u0c82\u0ca6\u0cbf\u0c97\u0cc6 \u0cb8\u0cc8\u0ca8\u0ccd \u0c87\u0ca8\u0ccd \u0cae\u0cbe\u0ca1\u0cb2\u0cc1 \u0caa\u0ccd\u0cb0\u0caf\u0ca4\u0ccd\u0ca8\u0cbf\u0cb8\u0cbf",
+ "redirectUriMismatch": "\u0cb0\u0cc0\u0ca1\u0cc8\u0cb0\u0cc6\u0c95\u0ccd\u0c9f\u0ccd URI \u0c93\u0ca5\u0ccd \u0c85\u0caa\u0ccd\u0cb2\u0cbf\u0c95\u0cc7\u0cb6\u0ca8\u0ccd \u0c95\u0cbe\u0ca8\u0ccd\u0cab\u0cbf\u0c97\u0cb0\u0cc7\u0cb6\u0ca8\u0ccd\u200c\u0c97\u0cc6 \u0cb9\u0cca\u0c82\u0ca6\u0cbf\u0c95\u0cc6\u0caf\u0cbe\u0c97\u0cc1\u0ca4\u0ccd\u0ca4\u0cbf\u0cb2\u0ccd\u0cb2",
+ "oauthCallback": "\u0cac\u0cc7\u0cb0\u0cc6 \u0c96\u0cbe\u0ca4\u0cc6\u0caf\u0cca\u0c82\u0ca6\u0cbf\u0c97\u0cc6 \u0cb8\u0cc8\u0ca8\u0ccd \u0c87\u0ca8\u0ccd \u0cae\u0cbe\u0ca1\u0cb2\u0cc1 \u0caa\u0ccd\u0cb0\u0caf\u0ca4\u0ccd\u0ca8\u0cbf\u0cb8\u0cbf",
+ "oauthCreateAccount": "\u0cac\u0cc7\u0cb0\u0cc6 \u0c96\u0cbe\u0ca4\u0cc6\u0caf\u0cca\u0c82\u0ca6\u0cbf\u0c97\u0cc6 \u0cb8\u0cc8\u0ca8\u0ccd \u0c87\u0ca8\u0ccd \u0cae\u0cbe\u0ca1\u0cb2\u0cc1 \u0caa\u0ccd\u0cb0\u0caf\u0ca4\u0ccd\u0ca8\u0cbf\u0cb8\u0cbf",
+ "emailCreateAccount": "\u0cac\u0cc7\u0cb0\u0cc6 \u0c96\u0cbe\u0ca4\u0cc6\u0caf\u0cca\u0c82\u0ca6\u0cbf\u0c97\u0cc6 \u0cb8\u0cc8\u0ca8\u0ccd \u0c87\u0ca8\u0ccd \u0cae\u0cbe\u0ca1\u0cb2\u0cc1 \u0caa\u0ccd\u0cb0\u0caf\u0ca4\u0ccd\u0ca8\u0cbf\u0cb8\u0cbf",
+ "callback": "\u0cac\u0cc7\u0cb0\u0cc6 \u0c96\u0cbe\u0ca4\u0cc6\u0caf\u0cca\u0c82\u0ca6\u0cbf\u0c97\u0cc6 \u0cb8\u0cc8\u0ca8\u0ccd \u0c87\u0ca8\u0ccd \u0cae\u0cbe\u0ca1\u0cb2\u0cc1 \u0caa\u0ccd\u0cb0\u0caf\u0ca4\u0ccd\u0ca8\u0cbf\u0cb8\u0cbf",
+ "oauthAccountNotLinked": "\u0ca8\u0cbf\u0cae\u0ccd\u0cae \u0c97\u0cc1\u0cb0\u0cc1\u0ca4\u0ca8\u0ccd\u0ca8\u0cc1 \u0ca6\u0cc3\u0ca2\u0cc0\u0c95\u0cb0\u0cbf\u0cb8\u0cb2\u0cc1, \u0ca8\u0cc0\u0cb5\u0cc1 \u0cae\u0cca\u0ca6\u0cb2\u0cc1 \u0cac\u0cb3\u0cb8\u0cbf\u0ca6 \u0c85\u0ca6\u0cc7 \u0c96\u0cbe\u0ca4\u0cc6\u0caf\u0cca\u0c82\u0ca6\u0cbf\u0c97\u0cc6 \u0cb8\u0cc8\u0ca8\u0ccd \u0c87\u0ca8\u0ccd \u0cae\u0cbe\u0ca1\u0cbf",
+ "emailSignin": "\u0c87\u0cae\u0cc7\u0cb2\u0ccd \u0c95\u0cb3\u0cc1\u0cb9\u0cbf\u0cb8\u0cb2\u0cc1 \u0cb8\u0cbe\u0ca7\u0ccd\u0caf\u0cb5\u0cbe\u0c97\u0cb2\u0cbf\u0cb2\u0ccd\u0cb2",
+ "emailVerify": "\u0ca6\u0caf\u0cb5\u0cbf\u0c9f\u0ccd\u0c9f\u0cc1 \u0ca8\u0cbf\u0cae\u0ccd\u0cae \u0c87\u0cae\u0cc7\u0cb2\u0ccd \u0caa\u0cb0\u0cbf\u0cb6\u0cc0\u0cb2\u0cbf\u0cb8\u0cbf, \u0cb9\u0cca\u0cb8 \u0c87\u0cae\u0cc7\u0cb2\u0ccd \u0c95\u0cb3\u0cc1\u0cb9\u0cbf\u0cb8\u0cb2\u0cbe\u0c97\u0cbf\u0ca6\u0cc6",
+ "credentialsSignin": "\u0cb8\u0cc8\u0ca8\u0ccd \u0c87\u0ca8\u0ccd \u0cb5\u0cbf\u0cab\u0cb2\u0cb5\u0cbe\u0c97\u0cbf\u0ca6\u0cc6. \u0ca8\u0cc0\u0cb5\u0cc1 \u0c92\u0ca6\u0c97\u0cbf\u0cb8\u0cbf\u0ca6 \u0cb5\u0cbf\u0cb5\u0cb0\u0c97\u0cb3\u0cc1 \u0cb8\u0cb0\u0cbf\u0caf\u0cbe\u0c97\u0cbf\u0cb5\u0cc6\u0caf\u0cc7 \u0c8e\u0c82\u0ca6\u0cc1 \u0caa\u0cb0\u0cbf\u0cb6\u0cc0\u0cb2\u0cbf\u0cb8\u0cbf",
+ "sessionRequired": "\u0c88 \u0caa\u0cc1\u0c9f\u0cb5\u0ca8\u0ccd\u0ca8\u0cc1 \u0caa\u0ccd\u0cb0\u0cb5\u0cc7\u0cb6\u0cbf\u0cb8\u0cb2\u0cc1 \u0ca6\u0caf\u0cb5\u0cbf\u0c9f\u0ccd\u0c9f\u0cc1 \u0cb8\u0cc8\u0ca8\u0ccd \u0c87\u0ca8\u0ccd \u0cae\u0cbe\u0ca1\u0cbf"
+ }
+ },
+ "provider": {
+ "continue": "{{provider}} \u0ca8\u0cca\u0c82\u0ca6\u0cbf\u0c97\u0cc6 \u0cae\u0cc1\u0c82\u0ca6\u0cc1\u0cb5\u0cb0\u0cbf\u0cb8\u0cbf"
+ }
+ },
+ "chat": {
+ "input": {
+ "placeholder": "\u0ca8\u0cbf\u0cae\u0ccd\u0cae \u0cb8\u0c82\u0ca6\u0cc7\u0cb6\u0cb5\u0ca8\u0ccd\u0ca8\u0cc1 \u0c87\u0cb2\u0ccd\u0cb2\u0cbf \u0c9f\u0cc8\u0caa\u0ccd \u0cae\u0cbe\u0ca1\u0cbf...",
+ "actions": {
+ "send": "\u0cb8\u0c82\u0ca6\u0cc7\u0cb6 \u0c95\u0cb3\u0cc1\u0cb9\u0cbf\u0cb8\u0cbf",
+ "stop": "\u0c95\u0cbe\u0cb0\u0ccd\u0caf \u0ca8\u0cbf\u0cb2\u0ccd\u0cb2\u0cbf\u0cb8\u0cbf",
+ "attachFiles": "\u0cab\u0cc8\u0cb2\u0ccd\u200c\u0c97\u0cb3\u0ca8\u0ccd\u0ca8\u0cc1 \u0cb2\u0c97\u0ca4\u0ccd\u0ca4\u0cbf\u0cb8\u0cbf"
+ }
+ },
+ "commands": {
+ "button": "\u0c89\u0caa\u0c95\u0cb0\u0ca3\u0c97\u0cb3\u0cc1",
+ "changeTool": "\u0c89\u0caa\u0c95\u0cb0\u0ca3\u0cb5\u0ca8\u0ccd\u0ca8\u0cc1 \u0cac\u0ca6\u0cb2\u0cbf\u0cb8\u0cbf",
+ "availableTools": "\u0cb2\u0cad\u0ccd\u0caf\u0cb5\u0cbf\u0cb0\u0cc1\u0cb5 \u0c89\u0caa\u0c95\u0cb0\u0ca3\u0c97\u0cb3\u0cc1"
+ },
+ "speech": {
+ "start": "\u0cb0\u0cc6\u0c95\u0cbe\u0cb0\u0ccd\u0ca1\u0cbf\u0c82\u0c97\u0ccd \u0caa\u0ccd\u0cb0\u0cbe\u0cb0\u0c82\u0cad\u0cbf\u0cb8\u0cbf",
+ "stop": "\u0cb0\u0cc6\u0c95\u0cbe\u0cb0\u0ccd\u0ca1\u0cbf\u0c82\u0c97\u0ccd \u0ca8\u0cbf\u0cb2\u0ccd\u0cb2\u0cbf\u0cb8\u0cbf",
+ "connecting": "\u0cb8\u0c82\u0caa\u0cb0\u0ccd\u0c95\u0cbf\u0cb8\u0cb2\u0cbe\u0c97\u0cc1\u0ca4\u0ccd\u0ca4\u0cbf\u0ca6\u0cc6"
+ },
+ "fileUpload": {
+ "dragDrop": "\u0cab\u0cc8\u0cb2\u0ccd\u200c\u0c97\u0cb3\u0ca8\u0ccd\u0ca8\u0cc1 \u0c87\u0cb2\u0ccd\u0cb2\u0cbf \u0c8e\u0cb3\u0cc6\u0ca6\u0cc1 \u0cac\u0cbf\u0ca1\u0cbf",
+ "browse": "\u0cab\u0cc8\u0cb2\u0ccd\u200c\u0c97\u0cb3\u0ca8\u0ccd\u0ca8\u0cc1 \u0cac\u0ccd\u0cb0\u0ccc\u0cb8\u0ccd \u0cae\u0cbe\u0ca1\u0cbf",
+ "sizeLimit": "\u0cae\u0cbf\u0ca4\u0cbf:",
+ "errors": {
+ "failed": "\u0c85\u0caa\u0ccd\u200c\u0cb2\u0ccb\u0ca1\u0ccd \u0cb5\u0cbf\u0cab\u0cb2\u0cb5\u0cbe\u0c97\u0cbf\u0ca6\u0cc6",
+ "cancelled": "\u0c85\u0caa\u0ccd\u200c\u0cb2\u0ccb\u0ca1\u0ccd \u0cb0\u0ca6\u0ccd\u0ca6\u0cc1\u0c97\u0cca\u0cb3\u0cbf\u0cb8\u0cb2\u0cbe\u0c97\u0cbf\u0ca6\u0cc6"
+ }
+ },
+ "messages": {
+ "status": {
+ "using": "\u0cac\u0cb3\u0cb8\u0cc1\u0ca4\u0ccd\u0ca4\u0cbf\u0cb0\u0cc1\u0cb5\u0cc1\u0ca6\u0cc1",
+ "used": "\u0cac\u0cb3\u0cb8\u0cb2\u0cbe\u0c97\u0cbf\u0ca6\u0cc6"
+ },
+ "actions": {
+ "copy": {
+ "button": "\u0c95\u0ccd\u0cb2\u0cbf\u0caa\u0ccd\u200c\u0cac\u0ccb\u0cb0\u0ccd\u0ca1\u0ccd\u200c\u0c97\u0cc6 \u0ca8\u0c95\u0cb2\u0cbf\u0cb8\u0cbf",
+ "success": "\u0ca8\u0c95\u0cb2\u0cbf\u0cb8\u0cb2\u0cbe\u0c97\u0cbf\u0ca6\u0cc6!"
+ }
+ },
+ "feedback": {
+ "positive": "\u0cb8\u0cb9\u0cbe\u0caf\u0c95\u0cb5\u0cbe\u0c97\u0cbf\u0ca6\u0cc6",
+ "negative": "\u0cb8\u0cb9\u0cbe\u0caf\u0c95\u0cb5\u0cbe\u0c97\u0cbf\u0cb2\u0ccd\u0cb2",
+ "edit": "\u0caa\u0ccd\u0cb0\u0ca4\u0cbf\u0c95\u0ccd\u0cb0\u0cbf\u0caf\u0cc6 \u0cb8\u0c82\u0caa\u0cbe\u0ca6\u0cbf\u0cb8\u0cbf",
+ "dialog": {
+ "title": "\u0c95\u0cbe\u0cae\u0cc6\u0c82\u0c9f\u0ccd \u0cb8\u0cc7\u0cb0\u0cbf\u0cb8\u0cbf",
+ "submit": "\u0caa\u0ccd\u0cb0\u0ca4\u0cbf\u0c95\u0ccd\u0cb0\u0cbf\u0caf\u0cc6 \u0cb8\u0cb2\u0ccd\u0cb2\u0cbf\u0cb8\u0cbf"
+ },
+ "status": {
+ "updating": "\u0ca8\u0cb5\u0cc0\u0c95\u0cb0\u0cbf\u0cb8\u0cb2\u0cbe\u0c97\u0cc1\u0ca4\u0ccd\u0ca4\u0cbf\u0ca6\u0cc6",
+ "updated": "\u0caa\u0ccd\u0cb0\u0ca4\u0cbf\u0c95\u0ccd\u0cb0\u0cbf\u0caf\u0cc6 \u0ca8\u0cb5\u0cc0\u0c95\u0cb0\u0cbf\u0cb8\u0cb2\u0cbe\u0c97\u0cbf\u0ca6\u0cc6"
+ }
+ }
+ },
+ "history": {
+ "title": "\u0c95\u0cca\u0ca8\u0cc6\u0caf \u0c87\u0ca8\u0ccd\u200c\u0caa\u0cc1\u0c9f\u0ccd\u200c\u0c97\u0cb3\u0cc1",
+ "empty": "\u0c96\u0cbe\u0cb2\u0cbf\u0caf\u0cbe\u0c97\u0cbf\u0ca6\u0cc6...",
+ "show": "\u0c87\u0ca4\u0cbf\u0cb9\u0cbe\u0cb8 \u0ca4\u0ccb\u0cb0\u0cbf\u0cb8\u0cbf"
+ },
+ "settings": {
+ "title": "\u0cb8\u0cc6\u0c9f\u0ccd\u0c9f\u0cbf\u0c82\u0c97\u0ccd\u200c\u0c97\u0cb3 \u0caa\u0ccd\u0caf\u0cbe\u0ca8\u0cc6\u0cb2\u0ccd"
+ },
+ "watermark": "LLM \u0c97\u0cb3\u0cc1 \u0ca4\u0caa\u0ccd\u0caa\u0cc1\u0c97\u0cb3\u0ca8\u0ccd\u0ca8\u0cc1 \u0cae\u0cbe\u0ca1\u0cac\u0cb9\u0cc1\u0ca6\u0cc1. \u0caa\u0ccd\u0cb0\u0cae\u0cc1\u0c96 \u0cae\u0cbe\u0cb9\u0cbf\u0ca4\u0cbf\u0caf\u0ca8\u0ccd\u0ca8\u0cc1 \u0caa\u0cb0\u0cbf\u0cb6\u0cc0\u0cb2\u0cbf\u0cb8\u0cc1\u0cb5\u0cc1\u0ca6\u0ca8\u0ccd\u0ca8\u0cc1 \u0caa\u0cb0\u0cbf\u0c97\u0ca3\u0cbf\u0cb8\u0cbf."
+ },
+ "threadHistory": {
+ "sidebar": {
+ "title": "\u0cb9\u0cbf\u0c82\u0ca6\u0cbf\u0ca8 \u0cb8\u0c82\u0cad\u0cbe\u0cb7\u0ca3\u0cc6\u0c97\u0cb3\u0cc1",
+ "filters": {
+ "search": "\u0cb9\u0cc1\u0ca1\u0cc1\u0c95\u0cbf",
+ "placeholder": "Search conversations..."
+ },
+ "timeframes": {
+ "today": "\u0c87\u0c82\u0ca6\u0cc1",
+ "yesterday": "\u0ca8\u0cbf\u0ca8\u0ccd\u0ca8\u0cc6",
+ "previous7days": "\u0cb9\u0cbf\u0c82\u0ca6\u0cbf\u0ca8 7 \u0ca6\u0cbf\u0ca8\u0c97\u0cb3\u0cc1",
+ "previous30days": "\u0cb9\u0cbf\u0c82\u0ca6\u0cbf\u0ca8 30 \u0ca6\u0cbf\u0ca8\u0c97\u0cb3\u0cc1"
+ },
+ "empty": "\u0caf\u0cbe\u0cb5\u0cc1\u0ca6\u0cc7 \u0cb8\u0c82\u0cad\u0cbe\u0cb7\u0ca3\u0cc6\u0c97\u0cb3\u0cc1 \u0c95\u0c82\u0ca1\u0cc1\u0cac\u0c82\u0ca6\u0cbf\u0cb2\u0ccd\u0cb2",
+ "actions": {
+ "close": "\u0caa\u0c95\u0ccd\u0c95\u0ca6 \u0caa\u0c9f\u0ccd\u0c9f\u0cbf \u0cae\u0cc1\u0c9a\u0ccd\u0c9a\u0cbf",
+ "open": "\u0caa\u0c95\u0ccd\u0c95\u0ca6 \u0caa\u0c9f\u0ccd\u0c9f\u0cbf \u0ca4\u0cc6\u0cb0\u0cc6\u0caf\u0cbf\u0cb0\u0cbf"
+ }
+ },
+ "thread": {
+ "untitled": "\u0cb6\u0cc0\u0cb0\u0ccd\u0cb7\u0cbf\u0c95\u0cc6\u0cb0\u0cb9\u0cbf\u0ca4 \u0cb8\u0c82\u0cad\u0cbe\u0cb7\u0ca3\u0cc6",
+ "menu": {
+ "rename": "Rename",
+ "delete": "Delete"
+ },
+ "actions": {
+ "delete": {
+ "title": "\u0c85\u0cb3\u0cbf\u0cb8\u0cc1\u0cb5\u0cbf\u0c95\u0cc6\u0caf\u0ca8\u0ccd\u0ca8\u0cc1 \u0ca6\u0cc3\u0ca2\u0cc0\u0c95\u0cb0\u0cbf\u0cb8\u0cbf",
+ "description": "\u0c87\u0ca6\u0cc1 \u0cb8\u0c82\u0cad\u0cbe\u0cb7\u0ca3\u0cc6\u0caf\u0ca8\u0ccd\u0ca8\u0cc1 \u0cb9\u0cbe\u0c97\u0cc2 \u0c85\u0ca6\u0cb0 \u0cb8\u0c82\u0ca6\u0cc7\u0cb6\u0c97\u0cb3\u0cc1 \u0cae\u0ca4\u0ccd\u0ca4\u0cc1 \u0c85\u0c82\u0cb6\u0c97\u0cb3\u0ca8\u0ccd\u0ca8\u0cc1 \u0c85\u0cb3\u0cbf\u0cb8\u0cc1\u0ca4\u0ccd\u0ca4\u0ca6\u0cc6. \u0c88 \u0c95\u0ccd\u0cb0\u0cbf\u0caf\u0cc6\u0caf\u0ca8\u0ccd\u0ca8\u0cc1 \u0cb0\u0ca6\u0ccd\u0ca6\u0cc1\u0c97\u0cca\u0cb3\u0cbf\u0cb8\u0cb2\u0cc1 \u0cb8\u0cbe\u0ca7\u0ccd\u0caf\u0cb5\u0cbf\u0cb2\u0ccd\u0cb2",
+ "success": "\u0cb8\u0c82\u0cad\u0cbe\u0cb7\u0ca3\u0cc6 \u0c85\u0cb3\u0cbf\u0cb8\u0cb2\u0cbe\u0c97\u0cbf\u0ca6\u0cc6",
+ "inProgress": "\u0cb8\u0c82\u0cad\u0cbe\u0cb7\u0ca3\u0cc6 \u0c85\u0cb3\u0cbf\u0cb8\u0cb2\u0cbe\u0c97\u0cc1\u0ca4\u0ccd\u0ca4\u0cbf\u0ca6\u0cc6"
+ },
+ "rename": {
+ "title": "\u0cb8\u0c82\u0cad\u0cbe\u0cb7\u0ca3\u0cc6\u0caf \u0cb9\u0cc6\u0cb8\u0cb0\u0cc1 \u0cac\u0ca6\u0cb2\u0cbe\u0caf\u0cbf\u0cb8\u0cbf",
+ "description": "\u0c88 \u0cb8\u0c82\u0cad\u0cbe\u0cb7\u0ca3\u0cc6\u0c97\u0cc6 \u0cb9\u0cca\u0cb8 \u0cb9\u0cc6\u0cb8\u0cb0\u0ca8\u0ccd\u0ca8\u0cc1 \u0ca8\u0cae\u0cc2\u0ca6\u0cbf\u0cb8\u0cbf",
+ "form": {
+ "name": {
+ "label": "\u0cb9\u0cc6\u0cb8\u0cb0\u0cc1",
+ "placeholder": "\u0cb9\u0cca\u0cb8 \u0cb9\u0cc6\u0cb8\u0cb0\u0ca8\u0ccd\u0ca8\u0cc1 \u0ca8\u0cae\u0cc2\u0ca6\u0cbf\u0cb8\u0cbf"
+ }
+ },
+ "success": "\u0cb8\u0c82\u0cad\u0cbe\u0cb7\u0ca3\u0cc6\u0caf \u0cb9\u0cc6\u0cb8\u0cb0\u0cc1 \u0cac\u0ca6\u0cb2\u0cbe\u0caf\u0cbf\u0cb8\u0cb2\u0cbe\u0c97\u0cbf\u0ca6\u0cc6!",
+ "inProgress": "\u0cb8\u0c82\u0cad\u0cbe\u0cb7\u0ca3\u0cc6\u0caf \u0cb9\u0cc6\u0cb8\u0cb0\u0cc1 \u0cac\u0ca6\u0cb2\u0cbe\u0caf\u0cbf\u0cb8\u0cb2\u0cbe\u0c97\u0cc1\u0ca4\u0ccd\u0ca4\u0cbf\u0ca6\u0cc6"
+ }
+ }
+ }
+ },
+ "navigation": {
+ "header": {
+ "chat": "\u0cb8\u0c82\u0cad\u0cbe\u0cb7\u0ca3\u0cc6",
+ "readme": "\u0c93\u0ca6\u0cbf",
+ "theme": {
+ "light": "Light Theme",
+ "dark": "Dark Theme",
+ "system": "Follow System"
+ }
+ },
+ "newChat": {
+ "button": "\u0cb9\u0cca\u0cb8 \u0cb8\u0c82\u0cad\u0cbe\u0cb7\u0ca3\u0cc6",
+ "dialog": {
+ "title": "\u0cb9\u0cca\u0cb8 \u0cb8\u0c82\u0cad\u0cbe\u0cb7\u0ca3\u0cc6 \u0cb0\u0c9a\u0cbf\u0cb8\u0cbf",
+ "description": "\u0c87\u0ca6\u0cc1 \u0ca8\u0cbf\u0cae\u0ccd\u0cae \u0caa\u0ccd\u0cb0\u0cb8\u0ccd\u0ca4\u0cc1\u0ca4 \u0cb8\u0c82\u0cad\u0cbe\u0cb7\u0ca3\u0cc6\u0caf \u0c87\u0ca4\u0cbf\u0cb9\u0cbe\u0cb8\u0cb5\u0ca8\u0ccd\u0ca8\u0cc1 \u0c85\u0cb3\u0cbf\u0cb8\u0cc1\u0ca4\u0ccd\u0ca4\u0ca6\u0cc6. \u0ca8\u0cc0\u0cb5\u0cc1 \u0cae\u0cc1\u0c82\u0ca6\u0cc1\u0cb5\u0cb0\u0cc6\u0caf\u0cb2\u0cc1 \u0cac\u0caf\u0cb8\u0cc1\u0cb5\u0cbf\u0cb0\u0cbe?",
+ "tooltip": "\u0cb9\u0cca\u0cb8 \u0cb8\u0c82\u0cad\u0cbe\u0cb7\u0ca3\u0cc6"
+ }
+ },
+ "user": {
+ "menu": {
+ "settings": "\u0cb8\u0cc6\u0c9f\u0ccd\u0c9f\u0cbf\u0c82\u0c97\u0ccd\u200c\u0c97\u0cb3\u0cc1",
+ "settingsKey": "S",
+ "apiKeys": "API \u0c95\u0cc0\u0c97\u0cb3\u0cc1",
+ "logout": "\u0cb2\u0cbe\u0c97\u0ccd \u0c94\u0c9f\u0ccd"
+ }
+ }
+ },
+ "apiKeys": {
+ "title": "\u0c85\u0c97\u0ca4\u0ccd\u0caf\u0cb5\u0cbf\u0cb0\u0cc1\u0cb5 API \u0c95\u0cc0\u0c97\u0cb3\u0cc1",
+ "description": "\u0c88 \u0c85\u0caa\u0ccd\u0cb2\u0cbf\u0c95\u0cc7\u0cb6\u0ca8\u0ccd \u0cac\u0cb3\u0cb8\u0cb2\u0cc1, \u0c88 \u0c95\u0cc6\u0cb3\u0c97\u0cbf\u0ca8 API \u0c95\u0cc0\u0c97\u0cb3\u0cc1 \u0c85\u0c97\u0ca4\u0ccd\u0caf\u0cb5\u0cbf\u0cb0\u0cc1\u0ca4\u0ccd\u0ca4\u0cb5\u0cc6. \u0c95\u0cc0\u0c97\u0cb3\u0ca8\u0ccd\u0ca8\u0cc1 \u0ca8\u0cbf\u0cae\u0ccd\u0cae \u0cb8\u0cbe\u0ca7\u0ca8\u0ca6 \u0cb8\u0ccd\u0ca5\u0cb3\u0cc0\u0caf \u0cb8\u0c82\u0c97\u0ccd\u0cb0\u0cb9\u0ca3\u0cc6\u0caf\u0cb2\u0ccd\u0cb2\u0cbf \u0cb8\u0c82\u0c97\u0ccd\u0cb0\u0cb9\u0cbf\u0cb8\u0cb2\u0cbe\u0c97\u0cc1\u0ca4\u0ccd\u0ca4\u0ca6\u0cc6.",
+ "success": {
+ "saved": "\u0caf\u0cb6\u0cb8\u0ccd\u0cb5\u0cbf\u0caf\u0cbe\u0c97\u0cbf \u0c89\u0cb3\u0cbf\u0cb8\u0cb2\u0cbe\u0c97\u0cbf\u0ca6\u0cc6"
+ }
+ },
+ "alerts": {
+ "info": "Info",
+ "note": "Note",
+ "tip": "Tip",
+ "important": "Important",
+ "warning": "Warning",
+ "caution": "Caution",
+ "debug": "Debug",
+ "example": "Example",
+ "success": "Success",
+ "help": "Help",
+ "idea": "Idea",
+ "pending": "Pending",
+ "security": "Security",
+ "beta": "Beta",
+ "best-practice": "Best Practice"
+ }
+}
\ No newline at end of file
diff --git a/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/ml.json b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/ml.json
new file mode 100644
index 0000000..69f9748
--- /dev/null
+++ b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/ml.json
@@ -0,0 +1,219 @@
+{
+ "common": {
+ "actions": {
+ "cancel": "\u0d31\u0d26\u0d4d\u0d26\u0d3e\u0d15\u0d4d\u0d15\u0d41\u0d15",
+ "confirm": "\u0d38\u0d4d\u0d25\u0d3f\u0d30\u0d40\u0d15\u0d30\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15",
+ "continue": "\u0d24\u0d41\u0d1f\u0d30\u0d41\u0d15",
+ "goBack": "\u0d24\u0d3f\u0d30\u0d3f\u0d15\u0d46 \u0d2a\u0d4b\u0d15\u0d41\u0d15",
+ "reset": "\u0d2a\u0d41\u0d28\u0d03\u0d38\u0d1c\u0d4d\u0d1c\u0d2e\u0d3e\u0d15\u0d4d\u0d15\u0d41\u0d15",
+ "submit": "\u0d38\u0d2e\u0d7c\u0d2a\u0d4d\u0d2a\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15"
+ },
+ "status": {
+ "loading": "\u0d32\u0d4b\u0d21\u0d4d \u0d1a\u0d46\u0d2f\u0d4d\u0d2f\u0d41\u0d28\u0d4d\u0d28\u0d41...",
+ "error": {
+ "default": "\u0d12\u0d30\u0d41 \u0d2a\u0d3f\u0d36\u0d15\u0d4d \u0d38\u0d02\u0d2d\u0d35\u0d3f\u0d1a\u0d4d\u0d1a\u0d41",
+ "serverConnection": "\u0d38\u0d46\u0d7c\u0d35\u0d31\u0d41\u0d2e\u0d3e\u0d2f\u0d3f \u0d2c\u0d28\u0d4d\u0d27\u0d2a\u0d4d\u0d2a\u0d46\u0d1f\u0d3e\u0d7b \u0d15\u0d34\u0d3f\u0d1e\u0d4d\u0d1e\u0d3f\u0d32\u0d4d\u0d32"
+ }
+ }
+ },
+ "auth": {
+ "login": {
+ "title": "\u0d06\u0d2a\u0d4d\u0d2a\u0d4d \u0d09\u0d2a\u0d2f\u0d4b\u0d17\u0d3f\u0d15\u0d4d\u0d15\u0d3e\u0d7b \u0d32\u0d4b\u0d17\u0d3f\u0d7b \u0d1a\u0d46\u0d2f\u0d4d\u0d2f\u0d41\u0d15",
+ "form": {
+ "email": {
+ "label": "\u0d07\u0d2e\u0d46\u0d2f\u0d3f\u0d7d \u0d35\u0d3f\u0d32\u0d3e\u0d38\u0d02",
+ "required": "\u0d07\u0d2e\u0d46\u0d2f\u0d3f\u0d7d \u0d12\u0d30\u0d41 \u0d06\u0d35\u0d36\u0d4d\u0d2f\u0d2e\u0d3e\u0d2f \u0d2b\u0d40\u0d7d\u0d21\u0d4d \u0d06\u0d23\u0d4d"
+ },
+ "password": {
+ "label": "\u0d2a\u0d3e\u0d38\u0d4d\u200c\u0d35\u0d47\u0d21\u0d4d",
+ "required": "\u0d2a\u0d3e\u0d38\u0d4d\u200c\u0d35\u0d47\u0d21\u0d4d \u0d12\u0d30\u0d41 \u0d06\u0d35\u0d36\u0d4d\u0d2f\u0d2e\u0d3e\u0d2f \u0d2b\u0d40\u0d7d\u0d21\u0d4d \u0d06\u0d23\u0d4d"
+ },
+ "actions": {
+ "signin": "\u0d38\u0d48\u0d7b \u0d07\u0d7b"
+ },
+ "alternativeText": {
+ "or": "\u0d05\u0d32\u0d4d\u0d32\u0d46\u0d19\u0d4d\u0d15\u0d3f\u0d7d"
+ }
+ },
+ "errors": {
+ "default": "\u0d38\u0d48\u0d7b \u0d07\u0d7b \u0d1a\u0d46\u0d2f\u0d4d\u0d2f\u0d3e\u0d7b \u0d15\u0d34\u0d3f\u0d2f\u0d41\u0d28\u0d4d\u0d28\u0d3f\u0d32\u0d4d\u0d32",
+ "signin": "\u0d2e\u0d31\u0d4d\u0d31\u0d4a\u0d30\u0d41 \u0d05\u0d15\u0d4d\u0d15\u0d57\u0d23\u0d4d\u0d1f\u0d4d \u0d09\u0d2a\u0d2f\u0d4b\u0d17\u0d3f\u0d1a\u0d4d\u0d1a\u0d4d \u0d38\u0d48\u0d7b \u0d07\u0d7b \u0d1a\u0d46\u0d2f\u0d4d\u0d2f\u0d3e\u0d7b \u0d36\u0d4d\u0d30\u0d2e\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15",
+ "oauthSignin": "\u0d2e\u0d31\u0d4d\u0d31\u0d4a\u0d30\u0d41 \u0d05\u0d15\u0d4d\u0d15\u0d57\u0d23\u0d4d\u0d1f\u0d4d \u0d09\u0d2a\u0d2f\u0d4b\u0d17\u0d3f\u0d1a\u0d4d\u0d1a\u0d4d \u0d38\u0d48\u0d7b \u0d07\u0d7b \u0d1a\u0d46\u0d2f\u0d4d\u0d2f\u0d3e\u0d7b \u0d36\u0d4d\u0d30\u0d2e\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15",
+ "redirectUriMismatch": "\u0d31\u0d40\u0d21\u0d2f\u0d31\u0d15\u0d4d\u0d1f\u0d4d URI oauth \u0d06\u0d2a\u0d4d\u0d2a\u0d4d \u0d15\u0d4b\u0d7a\u0d2b\u0d3f\u0d17\u0d31\u0d47\u0d37\u0d28\u0d41\u0d2e\u0d3e\u0d2f\u0d3f \u0d2a\u0d4a\u0d30\u0d41\u0d24\u0d4d\u0d24\u0d2a\u0d4d\u0d2a\u0d46\u0d1f\u0d41\u0d28\u0d4d\u0d28\u0d3f\u0d32\u0d4d\u0d32",
+ "oauthCallback": "\u0d2e\u0d31\u0d4d\u0d31\u0d4a\u0d30\u0d41 \u0d05\u0d15\u0d4d\u0d15\u0d57\u0d23\u0d4d\u0d1f\u0d4d \u0d09\u0d2a\u0d2f\u0d4b\u0d17\u0d3f\u0d1a\u0d4d\u0d1a\u0d4d \u0d38\u0d48\u0d7b \u0d07\u0d7b \u0d1a\u0d46\u0d2f\u0d4d\u0d2f\u0d3e\u0d7b \u0d36\u0d4d\u0d30\u0d2e\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15",
+ "oauthCreateAccount": "\u0d2e\u0d31\u0d4d\u0d31\u0d4a\u0d30\u0d41 \u0d05\u0d15\u0d4d\u0d15\u0d57\u0d23\u0d4d\u0d1f\u0d4d \u0d09\u0d2a\u0d2f\u0d4b\u0d17\u0d3f\u0d1a\u0d4d\u0d1a\u0d4d \u0d38\u0d48\u0d7b \u0d07\u0d7b \u0d1a\u0d46\u0d2f\u0d4d\u0d2f\u0d3e\u0d7b \u0d36\u0d4d\u0d30\u0d2e\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15",
+ "emailCreateAccount": "\u0d2e\u0d31\u0d4d\u0d31\u0d4a\u0d30\u0d41 \u0d05\u0d15\u0d4d\u0d15\u0d57\u0d23\u0d4d\u0d1f\u0d4d \u0d09\u0d2a\u0d2f\u0d4b\u0d17\u0d3f\u0d1a\u0d4d\u0d1a\u0d4d \u0d38\u0d48\u0d7b \u0d07\u0d7b \u0d1a\u0d46\u0d2f\u0d4d\u0d2f\u0d3e\u0d7b \u0d36\u0d4d\u0d30\u0d2e\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15",
+ "callback": "\u0d2e\u0d31\u0d4d\u0d31\u0d4a\u0d30\u0d41 \u0d05\u0d15\u0d4d\u0d15\u0d57\u0d23\u0d4d\u0d1f\u0d4d \u0d09\u0d2a\u0d2f\u0d4b\u0d17\u0d3f\u0d1a\u0d4d\u0d1a\u0d4d \u0d38\u0d48\u0d7b \u0d07\u0d7b \u0d1a\u0d46\u0d2f\u0d4d\u0d2f\u0d3e\u0d7b \u0d36\u0d4d\u0d30\u0d2e\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15",
+ "oauthAccountNotLinked": "\u0d28\u0d3f\u0d19\u0d4d\u0d19\u0d33\u0d41\u0d1f\u0d46 \u0d35\u0d4d\u0d2f\u0d15\u0d4d\u0d24\u0d3f\u0d24\u0d4d\u0d35\u0d02 \u0d38\u0d4d\u0d25\u0d3f\u0d30\u0d40\u0d15\u0d30\u0d3f\u0d15\u0d4d\u0d15\u0d3e\u0d7b, \u0d06\u0d26\u0d4d\u0d2f\u0d02 \u0d09\u0d2a\u0d2f\u0d4b\u0d17\u0d3f\u0d1a\u0d4d\u0d1a \u0d05\u0d24\u0d47 \u0d05\u0d15\u0d4d\u0d15\u0d57\u0d23\u0d4d\u0d1f\u0d4d \u0d09\u0d2a\u0d2f\u0d4b\u0d17\u0d3f\u0d1a\u0d4d\u0d1a\u0d4d \u0d38\u0d48\u0d7b \u0d07\u0d7b \u0d1a\u0d46\u0d2f\u0d4d\u0d2f\u0d41\u0d15",
+ "emailSignin": "\u0d07\u0d2e\u0d46\u0d2f\u0d3f\u0d7d \u0d05\u0d2f\u0d2f\u0d4d\u0d15\u0d4d\u0d15\u0d3e\u0d7b \u0d15\u0d34\u0d3f\u0d1e\u0d4d\u0d1e\u0d3f\u0d32\u0d4d\u0d32",
+ "emailVerify": "\u0d28\u0d3f\u0d19\u0d4d\u0d19\u0d33\u0d41\u0d1f\u0d46 \u0d07\u0d2e\u0d46\u0d2f\u0d3f\u0d7d \u0d2a\u0d30\u0d3f\u0d36\u0d4b\u0d27\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15, \u0d12\u0d30\u0d41 \u0d2a\u0d41\u0d24\u0d3f\u0d2f \u0d07\u0d2e\u0d46\u0d2f\u0d3f\u0d7d \u0d05\u0d2f\u0d1a\u0d4d\u0d1a\u0d3f\u0d1f\u0d4d\u0d1f\u0d41\u0d23\u0d4d\u0d1f\u0d4d",
+ "credentialsSignin": "\u0d38\u0d48\u0d7b \u0d07\u0d7b \u0d2a\u0d30\u0d3e\u0d1c\u0d2f\u0d2a\u0d4d\u0d2a\u0d46\u0d1f\u0d4d\u0d1f\u0d41. \u0d28\u0d3f\u0d19\u0d4d\u0d19\u0d7e \u0d28\u0d7d\u0d15\u0d3f\u0d2f \u0d35\u0d3f\u0d35\u0d30\u0d19\u0d4d\u0d19\u0d7e \u0d36\u0d30\u0d3f\u0d2f\u0d3e\u0d23\u0d46\u0d28\u0d4d\u0d28\u0d4d \u0d2a\u0d30\u0d3f\u0d36\u0d4b\u0d27\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15",
+ "sessionRequired": "\u0d08 \u0d2a\u0d47\u0d1c\u0d4d \u0d06\u0d15\u0d4d\u0d38\u0d38\u0d4d \u0d1a\u0d46\u0d2f\u0d4d\u0d2f\u0d3e\u0d7b \u0d26\u0d2f\u0d35\u0d3e\u0d2f\u0d3f \u0d38\u0d48\u0d7b \u0d07\u0d7b \u0d1a\u0d46\u0d2f\u0d4d\u0d2f\u0d41\u0d15"
+ }
+ },
+ "provider": {
+ "continue": "{{provider}} \u0d09\u0d2a\u0d2f\u0d4b\u0d17\u0d3f\u0d1a\u0d4d\u0d1a\u0d4d \u0d24\u0d41\u0d1f\u0d30\u0d41\u0d15"
+ }
+ },
+ "chat": {
+ "input": {
+ "placeholder": "\u0d28\u0d3f\u0d19\u0d4d\u0d19\u0d33\u0d41\u0d1f\u0d46 \u0d38\u0d28\u0d4d\u0d26\u0d47\u0d36\u0d02 \u0d07\u0d35\u0d3f\u0d1f\u0d46 \u0d1f\u0d48\u0d2a\u0d4d\u0d2a\u0d4d \u0d1a\u0d46\u0d2f\u0d4d\u0d2f\u0d41\u0d15...",
+ "actions": {
+ "send": "\u0d38\u0d28\u0d4d\u0d26\u0d47\u0d36\u0d02 \u0d05\u0d2f\u0d2f\u0d4d\u0d15\u0d4d\u0d15\u0d41\u0d15",
+ "stop": "\u0d1f\u0d3e\u0d38\u0d4d\u0d15\u0d4d \u0d28\u0d3f\u0d7c\u0d24\u0d4d\u0d24\u0d41\u0d15",
+ "attachFiles": "\u0d2b\u0d2f\u0d32\u0d41\u0d15\u0d7e \u0d05\u0d31\u0d4d\u0d31\u0d3e\u0d1a\u0d4d\u0d1a\u0d4d \u0d1a\u0d46\u0d2f\u0d4d\u0d2f\u0d41\u0d15"
+ }
+ },
+ "commands": {
+ "button": "\u0d09\u0d2a\u0d15\u0d30\u0d23\u0d19\u0d4d\u0d19\u0d7e",
+ "changeTool": "\u0d09\u0d2a\u0d15\u0d30\u0d23\u0d02 \u0d2e\u0d3e\u0d31\u0d4d\u0d31\u0d41\u0d15",
+ "availableTools": "\u0d32\u0d2d\u0d4d\u0d2f\u0d2e\u0d3e\u0d2f \u0d09\u0d2a\u0d15\u0d30\u0d23\u0d19\u0d4d\u0d19\u0d7e"
+ },
+ "speech": {
+ "start": "\u0d31\u0d46\u0d15\u0d4d\u0d15\u0d4b\u0d7c\u0d21\u0d3f\u0d02\u0d17\u0d4d \u0d06\u0d30\u0d02\u0d2d\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15",
+ "stop": "\u0d31\u0d46\u0d15\u0d4d\u0d15\u0d4b\u0d7c\u0d21\u0d3f\u0d02\u0d17\u0d4d \u0d28\u0d3f\u0d7c\u0d24\u0d4d\u0d24\u0d41\u0d15",
+ "connecting": "\u0d2c\u0d28\u0d4d\u0d27\u0d3f\u0d2a\u0d4d\u0d2a\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d28\u0d4d\u0d28\u0d41"
+ },
+ "fileUpload": {
+ "dragDrop": "\u0d2b\u0d2f\u0d32\u0d41\u0d15\u0d7e \u0d07\u0d35\u0d3f\u0d1f\u0d46 \u0d35\u0d32\u0d3f\u0d1a\u0d4d\u0d1a\u0d3f\u0d1f\u0d41\u0d15",
+ "browse": "\u0d2b\u0d2f\u0d32\u0d41\u0d15\u0d7e \u0d24\u0d3f\u0d30\u0d2f\u0d41\u0d15",
+ "sizeLimit": "\u0d2a\u0d30\u0d3f\u0d27\u0d3f:",
+ "errors": {
+ "failed": "\u0d05\u0d2a\u0d4d\u200c\u0d32\u0d4b\u0d21\u0d4d \u0d2a\u0d30\u0d3e\u0d1c\u0d2f\u0d2a\u0d4d\u0d2a\u0d46\u0d1f\u0d4d\u0d1f\u0d41",
+ "cancelled": "\u0d05\u0d2a\u0d4d\u200c\u0d32\u0d4b\u0d21\u0d4d \u0d31\u0d26\u0d4d\u0d26\u0d3e\u0d15\u0d4d\u0d15\u0d3f"
+ }
+ },
+ "messages": {
+ "status": {
+ "using": "\u0d09\u0d2a\u0d2f\u0d4b\u0d17\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d28\u0d4d\u0d28\u0d41",
+ "used": "\u0d09\u0d2a\u0d2f\u0d4b\u0d17\u0d3f\u0d1a\u0d4d\u0d1a\u0d41"
+ },
+ "actions": {
+ "copy": {
+ "button": "\u0d15\u0d4d\u0d32\u0d3f\u0d2a\u0d4d\u0d2a\u0d4d\u0d2c\u0d4b\u0d7c\u0d21\u0d3f\u0d32\u0d47\u0d15\u0d4d\u0d15\u0d4d \u0d2a\u0d15\u0d7c\u0d24\u0d4d\u0d24\u0d41\u0d15",
+ "success": "\u0d2a\u0d15\u0d7c\u0d24\u0d4d\u0d24\u0d3f!"
+ }
+ },
+ "feedback": {
+ "positive": "\u0d38\u0d39\u0d3e\u0d2f\u0d15\u0d30\u0d02",
+ "negative": "\u0d38\u0d39\u0d3e\u0d2f\u0d15\u0d30\u0d2e\u0d32\u0d4d\u0d32",
+ "edit": "\u0d2b\u0d40\u0d21\u0d4d\u0d2c\u0d3e\u0d15\u0d4d\u0d15\u0d4d \u0d0e\u0d21\u0d3f\u0d31\u0d4d\u0d31\u0d4d \u0d1a\u0d46\u0d2f\u0d4d\u0d2f\u0d41\u0d15",
+ "dialog": {
+ "title": "\u0d12\u0d30\u0d41 \u0d15\u0d2e\u0d28\u0d4d\u0d31\u0d4d \u0d1a\u0d47\u0d7c\u0d15\u0d4d\u0d15\u0d41\u0d15",
+ "submit": "\u0d2b\u0d40\u0d21\u0d4d\u0d2c\u0d3e\u0d15\u0d4d\u0d15\u0d4d \u0d38\u0d2e\u0d7c\u0d2a\u0d4d\u0d2a\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15"
+ },
+ "status": {
+ "updating": "\u0d05\u0d2a\u0d4d\u0d21\u0d47\u0d31\u0d4d\u0d31\u0d4d \u0d1a\u0d46\u0d2f\u0d4d\u0d2f\u0d41\u0d28\u0d4d\u0d28\u0d41",
+ "updated": "\u0d2b\u0d40\u0d21\u0d4d\u0d2c\u0d3e\u0d15\u0d4d\u0d15\u0d4d \u0d05\u0d2a\u0d4d\u0d21\u0d47\u0d31\u0d4d\u0d31\u0d4d \u0d1a\u0d46\u0d2f\u0d4d\u0d24\u0d41"
+ }
+ }
+ },
+ "history": {
+ "title": "\u0d05\u0d35\u0d38\u0d3e\u0d28 \u0d07\u0d7b\u0d2a\u0d41\u0d1f\u0d4d\u0d1f\u0d41\u0d15\u0d7e",
+ "empty": "\u0d12\u0d28\u0d4d\u0d28\u0d41\u0d2e\u0d3f\u0d32\u0d4d\u0d32...",
+ "show": "\u0d39\u0d3f\u0d38\u0d4d\u0d31\u0d4d\u0d31\u0d31\u0d3f \u0d15\u0d3e\u0d23\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15"
+ },
+ "settings": {
+ "title": "\u0d15\u0d4d\u0d30\u0d2e\u0d40\u0d15\u0d30\u0d23\u0d19\u0d4d\u0d19\u0d7e \u0d2a\u0d3e\u0d28\u0d7d"
+ },
+ "watermark": "LLM \u0d15\u0d7e\u0d15\u0d4d\u0d15\u0d4d \u0d24\u0d46\u0d31\u0d4d\u0d31\u0d41\u0d15\u0d7e \u0d35\u0d30\u0d41\u0d24\u0d4d\u0d24\u0d3e\u0d02. \u0d2a\u0d4d\u0d30\u0d27\u0d3e\u0d28\u0d2a\u0d4d\u0d2a\u0d46\u0d1f\u0d4d\u0d1f \u0d35\u0d3f\u0d35\u0d30\u0d19\u0d4d\u0d19\u0d7e \u0d2a\u0d30\u0d3f\u0d36\u0d4b\u0d27\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d28\u0d4d\u0d28\u0d24\u0d4d \u0d2a\u0d30\u0d3f\u0d17\u0d23\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15."
+ },
+ "threadHistory": {
+ "sidebar": {
+ "title": "\u0d2e\u0d41\u0d7b \u0d1a\u0d3e\u0d31\u0d4d\u0d31\u0d41\u0d15\u0d7e",
+ "filters": {
+ "search": "\u0d24\u0d3f\u0d30\u0d2f\u0d41\u0d15",
+ "placeholder": "Search conversations..."
+ },
+ "timeframes": {
+ "today": "\u0d07\u0d28\u0d4d\u0d28\u0d4d",
+ "yesterday": "\u0d07\u0d28\u0d4d\u0d28\u0d32\u0d46",
+ "previous7days": "\u0d15\u0d34\u0d3f\u0d1e\u0d4d\u0d1e 7 \u0d26\u0d3f\u0d35\u0d38\u0d02",
+ "previous30days": "\u0d15\u0d34\u0d3f\u0d1e\u0d4d\u0d1e 30 \u0d26\u0d3f\u0d35\u0d38\u0d02"
+ },
+ "empty": "\u0d24\u0d4d\u0d30\u0d46\u0d21\u0d41\u0d15\u0d7e \u0d15\u0d23\u0d4d\u0d1f\u0d46\u0d24\u0d4d\u0d24\u0d3f\u0d2f\u0d3f\u0d32\u0d4d\u0d32",
+ "actions": {
+ "close": "\u0d38\u0d48\u0d21\u0d4d\u0d2c\u0d3e\u0d7c \u0d05\u0d1f\u0d2f\u0d4d\u0d15\u0d4d\u0d15\u0d41\u0d15",
+ "open": "\u0d38\u0d48\u0d21\u0d4d\u0d2c\u0d3e\u0d7c \u0d24\u0d41\u0d31\u0d15\u0d4d\u0d15\u0d41\u0d15"
+ }
+ },
+ "thread": {
+ "untitled": "\u0d2a\u0d47\u0d30\u0d3f\u0d32\u0d4d\u0d32\u0d3e\u0d24\u0d4d\u0d24 \u0d38\u0d02\u0d2d\u0d3e\u0d37\u0d23\u0d02",
+ "menu": {
+ "rename": "Rename",
+ "delete": "Delete"
+ },
+ "actions": {
+ "delete": {
+ "title": "\u0d21\u0d3f\u0d32\u0d40\u0d31\u0d4d\u0d31\u0d4d \u0d38\u0d4d\u0d25\u0d3f\u0d30\u0d40\u0d15\u0d30\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15",
+ "description": "\u0d07\u0d24\u0d4d \u0d24\u0d4d\u0d30\u0d46\u0d21\u0d41\u0d02 \u0d05\u0d24\u0d3f\u0d28\u0d4d\u0d31\u0d46 \u0d38\u0d28\u0d4d\u0d26\u0d47\u0d36\u0d19\u0d4d\u0d19\u0d33\u0d41\u0d02 \u0d18\u0d1f\u0d15\u0d19\u0d4d\u0d19\u0d33\u0d41\u0d02 \u0d21\u0d3f\u0d32\u0d40\u0d31\u0d4d\u0d31\u0d4d \u0d1a\u0d46\u0d2f\u0d4d\u0d2f\u0d41\u0d02. \u0d08 \u0d2a\u0d4d\u0d30\u0d35\u0d7c\u0d24\u0d4d\u0d24\u0d3f \u0d2a\u0d34\u0d2f\u0d2a\u0d1f\u0d3f\u0d2f\u0d3e\u0d15\u0d4d\u0d15\u0d3e\u0d7b \u0d15\u0d34\u0d3f\u0d2f\u0d3f\u0d32\u0d4d\u0d32",
+ "success": "\u0d1a\u0d3e\u0d31\u0d4d\u0d31\u0d4d \u0d21\u0d3f\u0d32\u0d40\u0d31\u0d4d\u0d31\u0d4d \u0d1a\u0d46\u0d2f\u0d4d\u0d24\u0d41",
+ "inProgress": "\u0d1a\u0d3e\u0d31\u0d4d\u0d31\u0d4d \u0d21\u0d3f\u0d32\u0d40\u0d31\u0d4d\u0d31\u0d4d \u0d1a\u0d46\u0d2f\u0d4d\u0d2f\u0d41\u0d28\u0d4d\u0d28\u0d41"
+ },
+ "rename": {
+ "title": "\u0d24\u0d4d\u0d30\u0d46\u0d21\u0d4d \u0d2a\u0d41\u0d28\u0d7c\u0d28\u0d3e\u0d2e\u0d15\u0d30\u0d23\u0d02 \u0d1a\u0d46\u0d2f\u0d4d\u0d2f\u0d41\u0d15",
+ "description": "\u0d08 \u0d24\u0d4d\u0d30\u0d46\u0d21\u0d3f\u0d28\u0d4d \u0d12\u0d30\u0d41 \u0d2a\u0d41\u0d24\u0d3f\u0d2f \u0d2a\u0d47\u0d30\u0d4d \u0d28\u0d7d\u0d15\u0d41\u0d15",
+ "form": {
+ "name": {
+ "label": "\u0d2a\u0d47\u0d30\u0d4d",
+ "placeholder": "\u0d2a\u0d41\u0d24\u0d3f\u0d2f \u0d2a\u0d47\u0d30\u0d4d \u0d28\u0d7d\u0d15\u0d41\u0d15"
+ }
+ },
+ "success": "\u0d24\u0d4d\u0d30\u0d46\u0d21\u0d4d \u0d2a\u0d41\u0d28\u0d7c\u0d28\u0d3e\u0d2e\u0d15\u0d30\u0d23\u0d02 \u0d1a\u0d46\u0d2f\u0d4d\u0d24\u0d41!",
+ "inProgress": "\u0d24\u0d4d\u0d30\u0d46\u0d21\u0d4d \u0d2a\u0d41\u0d28\u0d7c\u0d28\u0d3e\u0d2e\u0d15\u0d30\u0d23\u0d02 \u0d1a\u0d46\u0d2f\u0d4d\u0d2f\u0d41\u0d28\u0d4d\u0d28\u0d41"
+ }
+ }
+ }
+ },
+ "navigation": {
+ "header": {
+ "chat": "\u0d1a\u0d3e\u0d31\u0d4d\u0d31\u0d4d",
+ "readme": "\u0d35\u0d3e\u0d2f\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15",
+ "theme": {
+ "light": "Light Theme",
+ "dark": "Dark Theme",
+ "system": "Follow System"
+ }
+ },
+ "newChat": {
+ "button": "\u0d2a\u0d41\u0d24\u0d3f\u0d2f \u0d1a\u0d3e\u0d31\u0d4d\u0d31\u0d4d",
+ "dialog": {
+ "title": "\u0d2a\u0d41\u0d24\u0d3f\u0d2f \u0d1a\u0d3e\u0d31\u0d4d\u0d31\u0d4d \u0d38\u0d43\u0d37\u0d4d\u0d1f\u0d3f\u0d15\u0d4d\u0d15\u0d41\u0d15",
+ "description": "\u0d07\u0d24\u0d4d \u0d28\u0d3f\u0d19\u0d4d\u0d19\u0d33\u0d41\u0d1f\u0d46 \u0d28\u0d3f\u0d32\u0d35\u0d3f\u0d32\u0d46 \u0d1a\u0d3e\u0d31\u0d4d\u0d31\u0d4d \u0d39\u0d3f\u0d38\u0d4d\u0d31\u0d4d\u0d31\u0d31\u0d3f \u0d2e\u0d3e\u0d2f\u0d4d\u0d15\u0d4d\u0d15\u0d41\u0d02. \u0d24\u0d41\u0d1f\u0d30\u0d3e\u0d7b \u0d24\u0d3e\u0d7d\u0d2a\u0d4d\u0d2a\u0d30\u0d4d\u0d2f\u0d2e\u0d41\u0d23\u0d4d\u0d1f\u0d4b?",
+ "tooltip": "\u0d2a\u0d41\u0d24\u0d3f\u0d2f \u0d1a\u0d3e\u0d31\u0d4d\u0d31\u0d4d"
+ }
+ },
+ "user": {
+ "menu": {
+ "settings": "\u0d15\u0d4d\u0d30\u0d2e\u0d40\u0d15\u0d30\u0d23\u0d19\u0d4d\u0d19\u0d7e",
+ "settingsKey": "S",
+ "apiKeys": "API \u0d15\u0d40\u0d15\u0d7e",
+ "logout": "\u0d32\u0d4b\u0d17\u0d4d\u0d14\u0d1f\u0d4d\u0d1f\u0d4d"
+ }
+ }
+ },
+ "apiKeys": {
+ "title": "\u0d06\u0d35\u0d36\u0d4d\u0d2f\u0d2e\u0d3e\u0d2f API \u0d15\u0d40\u0d15\u0d7e",
+ "description": "\u0d08 \u0d06\u0d2a\u0d4d\u0d2a\u0d4d \u0d09\u0d2a\u0d2f\u0d4b\u0d17\u0d3f\u0d15\u0d4d\u0d15\u0d3e\u0d7b, \u0d24\u0d3e\u0d34\u0d46\u0d2a\u0d4d\u0d2a\u0d31\u0d2f\u0d41\u0d28\u0d4d\u0d28 API \u0d15\u0d40\u0d15\u0d7e \u0d06\u0d35\u0d36\u0d4d\u0d2f\u0d2e\u0d3e\u0d23\u0d4d. \u0d15\u0d40\u0d15\u0d7e \u0d28\u0d3f\u0d19\u0d4d\u0d19\u0d33\u0d41\u0d1f\u0d46 \u0d09\u0d2a\u0d15\u0d30\u0d23\u0d24\u0d4d\u0d24\u0d3f\u0d28\u0d4d\u0d31\u0d46 \u0d32\u0d4b\u0d15\u0d4d\u0d15\u0d7d \u0d38\u0d4d\u0d31\u0d4d\u0d31\u0d4b\u0d31\u0d47\u0d1c\u0d3f\u0d7d \u0d38\u0d02\u0d2d\u0d30\u0d3f\u0d15\u0d4d\u0d15\u0d2a\u0d4d\u0d2a\u0d46\u0d1f\u0d41\u0d28\u0d4d\u0d28\u0d41.",
+ "success": {
+ "saved": "\u0d35\u0d3f\u0d1c\u0d2f\u0d15\u0d30\u0d2e\u0d3e\u0d2f\u0d3f \u0d38\u0d02\u0d30\u0d15\u0d4d\u0d37\u0d3f\u0d1a\u0d4d\u0d1a\u0d41"
+ }
+ },
+ "alerts": {
+ "info": "Info",
+ "note": "Note",
+ "tip": "Tip",
+ "important": "Important",
+ "warning": "Warning",
+ "caution": "Caution",
+ "debug": "Debug",
+ "example": "Example",
+ "success": "Success",
+ "help": "Help",
+ "idea": "Idea",
+ "pending": "Pending",
+ "security": "Security",
+ "beta": "Beta",
+ "best-practice": "Best Practice"
+ }
+}
\ No newline at end of file
diff --git a/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/mr.json b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/mr.json
new file mode 100644
index 0000000..6e9ff7b
--- /dev/null
+++ b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/mr.json
@@ -0,0 +1,219 @@
+{
+ "common": {
+ "actions": {
+ "cancel": "\u0930\u0926\u094d\u0926 \u0915\u0930\u093e",
+ "confirm": "\u092a\u0941\u0937\u094d\u091f\u0940 \u0915\u0930\u093e",
+ "continue": "\u092a\u0941\u0922\u0947 \u091c\u093e",
+ "goBack": "\u092e\u093e\u0917\u0947 \u091c\u093e",
+ "reset": "\u0930\u0940\u0938\u0947\u091f \u0915\u0930\u093e",
+ "submit": "\u0938\u092c\u092e\u093f\u091f \u0915\u0930\u093e"
+ },
+ "status": {
+ "loading": "\u0932\u094b\u0921 \u0915\u0930\u0924 \u0906\u0939\u0947...",
+ "error": {
+ "default": "\u090f\u0915 \u0924\u094d\u0930\u0941\u091f\u0940 \u0906\u0932\u0940",
+ "serverConnection": "\u0938\u0930\u094d\u0935\u094d\u0939\u0930\u0936\u0940 \u0915\u0928\u0947\u0915\u094d\u091f \u0939\u094b\u090a \u0936\u0915\u0932\u0947 \u0928\u093e\u0939\u0940"
+ }
+ }
+ },
+ "auth": {
+ "login": {
+ "title": "\u0905\u0945\u092a \u0935\u093e\u092a\u0930\u0923\u094d\u092f\u093e\u0938\u093e\u0920\u0940 \u0932\u0949\u0917\u093f\u0928 \u0915\u0930\u093e",
+ "form": {
+ "email": {
+ "label": "\u0908\u092e\u0947\u0932 \u092a\u0924\u094d\u0924\u093e",
+ "required": "\u0908\u092e\u0947\u0932 \u0906\u0935\u0936\u094d\u092f\u0915 \u0906\u0939\u0947"
+ },
+ "password": {
+ "label": "\u092a\u093e\u0938\u0935\u0930\u094d\u0921",
+ "required": "\u092a\u093e\u0938\u0935\u0930\u094d\u0921 \u0906\u0935\u0936\u094d\u092f\u0915 \u0906\u0939\u0947"
+ },
+ "actions": {
+ "signin": "\u0938\u093e\u0907\u0928 \u0907\u0928 \u0915\u0930\u093e"
+ },
+ "alternativeText": {
+ "or": "\u0915\u093f\u0902\u0935\u093e"
+ }
+ },
+ "errors": {
+ "default": "\u0938\u093e\u0907\u0928 \u0907\u0928 \u0915\u0930\u0942 \u0936\u0915\u0924 \u0928\u093e\u0939\u0940",
+ "signin": "\u0935\u0947\u0917\u0933\u094d\u092f\u093e \u0916\u093e\u0924\u094d\u092f\u093e\u0928\u0947 \u0938\u093e\u0907\u0928 \u0907\u0928 \u0915\u0930\u0923\u094d\u092f\u093e\u091a\u093e \u092a\u094d\u0930\u092f\u0924\u094d\u0928 \u0915\u0930\u093e",
+ "oauthSignin": "\u0935\u0947\u0917\u0933\u094d\u092f\u093e \u0916\u093e\u0924\u094d\u092f\u093e\u0928\u0947 \u0938\u093e\u0907\u0928 \u0907\u0928 \u0915\u0930\u0923\u094d\u092f\u093e\u091a\u093e \u092a\u094d\u0930\u092f\u0924\u094d\u0928 \u0915\u0930\u093e",
+ "redirectUriMismatch": "\u0930\u0940\u0921\u093e\u092f\u0930\u0947\u0915\u094d\u091f URI \u0913\u0925 \u0905\u0945\u092a \u0915\u0949\u0928\u094d\u092b\u093f\u0917\u0930\u0947\u0936\u0928\u0936\u0940 \u091c\u0941\u0933\u0924 \u0928\u093e\u0939\u0940",
+ "oauthCallback": "\u0935\u0947\u0917\u0933\u094d\u092f\u093e \u0916\u093e\u0924\u094d\u092f\u093e\u0928\u0947 \u0938\u093e\u0907\u0928 \u0907\u0928 \u0915\u0930\u0923\u094d\u092f\u093e\u091a\u093e \u092a\u094d\u0930\u092f\u0924\u094d\u0928 \u0915\u0930\u093e",
+ "oauthCreateAccount": "\u0935\u0947\u0917\u0933\u094d\u092f\u093e \u0916\u093e\u0924\u094d\u092f\u093e\u0928\u0947 \u0938\u093e\u0907\u0928 \u0907\u0928 \u0915\u0930\u0923\u094d\u092f\u093e\u091a\u093e \u092a\u094d\u0930\u092f\u0924\u094d\u0928 \u0915\u0930\u093e",
+ "emailCreateAccount": "\u0935\u0947\u0917\u0933\u094d\u092f\u093e \u0916\u093e\u0924\u094d\u092f\u093e\u0928\u0947 \u0938\u093e\u0907\u0928 \u0907\u0928 \u0915\u0930\u0923\u094d\u092f\u093e\u091a\u093e \u092a\u094d\u0930\u092f\u0924\u094d\u0928 \u0915\u0930\u093e",
+ "callback": "\u0935\u0947\u0917\u0933\u094d\u092f\u093e \u0916\u093e\u0924\u094d\u092f\u093e\u0928\u0947 \u0938\u093e\u0907\u0928 \u0907\u0928 \u0915\u0930\u0923\u094d\u092f\u093e\u091a\u093e \u092a\u094d\u0930\u092f\u0924\u094d\u0928 \u0915\u0930\u093e",
+ "oauthAccountNotLinked": "\u0924\u0941\u092e\u091a\u0940 \u0913\u0933\u0916 \u092a\u091f\u0935\u0923\u094d\u092f\u093e\u0938\u093e\u0920\u0940, \u092e\u0942\u0933 \u0935\u093e\u092a\u0930\u0932\u0947\u0932\u094d\u092f\u093e \u0916\u093e\u0924\u094d\u092f\u093e\u0928\u0947\u091a \u0938\u093e\u0907\u0928 \u0907\u0928 \u0915\u0930\u093e",
+ "emailSignin": "\u0908\u092e\u0947\u0932 \u092a\u093e\u0920\u0935\u0942 \u0936\u0915\u0932\u0947 \u0928\u093e\u0939\u0940",
+ "emailVerify": "\u0915\u0943\u092a\u092f\u093e \u0924\u0941\u092e\u091a\u093e \u0908\u092e\u0947\u0932 \u0924\u092a\u093e\u0938\u093e, \u0928\u0935\u0940\u0928 \u0908\u092e\u0947\u0932 \u092a\u093e\u0920\u0935\u0932\u093e \u0917\u0947\u0932\u093e \u0906\u0939\u0947",
+ "credentialsSignin": "\u0938\u093e\u0907\u0928 \u0907\u0928 \u0905\u092f\u0936\u0938\u094d\u0935\u0940. \u0924\u0941\u092e\u094d\u0939\u0940 \u0926\u093f\u0932\u0947\u0932\u0940 \u092e\u093e\u0939\u093f\u0924\u0940 \u092f\u094b\u0917\u094d\u092f \u0906\u0939\u0947 \u0915\u093e \u0924\u0947 \u0924\u092a\u093e\u0938\u093e",
+ "sessionRequired": "\u092f\u093e \u092a\u0943\u0937\u094d\u0920\u093e\u0935\u0930 \u092a\u094d\u0930\u0935\u0947\u0936 \u0915\u0930\u0923\u094d\u092f\u093e\u0938\u093e\u0920\u0940 \u0915\u0943\u092a\u092f\u093e \u0938\u093e\u0907\u0928 \u0907\u0928 \u0915\u0930\u093e"
+ }
+ },
+ "provider": {
+ "continue": "{{provider}} \u0938\u0939 \u092a\u0941\u0922\u0947 \u091c\u093e"
+ }
+ },
+ "chat": {
+ "input": {
+ "placeholder": "\u0924\u0941\u092e\u091a\u093e \u0938\u0902\u0926\u0947\u0936 \u092f\u0947\u0925\u0947 \u091f\u093e\u0907\u092a \u0915\u0930\u093e...",
+ "actions": {
+ "send": "\u0938\u0902\u0926\u0947\u0936 \u092a\u093e\u0920\u0935\u093e",
+ "stop": "\u0915\u093e\u0930\u094d\u092f \u0925\u093e\u0902\u092c\u0935\u093e",
+ "attachFiles": "\u092b\u093e\u0907\u0932\u094d\u0938 \u091c\u094b\u0921\u093e"
+ }
+ },
+ "speech": {
+ "start": "\u0930\u0947\u0915\u0949\u0930\u094d\u0921\u093f\u0902\u0917 \u0938\u0941\u0930\u0942 \u0915\u0930\u093e",
+ "stop": "\u0930\u0947\u0915\u0949\u0930\u094d\u0921\u093f\u0902\u0917 \u0925\u093e\u0902\u092c\u0935\u093e",
+ "connecting": "\u0915\u0928\u0947\u0915\u094d\u091f \u0915\u0930\u0924 \u0906\u0939\u0947"
+ },
+ "commands": {
+ "button": "\u0938\u093e\u0927\u0928\u0947",
+ "changeTool": "\u0938\u093e\u0927\u0928 \u092c\u0926\u0932\u093e",
+ "availableTools": "\u0909\u092a\u0932\u092c\u094d\u0927 \u0938\u093e\u0927\u0928\u0947"
+ },
+ "fileUpload": {
+ "dragDrop": "\u092b\u093e\u0907\u0932\u094d\u0938 \u092f\u0947\u0925\u0947 \u0921\u094d\u0930\u0945\u0917 \u0906\u0923\u093f \u0921\u094d\u0930\u0949\u092a \u0915\u0930\u093e",
+ "browse": "\u092b\u093e\u0907\u0932\u094d\u0938 \u092c\u094d\u0930\u093e\u0909\u091d \u0915\u0930\u093e",
+ "sizeLimit": "\u092e\u0930\u094d\u092f\u093e\u0926\u093e:",
+ "errors": {
+ "failed": "\u0905\u092a\u0932\u094b\u0921 \u0905\u092f\u0936\u0938\u094d\u0935\u0940",
+ "cancelled": "\u092f\u093e\u0902\u091a\u0947 \u0905\u092a\u0932\u094b\u0921 \u0930\u0926\u094d\u0926 \u0915\u0947\u0932\u0947"
+ }
+ },
+ "messages": {
+ "status": {
+ "using": "\u0935\u093e\u092a\u0930\u0924 \u0906\u0939\u0947",
+ "used": "\u0935\u093e\u092a\u0930\u0932\u0947"
+ },
+ "actions": {
+ "copy": {
+ "button": "\u0915\u094d\u0932\u093f\u092a\u092c\u094b\u0930\u094d\u0921\u0935\u0930 \u0915\u0949\u092a\u0940 \u0915\u0930\u093e",
+ "success": "\u0915\u0949\u092a\u0940 \u0915\u0947\u0932\u0947!"
+ }
+ },
+ "feedback": {
+ "positive": "\u0909\u092a\u092f\u0941\u0915\u094d\u0924",
+ "negative": "\u0909\u092a\u092f\u0941\u0915\u094d\u0924 \u0928\u093e\u0939\u0940",
+ "edit": "\u092b\u0940\u0921\u092c\u0945\u0915 \u0938\u0902\u092a\u093e\u0926\u093f\u0924 \u0915\u0930\u093e",
+ "dialog": {
+ "title": "\u091f\u093f\u092a\u094d\u092a\u0923\u0940 \u091c\u094b\u0921\u093e",
+ "submit": "\u092b\u0940\u0921\u092c\u0945\u0915 \u0938\u092c\u092e\u093f\u091f \u0915\u0930\u093e"
+ },
+ "status": {
+ "updating": "\u0905\u092a\u0921\u0947\u091f \u0915\u0930\u0924 \u0906\u0939\u0947",
+ "updated": "\u092b\u0940\u0921\u092c\u0945\u0915 \u0905\u092a\u0921\u0947\u091f \u0915\u0947\u0932\u0947"
+ }
+ }
+ },
+ "history": {
+ "title": "\u0936\u0947\u0935\u091f\u091a\u0947 \u0907\u0928\u092a\u0941\u091f",
+ "empty": "\u0930\u093f\u0915\u093e\u092e\u0947 \u0906\u0939\u0947...",
+ "show": "\u0907\u0924\u093f\u0939\u093e\u0938 \u0926\u093e\u0916\u0935\u093e"
+ },
+ "settings": {
+ "title": "\u0938\u0947\u091f\u093f\u0902\u0917\u094d\u091c \u092a\u0945\u0928\u0932"
+ },
+ "watermark": "LLM \u091a\u0941\u0915\u093e \u0915\u0930\u0942 \u0936\u0915\u0924\u093e\u0924. \u092e\u0939\u0924\u094d\u0924\u094d\u0935\u093e\u091a\u0940 \u092e\u093e\u0939\u093f\u0924\u0940 \u0924\u092a\u093e\u0938\u0923\u094d\u092f\u093e\u091a\u093e \u0935\u093f\u091a\u093e\u0930 \u0915\u0930\u093e."
+ },
+ "threadHistory": {
+ "sidebar": {
+ "title": "\u092e\u093e\u0917\u0940\u0932 \u091a\u0945\u091f\u094d\u0938",
+ "filters": {
+ "search": "\u0936\u094b\u0927\u093e",
+ "placeholder": "Search conversations..."
+ },
+ "timeframes": {
+ "today": "\u0906\u091c",
+ "yesterday": "\u0915\u093e\u0932",
+ "previous7days": "\u092e\u093e\u0917\u0940\u0932 7 \u0926\u093f\u0935\u0938",
+ "previous30days": "\u092e\u093e\u0917\u0940\u0932 30 \u0926\u093f\u0935\u0938"
+ },
+ "empty": "\u0915\u094b\u0923\u0924\u0947\u0939\u0940 \u0925\u094d\u0930\u0947\u0921 \u0938\u093e\u092a\u0921\u0932\u0947 \u0928\u093e\u0939\u0940\u0924",
+ "actions": {
+ "close": "\u0938\u093e\u0907\u0921\u092c\u093e\u0930 \u092c\u0902\u0926 \u0915\u0930\u093e",
+ "open": "\u0938\u093e\u0907\u0921\u092c\u093e\u0930 \u0909\u0918\u0921\u093e"
+ }
+ },
+ "thread": {
+ "untitled": "\u0936\u0940\u0930\u094d\u0937\u0915\u0935\u093f\u0930\u0939\u093f\u0924 \u0938\u0902\u092d\u093e\u0937\u0923",
+ "menu": {
+ "rename": "Rename",
+ "delete": "Delete"
+ },
+ "actions": {
+ "delete": {
+ "title": "\u0939\u091f\u0935\u093f\u0923\u094d\u092f\u093e\u091a\u0940 \u092a\u0941\u0937\u094d\u091f\u0940 \u0915\u0930\u093e",
+ "description": "\u0939\u0947 \u0925\u094d\u0930\u0947\u0921 \u0906\u0923\u093f \u0924\u094d\u092f\u093e\u091a\u0947 \u0938\u0902\u0926\u0947\u0936 \u0935 \u0918\u091f\u0915 \u0939\u091f\u0935\u0947\u0932. \u0939\u0940 \u0915\u094d\u0930\u093f\u092f\u093e \u092a\u0942\u0930\u094d\u0935\u0935\u0924 \u0915\u0947\u0932\u0940 \u091c\u093e\u090a \u0936\u0915\u0924 \u0928\u093e\u0939\u0940",
+ "success": "\u091a\u0945\u091f \u0939\u091f\u0935\u0932\u093e",
+ "inProgress": "\u091a\u0945\u091f \u0939\u091f\u0935\u0924 \u0906\u0939\u0947"
+ },
+ "rename": {
+ "title": "\u0925\u094d\u0930\u0947\u0921\u091a\u0947 \u0928\u093e\u0935 \u092c\u0926\u0932\u093e",
+ "description": "\u092f\u093e \u0925\u094d\u0930\u0947\u0921\u0938\u093e\u0920\u0940 \u0928\u0935\u0940\u0928 \u0928\u093e\u0935 \u092a\u094d\u0930\u0935\u093f\u0937\u094d\u091f \u0915\u0930\u093e",
+ "form": {
+ "name": {
+ "label": "\u0928\u093e\u0935",
+ "placeholder": "\u0928\u0935\u0940\u0928 \u0928\u093e\u0935 \u092a\u094d\u0930\u0935\u093f\u0937\u094d\u091f \u0915\u0930\u093e"
+ }
+ },
+ "success": "\u0925\u094d\u0930\u0947\u0921\u091a\u0947 \u0928\u093e\u0935 \u092c\u0926\u0932\u0932\u0947!",
+ "inProgress": "\u0925\u094d\u0930\u0947\u0921\u091a\u0947 \u0928\u093e\u0935 \u092c\u0926\u0932\u0924 \u0906\u0939\u0947"
+ }
+ }
+ }
+ },
+ "navigation": {
+ "header": {
+ "chat": "\u091a\u0945\u091f",
+ "readme": "\u0935\u093e\u091a\u093e",
+ "theme": {
+ "light": "Light Theme",
+ "dark": "Dark Theme",
+ "system": "Follow System"
+ }
+ },
+ "newChat": {
+ "button": "\u0928\u0935\u0940\u0928 \u091a\u0945\u091f",
+ "dialog": {
+ "title": "\u0928\u0935\u0940\u0928 \u091a\u0945\u091f \u0924\u092f\u093e\u0930 \u0915\u0930\u093e",
+ "description": "\u0939\u0947 \u0924\u0941\u092e\u091a\u093e \u0938\u0927\u094d\u092f\u093e\u091a\u093e \u091a\u0945\u091f \u0907\u0924\u093f\u0939\u093e\u0938 \u0938\u093e\u092b \u0915\u0930\u0947\u0932. \u0924\u0941\u092e\u094d\u0939\u093e\u0932\u093e \u0916\u093e\u0924\u094d\u0930\u0940 \u0906\u0939\u0947 \u0915\u0940 \u0924\u0941\u092e\u094d\u0939\u0940 \u092a\u0941\u0922\u0947 \u091c\u093e\u090a \u0907\u091a\u094d\u091b\u093f\u0924\u093e?",
+ "tooltip": "\u0928\u0935\u0940\u0928 \u091a\u0945\u091f"
+ }
+ },
+ "user": {
+ "menu": {
+ "settings": "\u0938\u0947\u091f\u093f\u0902\u0917\u094d\u091c",
+ "settingsKey": "S",
+ "apiKeys": "API \u0915\u0940\u091c",
+ "logout": "\u0932\u0949\u0917\u0906\u0909\u091f"
+ }
+ }
+ },
+ "apiKeys": {
+ "title": "\u0906\u0935\u0936\u094d\u092f\u0915 API \u0915\u0940\u091c",
+ "description": "\u0939\u0947 \u0905\u0945\u092a \u0935\u093e\u092a\u0930\u0923\u094d\u092f\u093e\u0938\u093e\u0920\u0940 \u0916\u093e\u0932\u0940\u0932 API \u0915\u0940\u091c \u0906\u0935\u0936\u094d\u092f\u0915 \u0906\u0939\u0947\u0924. \u0915\u0940\u091c \u0924\u0941\u092e\u091a\u094d\u092f\u093e \u0921\u093f\u0935\u094d\u0939\u093e\u0907\u0938\u091a\u094d\u092f\u093e \u0932\u094b\u0915\u0932 \u0938\u094d\u091f\u094b\u0930\u0947\u091c\u092e\u0927\u094d\u092f\u0947 \u0938\u093e\u0920\u0935\u0932\u094d\u092f\u093e \u091c\u093e\u0924\u093e\u0924.",
+ "success": {
+ "saved": "\u092f\u0936\u0938\u094d\u0935\u0940\u0930\u093f\u0924\u094d\u092f\u093e \u091c\u0924\u0928 \u0915\u0947\u0932\u0947"
+ }
+ },
+ "alerts": {
+ "info": "Info",
+ "note": "Note",
+ "tip": "Tip",
+ "important": "Important",
+ "warning": "Warning",
+ "caution": "Caution",
+ "debug": "Debug",
+ "example": "Example",
+ "success": "Success",
+ "help": "Help",
+ "idea": "Idea",
+ "pending": "Pending",
+ "security": "Security",
+ "beta": "Beta",
+ "best-practice": "Best Practice"
+ }
+}
\ No newline at end of file
diff --git a/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/nl.json b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/nl.json
new file mode 100644
index 0000000..49d6e99
--- /dev/null
+++ b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/nl.json
@@ -0,0 +1,219 @@
+{
+ "common": {
+ "actions": {
+ "cancel": "Annuleren",
+ "confirm": "Bevestigen",
+ "continue": "Doorgaan",
+ "goBack": "Terug",
+ "reset": "Herstellen",
+ "submit": "Versturen"
+ },
+ "status": {
+ "loading": "Laden...",
+ "error": {
+ "default": "Er is een fout opgetreden",
+ "serverConnection": "Kon geen verbinding maken met de server"
+ }
+ }
+ },
+ "auth": {
+ "login": {
+ "title": "Inloggen om toegang te krijgen tot de app",
+ "form": {
+ "email": {
+ "label": "E-mailadres",
+ "required": "e-mail is een verplicht veld"
+ },
+ "password": {
+ "label": "Wachtwoord",
+ "required": "wachtwoord is een verplicht veld"
+ },
+ "actions": {
+ "signin": "Inloggen"
+ },
+ "alternativeText": {
+ "or": "OF"
+ }
+ },
+ "errors": {
+ "default": "Kan niet inloggen",
+ "signin": "Probeer in te loggen met een ander account",
+ "oauthSignin": "Probeer in te loggen met een ander account",
+ "redirectUriMismatch": "De redirect URI komt niet overeen met de oauth app configuratie",
+ "oauthCallback": "Probeer in te loggen met een ander account",
+ "oauthCreateAccount": "Probeer in te loggen met een ander account",
+ "emailCreateAccount": "Probeer in te loggen met een ander account",
+ "callback": "Probeer in te loggen met een ander account",
+ "oauthAccountNotLinked": "Om je identiteit te bevestigen, log in met hetzelfde account dat je oorspronkelijk hebt gebruikt",
+ "emailSignin": "De e-mail kon niet worden verzonden",
+ "emailVerify": "Verifieer je e-mail, er is een nieuwe e-mail verzonden",
+ "credentialsSignin": "Inloggen mislukt. Controleer of de ingevoerde gegevens correct zijn",
+ "sessionRequired": "Log in om toegang te krijgen tot deze pagina"
+ }
+ },
+ "provider": {
+ "continue": "Doorgaan met {{provider}}"
+ }
+ },
+ "chat": {
+ "input": {
+ "placeholder": "Typ hier je bericht...",
+ "actions": {
+ "send": "Bericht versturen",
+ "stop": "Taak stoppen",
+ "attachFiles": "Bestanden bijvoegen"
+ }
+ },
+ "speech": {
+ "start": "Start opname",
+ "stop": "Stop opname",
+ "connecting": "Verbinden"
+ },
+ "fileUpload": {
+ "dragDrop": "Sleep bestanden hierheen",
+ "browse": "Bestanden zoeken",
+ "sizeLimit": "Limiet:",
+ "errors": {
+ "failed": "Uploaden mislukt",
+ "cancelled": "Upload geannuleerd van"
+ }
+ },
+ "commands": {
+ "button": "Hulpmiddelen",
+ "changeTool": "Wijzig hulpmiddel",
+ "availableTools": "Beschikbare hulpmiddelen"
+ },
+ "messages": {
+ "status": {
+ "using": "In gebruik",
+ "used": "Gebruikt"
+ },
+ "actions": {
+ "copy": {
+ "button": "Kopi\u00ebren naar klembord",
+ "success": "Gekopieerd!"
+ }
+ },
+ "feedback": {
+ "positive": "Nuttig",
+ "negative": "Niet nuttig",
+ "edit": "Feedback bewerken",
+ "dialog": {
+ "title": "Voeg een opmerking toe",
+ "submit": "Feedback versturen"
+ },
+ "status": {
+ "updating": "Bijwerken",
+ "updated": "Feedback bijgewerkt"
+ }
+ }
+ },
+ "history": {
+ "title": "Laatste invoer",
+ "empty": "Zo leeg...",
+ "show": "Toon geschiedenis"
+ },
+ "settings": {
+ "title": "Instellingenpaneel"
+ },
+ "watermark": "LLM's kunnen fouten maken. Overweeg het controleren van belangrijke informatie."
+ },
+ "threadHistory": {
+ "sidebar": {
+ "title": "Eerdere chats",
+ "filters": {
+ "search": "Zoeken",
+ "placeholder": "Search conversations..."
+ },
+ "timeframes": {
+ "today": "Vandaag",
+ "yesterday": "Gisteren",
+ "previous7days": "Afgelopen 7 dagen",
+ "previous30days": "Afgelopen 30 dagen"
+ },
+ "empty": "Geen gesprekken gevonden",
+ "actions": {
+ "close": "Zijbalk sluiten",
+ "open": "Zijbalk openen"
+ }
+ },
+ "thread": {
+ "untitled": "Naamloos gesprek",
+ "menu": {
+ "rename": "Rename",
+ "delete": "Delete"
+ },
+ "actions": {
+ "delete": {
+ "title": "Verwijdering bevestigen",
+ "description": "Dit zal het gesprek en bijbehorende berichten en elementen verwijderen. Deze actie kan niet ongedaan worden gemaakt",
+ "success": "Chat verwijderd",
+ "inProgress": "Chat verwijderen"
+ },
+ "rename": {
+ "title": "Gesprek hernoemen",
+ "description": "Voer een nieuwe naam in voor dit gesprek",
+ "form": {
+ "name": {
+ "label": "Naam",
+ "placeholder": "Voer nieuwe naam in"
+ }
+ },
+ "success": "Gesprek hernoemd!",
+ "inProgress": "Gesprek hernoemen"
+ }
+ }
+ }
+ },
+ "navigation": {
+ "header": {
+ "chat": "Chat",
+ "readme": "Leesmij",
+ "theme": {
+ "light": "Light Theme",
+ "dark": "Dark Theme",
+ "system": "Follow System"
+ }
+ },
+ "newChat": {
+ "button": "Nieuwe chat",
+ "dialog": {
+ "title": "Nieuwe chat aanmaken",
+ "description": "Dit zal je huidige chatgeschiedenis wissen. Weet je zeker dat je door wilt gaan?",
+ "tooltip": "Nieuwe chat"
+ }
+ },
+ "user": {
+ "menu": {
+ "settings": "Instellingen",
+ "settingsKey": "I",
+ "apiKeys": "API-sleutels",
+ "logout": "Uitloggen"
+ }
+ }
+ },
+ "apiKeys": {
+ "title": "Vereiste API-sleutels",
+ "description": "Om deze app te gebruiken zijn de volgende API-sleutels vereist. De sleutels worden opgeslagen in de lokale opslag van je apparaat.",
+ "success": {
+ "saved": "Succesvol opgeslagen"
+ }
+ },
+ "alerts": {
+ "info": "Info",
+ "note": "Note",
+ "tip": "Tip",
+ "important": "Important",
+ "warning": "Warning",
+ "caution": "Caution",
+ "debug": "Debug",
+ "example": "Example",
+ "success": "Success",
+ "help": "Help",
+ "idea": "Idea",
+ "pending": "Pending",
+ "security": "Security",
+ "beta": "Beta",
+ "best-practice": "Best Practice"
+ }
+}
\ No newline at end of file
diff --git a/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/ta.json b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/ta.json
new file mode 100644
index 0000000..7fb9070
--- /dev/null
+++ b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/ta.json
@@ -0,0 +1,219 @@
+{
+ "common": {
+ "actions": {
+ "cancel": "\u0bb0\u0ba4\u0bcd\u0ba4\u0bc1 \u0b9a\u0bc6\u0baf\u0bcd",
+ "confirm": "\u0b89\u0bb1\u0bc1\u0ba4\u0bbf\u0baa\u0bcd\u0baa\u0b9f\u0bc1\u0ba4\u0bcd\u0ba4\u0bc1",
+ "continue": "\u0ba4\u0bca\u0b9f\u0bb0\u0bcd\u0b95",
+ "goBack": "\u0ba4\u0bbf\u0bb0\u0bc1\u0bae\u0bcd\u0baa\u0bbf\u0b9a\u0bcd \u0b9a\u0bc6\u0bb2\u0bcd",
+ "reset": "\u0bae\u0bc0\u0b9f\u0bcd\u0b9f\u0bae\u0bc8",
+ "submit": "\u0b9a\u0bae\u0bb0\u0bcd\u0baa\u0bcd\u0baa\u0bbf"
+ },
+ "status": {
+ "loading": "\u0b8f\u0bb1\u0bcd\u0bb1\u0bc1\u0b95\u0bbf\u0bb1\u0ba4\u0bc1...",
+ "error": {
+ "default": "\u0baa\u0bbf\u0bb4\u0bc8 \u0b8f\u0bb1\u0bcd\u0baa\u0b9f\u0bcd\u0b9f\u0ba4\u0bc1",
+ "serverConnection": "\u0b9a\u0bc7\u0bb5\u0bc8\u0baf\u0b95\u0ba4\u0bcd\u0ba4\u0bc8 \u0b85\u0b9f\u0bc8\u0baf \u0bae\u0bc1\u0b9f\u0bbf\u0baf\u0bb5\u0bbf\u0bb2\u0bcd\u0bb2\u0bc8"
+ }
+ }
+ },
+ "auth": {
+ "login": {
+ "title": "\u0baa\u0baf\u0ba9\u0bcd\u0baa\u0bbe\u0b9f\u0bcd\u0b9f\u0bc8 \u0b85\u0ba3\u0bc1\u0b95 \u0b89\u0bb3\u0bcd\u0ba8\u0bc1\u0bb4\u0bc8\u0baf\u0bb5\u0bc1\u0bae\u0bcd",
+ "form": {
+ "email": {
+ "label": "\u0bae\u0bbf\u0ba9\u0bcd\u0ba9\u0b9e\u0bcd\u0b9a\u0bb2\u0bcd \u0bae\u0bc1\u0b95\u0bb5\u0bb0\u0bbf",
+ "required": "\u0bae\u0bbf\u0ba9\u0bcd\u0ba9\u0b9e\u0bcd\u0b9a\u0bb2\u0bcd \u0ba4\u0bc7\u0bb5\u0bc8\u0baf\u0bbe\u0ba9 \u0baa\u0bc1\u0bb2\u0bae\u0bcd"
+ },
+ "password": {
+ "label": "\u0b95\u0b9f\u0bb5\u0bc1\u0b9a\u0bcd\u0b9a\u0bca\u0bb2\u0bcd",
+ "required": "\u0b95\u0b9f\u0bb5\u0bc1\u0b9a\u0bcd\u0b9a\u0bca\u0bb2\u0bcd \u0ba4\u0bc7\u0bb5\u0bc8\u0baf\u0bbe\u0ba9 \u0baa\u0bc1\u0bb2\u0bae\u0bcd"
+ },
+ "actions": {
+ "signin": "\u0b89\u0bb3\u0bcd\u0ba8\u0bc1\u0bb4\u0bc8\u0b95"
+ },
+ "alternativeText": {
+ "or": "\u0b85\u0bb2\u0bcd\u0bb2\u0ba4\u0bc1"
+ }
+ },
+ "errors": {
+ "default": "\u0b89\u0bb3\u0bcd\u0ba8\u0bc1\u0bb4\u0bc8\u0baf \u0bae\u0bc1\u0b9f\u0bbf\u0baf\u0bb5\u0bbf\u0bb2\u0bcd\u0bb2\u0bc8",
+ "signin": "\u0bb5\u0bc7\u0bb1\u0bc1 \u0b95\u0ba3\u0b95\u0bcd\u0b95\u0bc1\u0b9f\u0ba9\u0bcd \u0b89\u0bb3\u0bcd\u0ba8\u0bc1\u0bb4\u0bc8\u0baf \u0bae\u0bc1\u0baf\u0bb1\u0bcd\u0b9a\u0bbf\u0b95\u0bcd\u0b95\u0bb5\u0bc1\u0bae\u0bcd",
+ "oauthSignin": "\u0bb5\u0bc7\u0bb1\u0bc1 \u0b95\u0ba3\u0b95\u0bcd\u0b95\u0bc1\u0b9f\u0ba9\u0bcd \u0b89\u0bb3\u0bcd\u0ba8\u0bc1\u0bb4\u0bc8\u0baf \u0bae\u0bc1\u0baf\u0bb1\u0bcd\u0b9a\u0bbf\u0b95\u0bcd\u0b95\u0bb5\u0bc1\u0bae\u0bcd",
+ "redirectUriMismatch": "\u0ba4\u0bbf\u0b9a\u0bc8\u0ba4\u0bbf\u0bb0\u0bc1\u0baa\u0bcd\u0baa\u0bb2\u0bcd URI \u0b93\u0b86\u0ba4\u0bcd \u0baa\u0baf\u0ba9\u0bcd\u0baa\u0bbe\u0b9f\u0bcd\u0b9f\u0bc1 \u0b95\u0b9f\u0bcd\u0b9f\u0bae\u0bc8\u0baa\u0bcd\u0baa\u0bc1\u0b9f\u0ba9\u0bcd \u0baa\u0bca\u0bb0\u0bc1\u0ba8\u0bcd\u0ba4\u0bb5\u0bbf\u0bb2\u0bcd\u0bb2\u0bc8",
+ "oauthCallback": "\u0bb5\u0bc7\u0bb1\u0bc1 \u0b95\u0ba3\u0b95\u0bcd\u0b95\u0bc1\u0b9f\u0ba9\u0bcd \u0b89\u0bb3\u0bcd\u0ba8\u0bc1\u0bb4\u0bc8\u0baf \u0bae\u0bc1\u0baf\u0bb1\u0bcd\u0b9a\u0bbf\u0b95\u0bcd\u0b95\u0bb5\u0bc1\u0bae\u0bcd",
+ "oauthCreateAccount": "\u0bb5\u0bc7\u0bb1\u0bc1 \u0b95\u0ba3\u0b95\u0bcd\u0b95\u0bc1\u0b9f\u0ba9\u0bcd \u0b89\u0bb3\u0bcd\u0ba8\u0bc1\u0bb4\u0bc8\u0baf \u0bae\u0bc1\u0baf\u0bb1\u0bcd\u0b9a\u0bbf\u0b95\u0bcd\u0b95\u0bb5\u0bc1\u0bae\u0bcd",
+ "emailCreateAccount": "\u0bb5\u0bc7\u0bb1\u0bc1 \u0b95\u0ba3\u0b95\u0bcd\u0b95\u0bc1\u0b9f\u0ba9\u0bcd \u0b89\u0bb3\u0bcd\u0ba8\u0bc1\u0bb4\u0bc8\u0baf \u0bae\u0bc1\u0baf\u0bb1\u0bcd\u0b9a\u0bbf\u0b95\u0bcd\u0b95\u0bb5\u0bc1\u0bae\u0bcd",
+ "callback": "\u0bb5\u0bc7\u0bb1\u0bc1 \u0b95\u0ba3\u0b95\u0bcd\u0b95\u0bc1\u0b9f\u0ba9\u0bcd \u0b89\u0bb3\u0bcd\u0ba8\u0bc1\u0bb4\u0bc8\u0baf \u0bae\u0bc1\u0baf\u0bb1\u0bcd\u0b9a\u0bbf\u0b95\u0bcd\u0b95\u0bb5\u0bc1\u0bae\u0bcd",
+ "oauthAccountNotLinked": "\u0b89\u0b99\u0bcd\u0b95\u0bb3\u0bcd \u0b85\u0b9f\u0bc8\u0baf\u0bbe\u0bb3\u0ba4\u0bcd\u0ba4\u0bc8 \u0b89\u0bb1\u0bc1\u0ba4\u0bbf\u0baa\u0bcd\u0baa\u0b9f\u0bc1\u0ba4\u0bcd\u0ba4, \u0bae\u0bc1\u0ba4\u0bb2\u0bbf\u0bb2\u0bcd \u0baa\u0baf\u0ba9\u0bcd\u0baa\u0b9f\u0bc1\u0ba4\u0bcd\u0ba4\u0bbf\u0baf \u0b85\u0ba4\u0bc7 \u0b95\u0ba3\u0b95\u0bcd\u0b95\u0bc1\u0b9f\u0ba9\u0bcd \u0b89\u0bb3\u0bcd\u0ba8\u0bc1\u0bb4\u0bc8\u0baf\u0bb5\u0bc1\u0bae\u0bcd",
+ "emailSignin": "\u0bae\u0bbf\u0ba9\u0bcd\u0ba9\u0b9e\u0bcd\u0b9a\u0bb2\u0bc8 \u0b85\u0ba9\u0bc1\u0baa\u0bcd\u0baa \u0bae\u0bc1\u0b9f\u0bbf\u0baf\u0bb5\u0bbf\u0bb2\u0bcd\u0bb2\u0bc8",
+ "emailVerify": "\u0b89\u0b99\u0bcd\u0b95\u0bb3\u0bcd \u0bae\u0bbf\u0ba9\u0bcd\u0ba9\u0b9e\u0bcd\u0b9a\u0bb2\u0bc8 \u0b9a\u0bb0\u0bbf\u0baa\u0bbe\u0bb0\u0bcd\u0b95\u0bcd\u0b95\u0bb5\u0bc1\u0bae\u0bcd, \u0baa\u0bc1\u0ba4\u0bbf\u0baf \u0bae\u0bbf\u0ba9\u0bcd\u0ba9\u0b9e\u0bcd\u0b9a\u0bb2\u0bcd \u0b85\u0ba9\u0bc1\u0baa\u0bcd\u0baa\u0baa\u0bcd\u0baa\u0b9f\u0bcd\u0b9f\u0bc1\u0bb3\u0bcd\u0bb3\u0ba4\u0bc1",
+ "credentialsSignin": "\u0b89\u0bb3\u0bcd\u0ba8\u0bc1\u0bb4\u0bc8\u0bb5\u0bc1 \u0ba4\u0bcb\u0bb2\u0bcd\u0bb5\u0bbf\u0baf\u0b9f\u0bc8\u0ba8\u0bcd\u0ba4\u0ba4\u0bc1. \u0ba8\u0bc0\u0b99\u0bcd\u0b95\u0bb3\u0bcd \u0bb5\u0bb4\u0b99\u0bcd\u0b95\u0bbf\u0baf \u0bb5\u0bbf\u0bb5\u0bb0\u0b99\u0bcd\u0b95\u0bb3\u0bcd \u0b9a\u0bb0\u0bbf\u0baf\u0bbe\u0ba9\u0bb5\u0bc8 \u0b8e\u0ba9 \u0b9a\u0bb0\u0bbf\u0baa\u0bbe\u0bb0\u0bcd\u0b95\u0bcd\u0b95\u0bb5\u0bc1\u0bae\u0bcd",
+ "sessionRequired": "\u0b87\u0ba8\u0bcd\u0ba4\u0baa\u0bcd \u0baa\u0b95\u0bcd\u0b95\u0ba4\u0bcd\u0ba4\u0bc8 \u0b85\u0ba3\u0bc1\u0b95 \u0b89\u0bb3\u0bcd\u0ba8\u0bc1\u0bb4\u0bc8\u0baf\u0bb5\u0bc1\u0bae\u0bcd"
+ }
+ },
+ "provider": {
+ "continue": "{{provider}} \u0bae\u0bc2\u0bb2\u0bae\u0bcd \u0ba4\u0bca\u0b9f\u0bb0\u0bb5\u0bc1\u0bae\u0bcd"
+ }
+ },
+ "chat": {
+ "input": {
+ "placeholder": "\u0b89\u0b99\u0bcd\u0b95\u0bb3\u0bcd \u0b9a\u0bc6\u0baf\u0bcd\u0ba4\u0bbf\u0baf\u0bc8 \u0b87\u0b99\u0bcd\u0b95\u0bc7 \u0ba4\u0b9f\u0bcd\u0b9f\u0b9a\u0bcd\u0b9a\u0bc1 \u0b9a\u0bc6\u0baf\u0bcd\u0baf\u0bb5\u0bc1\u0bae\u0bcd...",
+ "actions": {
+ "send": "\u0b9a\u0bc6\u0baf\u0bcd\u0ba4\u0bbf \u0b85\u0ba9\u0bc1\u0baa\u0bcd\u0baa\u0bc1",
+ "stop": "\u0baa\u0ba3\u0bbf\u0baf\u0bc8 \u0ba8\u0bbf\u0bb1\u0bc1\u0ba4\u0bcd\u0ba4\u0bc1",
+ "attachFiles": "\u0b95\u0bcb\u0baa\u0bcd\u0baa\u0bc1\u0b95\u0bb3\u0bc8 \u0b87\u0ba3\u0bc8"
+ }
+ },
+ "commands": {
+ "button": "\u0b95\u0bb0\u0bc1\u0bb5\u0bbf\u0b95\u0bb3\u0bcd",
+ "changeTool": "\u0b95\u0bb0\u0bc1\u0bb5\u0bbf\u0baf\u0bc8 \u0bae\u0bbe\u0bb1\u0bcd\u0bb1\u0bb5\u0bc1\u0bae\u0bcd",
+ "availableTools": "\u0b95\u0bbf\u0b9f\u0bc8\u0b95\u0bcd\u0b95\u0bc1\u0bae\u0bcd \u0b95\u0bb0\u0bc1\u0bb5\u0bbf\u0b95\u0bb3\u0bcd"
+ },
+ "speech": {
+ "start": "\u0baa\u0ba4\u0bbf\u0bb5\u0bc1 \u0ba4\u0bca\u0b9f\u0b99\u0bcd\u0b95\u0bc1",
+ "stop": "\u0baa\u0ba4\u0bbf\u0bb5\u0bc8 \u0ba8\u0bbf\u0bb1\u0bc1\u0ba4\u0bcd\u0ba4\u0bc1",
+ "connecting": "\u0b87\u0ba3\u0bc8\u0b95\u0bcd\u0b95\u0bbf\u0bb1\u0ba4\u0bc1"
+ },
+ "fileUpload": {
+ "dragDrop": "\u0b95\u0bcb\u0baa\u0bcd\u0baa\u0bc1\u0b95\u0bb3\u0bc8 \u0b87\u0b99\u0bcd\u0b95\u0bc7 \u0b87\u0bb4\u0bc1\u0ba4\u0bcd\u0ba4\u0bc1 \u0bb5\u0bbf\u0b9f\u0bb5\u0bc1\u0bae\u0bcd",
+ "browse": "\u0b95\u0bcb\u0baa\u0bcd\u0baa\u0bc1\u0b95\u0bb3\u0bc8 \u0b89\u0bb2\u0bbe\u0bb5\u0bc1",
+ "sizeLimit": "\u0bb5\u0bb0\u0bae\u0bcd\u0baa\u0bc1:",
+ "errors": {
+ "failed": "\u0baa\u0ba4\u0bbf\u0bb5\u0bc7\u0bb1\u0bcd\u0bb1\u0bae\u0bcd \u0ba4\u0bcb\u0bb2\u0bcd\u0bb5\u0bbf\u0baf\u0b9f\u0bc8\u0ba8\u0bcd\u0ba4\u0ba4\u0bc1",
+ "cancelled": "\u0baa\u0ba4\u0bbf\u0bb5\u0bc7\u0bb1\u0bcd\u0bb1\u0bae\u0bcd \u0bb0\u0ba4\u0bcd\u0ba4\u0bc1 \u0b9a\u0bc6\u0baf\u0bcd\u0baf\u0baa\u0bcd\u0baa\u0b9f\u0bcd\u0b9f\u0ba4\u0bc1"
+ }
+ },
+ "messages": {
+ "status": {
+ "using": "\u0baa\u0baf\u0ba9\u0bcd\u0baa\u0b9f\u0bc1\u0ba4\u0bcd\u0ba4\u0bc1\u0b95\u0bbf\u0bb1\u0ba4\u0bc1",
+ "used": "\u0baa\u0baf\u0ba9\u0bcd\u0baa\u0b9f\u0bc1\u0ba4\u0bcd\u0ba4\u0baa\u0bcd\u0baa\u0b9f\u0bcd\u0b9f\u0ba4\u0bc1"
+ },
+ "actions": {
+ "copy": {
+ "button": "\u0b95\u0bbf\u0bb3\u0bbf\u0baa\u0bcd\u0baa\u0bcb\u0bb0\u0bcd\u0b9f\u0bc1\u0b95\u0bcd\u0b95\u0bc1 \u0ba8\u0b95\u0bb2\u0bc6\u0b9f\u0bc1",
+ "success": "\u0ba8\u0b95\u0bb2\u0bc6\u0b9f\u0bc1\u0b95\u0bcd\u0b95\u0baa\u0bcd\u0baa\u0b9f\u0bcd\u0b9f\u0ba4\u0bc1!"
+ }
+ },
+ "feedback": {
+ "positive": "\u0baa\u0baf\u0ba9\u0bc1\u0bb3\u0bcd\u0bb3\u0ba4\u0bbe\u0b95 \u0b87\u0bb0\u0bc1\u0ba8\u0bcd\u0ba4\u0ba4\u0bc1",
+ "negative": "\u0baa\u0baf\u0ba9\u0bc1\u0bb3\u0bcd\u0bb3\u0ba4\u0bbe\u0b95 \u0b87\u0bb2\u0bcd\u0bb2\u0bc8",
+ "edit": "\u0b95\u0bb0\u0bc1\u0ba4\u0bcd\u0ba4\u0bc8 \u0ba4\u0bbf\u0bb0\u0bc1\u0ba4\u0bcd\u0ba4\u0bc1",
+ "dialog": {
+ "title": "\u0b95\u0bb0\u0bc1\u0ba4\u0bcd\u0ba4\u0bc8\u0b9a\u0bcd \u0b9a\u0bc7\u0bb0\u0bcd",
+ "submit": "\u0b95\u0bb0\u0bc1\u0ba4\u0bcd\u0ba4\u0bc8 \u0b9a\u0bae\u0bb0\u0bcd\u0baa\u0bcd\u0baa\u0bbf"
+ },
+ "status": {
+ "updating": "\u0baa\u0bc1\u0ba4\u0bc1\u0baa\u0bcd\u0baa\u0bbf\u0b95\u0bcd\u0b95\u0bbf\u0bb1\u0ba4\u0bc1",
+ "updated": "\u0b95\u0bb0\u0bc1\u0ba4\u0bcd\u0ba4\u0bc1 \u0baa\u0bc1\u0ba4\u0bc1\u0baa\u0bcd\u0baa\u0bbf\u0b95\u0bcd\u0b95\u0baa\u0bcd\u0baa\u0b9f\u0bcd\u0b9f\u0ba4\u0bc1"
+ }
+ }
+ },
+ "history": {
+ "title": "\u0b95\u0b9f\u0bc8\u0b9a\u0bbf \u0b89\u0bb3\u0bcd\u0bb3\u0bc0\u0b9f\u0bc1\u0b95\u0bb3\u0bcd",
+ "empty": "\u0b95\u0bbe\u0bb2\u0bbf\u0baf\u0bbe\u0b95 \u0b89\u0bb3\u0bcd\u0bb3\u0ba4\u0bc1...",
+ "show": "\u0bb5\u0bb0\u0bb2\u0bbe\u0bb1\u0bcd\u0bb1\u0bc8\u0b95\u0bcd \u0b95\u0bbe\u0b9f\u0bcd\u0b9f\u0bc1"
+ },
+ "settings": {
+ "title": "\u0b85\u0bae\u0bc8\u0baa\u0bcd\u0baa\u0bc1\u0b95\u0bb3\u0bcd \u0baa\u0bb2\u0b95\u0bae\u0bcd"
+ },
+ "watermark": "LLM \u0b95\u0bb3\u0bcd \u0ba4\u0bb5\u0bb1\u0bc1\u0b95\u0bb3\u0bcd \u0b9a\u0bc6\u0baf\u0bcd\u0baf\u0bb2\u0bbe\u0bae\u0bcd. \u0bae\u0bc1\u0b95\u0bcd\u0b95\u0bbf\u0baf\u0bae\u0bbe\u0ba9 \u0ba4\u0b95\u0bb5\u0bb2\u0bcd\u0b95\u0bb3\u0bc8\u0b9a\u0bcd \u0b9a\u0bb0\u0bbf\u0baa\u0bbe\u0bb0\u0bcd\u0baa\u0bcd\u0baa\u0ba4\u0bc8\u0b95\u0bcd \u0b95\u0bb0\u0bc1\u0ba4\u0bcd\u0ba4\u0bbf\u0bb2\u0bcd \u0b95\u0bca\u0bb3\u0bcd\u0bb3\u0bc1\u0b99\u0bcd\u0b95\u0bb3\u0bcd."
+ },
+ "threadHistory": {
+ "sidebar": {
+ "title": "\u0b95\u0b9f\u0ba8\u0bcd\u0ba4 \u0b89\u0bb0\u0bc8\u0baf\u0bbe\u0b9f\u0bb2\u0bcd\u0b95\u0bb3\u0bcd",
+ "filters": {
+ "search": "\u0ba4\u0bc7\u0b9f\u0bc1",
+ "placeholder": "Search conversations..."
+ },
+ "timeframes": {
+ "today": "\u0b87\u0ba9\u0bcd\u0bb1\u0bc1",
+ "yesterday": "\u0ba8\u0bc7\u0bb1\u0bcd\u0bb1\u0bc1",
+ "previous7days": "\u0b95\u0b9f\u0ba8\u0bcd\u0ba4 7 \u0ba8\u0bbe\u0b9f\u0bcd\u0b95\u0bb3\u0bcd",
+ "previous30days": "\u0b95\u0b9f\u0ba8\u0bcd\u0ba4 30 \u0ba8\u0bbe\u0b9f\u0bcd\u0b95\u0bb3\u0bcd"
+ },
+ "empty": "\u0b89\u0bb0\u0bc8\u0baf\u0bbe\u0b9f\u0bb2\u0bcd\u0b95\u0bb3\u0bcd \u0b8e\u0ba4\u0bc1\u0bb5\u0bc1\u0bae\u0bcd \u0b87\u0bb2\u0bcd\u0bb2\u0bc8",
+ "actions": {
+ "close": "\u0baa\u0b95\u0bcd\u0b95\u0baa\u0bcd\u0baa\u0b9f\u0bcd\u0b9f\u0bbf\u0baf\u0bc8 \u0bae\u0bc2\u0b9f\u0bc1",
+ "open": "\u0baa\u0b95\u0bcd\u0b95\u0baa\u0bcd\u0baa\u0b9f\u0bcd\u0b9f\u0bbf\u0baf\u0bc8 \u0ba4\u0bbf\u0bb1"
+ }
+ },
+ "thread": {
+ "untitled": "\u0ba4\u0bb2\u0bc8\u0baa\u0bcd\u0baa\u0bbf\u0b9f\u0bbe\u0ba4 \u0b89\u0bb0\u0bc8\u0baf\u0bbe\u0b9f\u0bb2\u0bcd",
+ "menu": {
+ "rename": "Rename",
+ "delete": "Delete"
+ },
+ "actions": {
+ "delete": {
+ "title": "\u0ba8\u0bc0\u0b95\u0bcd\u0b95\u0bc1\u0bb5\u0ba4\u0bc8 \u0b89\u0bb1\u0bc1\u0ba4\u0bbf\u0baa\u0bcd\u0baa\u0b9f\u0bc1\u0ba4\u0bcd\u0ba4\u0bc1",
+ "description": "\u0b87\u0ba4\u0bc1 \u0b89\u0bb0\u0bc8\u0baf\u0bbe\u0b9f\u0bb2\u0bcd \u0bae\u0bb1\u0bcd\u0bb1\u0bc1\u0bae\u0bcd \u0b85\u0ba4\u0ba9\u0bcd \u0b9a\u0bc6\u0baf\u0bcd\u0ba4\u0bbf\u0b95\u0bb3\u0bcd, \u0b89\u0bb1\u0bc1\u0baa\u0bcd\u0baa\u0bc1\u0b95\u0bb3\u0bc8 \u0ba8\u0bc0\u0b95\u0bcd\u0b95\u0bc1\u0bae\u0bcd. \u0b87\u0ba8\u0bcd\u0ba4 \u0b9a\u0bc6\u0baf\u0bb2\u0bc8 \u0bae\u0bc0\u0b9f\u0bcd\u0b9f\u0bc6\u0b9f\u0bc1\u0b95\u0bcd\u0b95 \u0bae\u0bc1\u0b9f\u0bbf\u0baf\u0bbe\u0ba4\u0bc1",
+ "success": "\u0b89\u0bb0\u0bc8\u0baf\u0bbe\u0b9f\u0bb2\u0bcd \u0ba8\u0bc0\u0b95\u0bcd\u0b95\u0baa\u0bcd\u0baa\u0b9f\u0bcd\u0b9f\u0ba4\u0bc1",
+ "inProgress": "\u0b89\u0bb0\u0bc8\u0baf\u0bbe\u0b9f\u0bb2\u0bc8 \u0ba8\u0bc0\u0b95\u0bcd\u0b95\u0bc1\u0b95\u0bbf\u0bb1\u0ba4\u0bc1"
+ },
+ "rename": {
+ "title": "\u0b89\u0bb0\u0bc8\u0baf\u0bbe\u0b9f\u0bb2\u0bc8 \u0bae\u0bb1\u0bc1\u0baa\u0bc6\u0baf\u0bb0\u0bbf\u0b9f\u0bc1",
+ "description": "\u0b87\u0ba8\u0bcd\u0ba4 \u0b89\u0bb0\u0bc8\u0baf\u0bbe\u0b9f\u0bb2\u0bc1\u0b95\u0bcd\u0b95\u0bc1 \u0baa\u0bc1\u0ba4\u0bbf\u0baf \u0baa\u0bc6\u0baf\u0bb0\u0bc8 \u0b89\u0bb3\u0bcd\u0bb3\u0bbf\u0b9f\u0bb5\u0bc1\u0bae\u0bcd",
+ "form": {
+ "name": {
+ "label": "\u0baa\u0bc6\u0baf\u0bb0\u0bcd",
+ "placeholder": "\u0baa\u0bc1\u0ba4\u0bbf\u0baf \u0baa\u0bc6\u0baf\u0bb0\u0bc8 \u0b89\u0bb3\u0bcd\u0bb3\u0bbf\u0b9f\u0bb5\u0bc1\u0bae\u0bcd"
+ }
+ },
+ "success": "\u0b89\u0bb0\u0bc8\u0baf\u0bbe\u0b9f\u0bb2\u0bcd \u0bae\u0bb1\u0bc1\u0baa\u0bc6\u0baf\u0bb0\u0bbf\u0b9f\u0baa\u0bcd\u0baa\u0b9f\u0bcd\u0b9f\u0ba4\u0bc1!",
+ "inProgress": "\u0b89\u0bb0\u0bc8\u0baf\u0bbe\u0b9f\u0bb2\u0bc8 \u0bae\u0bb1\u0bc1\u0baa\u0bc6\u0baf\u0bb0\u0bbf\u0b9f\u0bc1\u0b95\u0bbf\u0bb1\u0ba4\u0bc1"
+ }
+ }
+ }
+ },
+ "navigation": {
+ "header": {
+ "chat": "\u0b89\u0bb0\u0bc8\u0baf\u0bbe\u0b9f\u0bb2\u0bcd",
+ "readme": "\u0baa\u0b9f\u0bbf\u0b95\u0bcd\u0b95\u0bb5\u0bc1\u0bae\u0bcd",
+ "theme": {
+ "light": "Light Theme",
+ "dark": "Dark Theme",
+ "system": "Follow System"
+ }
+ },
+ "newChat": {
+ "button": "\u0baa\u0bc1\u0ba4\u0bbf\u0baf \u0b89\u0bb0\u0bc8\u0baf\u0bbe\u0b9f\u0bb2\u0bcd",
+ "dialog": {
+ "title": "\u0baa\u0bc1\u0ba4\u0bbf\u0baf \u0b89\u0bb0\u0bc8\u0baf\u0bbe\u0b9f\u0bb2\u0bc8 \u0b89\u0bb0\u0bc1\u0bb5\u0bbe\u0b95\u0bcd\u0b95\u0bc1",
+ "description": "\u0b87\u0ba4\u0bc1 \u0b89\u0b99\u0bcd\u0b95\u0bb3\u0bcd \u0ba4\u0bb1\u0bcd\u0baa\u0bcb\u0ba4\u0bc8\u0baf \u0b89\u0bb0\u0bc8\u0baf\u0bbe\u0b9f\u0bb2\u0bcd \u0bb5\u0bb0\u0bb2\u0bbe\u0bb1\u0bcd\u0bb1\u0bc8 \u0b85\u0bb4\u0bbf\u0b95\u0bcd\u0b95\u0bc1\u0bae\u0bcd. \u0ba4\u0bca\u0b9f\u0bb0 \u0bb5\u0bbf\u0bb0\u0bc1\u0bae\u0bcd\u0baa\u0bc1\u0b95\u0bbf\u0bb1\u0bc0\u0bb0\u0bcd\u0b95\u0bb3\u0bbe?",
+ "tooltip": "\u0baa\u0bc1\u0ba4\u0bbf\u0baf \u0b89\u0bb0\u0bc8\u0baf\u0bbe\u0b9f\u0bb2\u0bcd"
+ }
+ },
+ "user": {
+ "menu": {
+ "settings": "\u0b85\u0bae\u0bc8\u0baa\u0bcd\u0baa\u0bc1\u0b95\u0bb3\u0bcd",
+ "settingsKey": "S",
+ "apiKeys": "API \u0bb5\u0bbf\u0b9a\u0bc8\u0b95\u0bb3\u0bcd",
+ "logout": "\u0bb5\u0bc6\u0bb3\u0bbf\u0baf\u0bc7\u0bb1\u0bc1"
+ }
+ }
+ },
+ "apiKeys": {
+ "title": "\u0ba4\u0bc7\u0bb5\u0bc8\u0baf\u0bbe\u0ba9 API \u0bb5\u0bbf\u0b9a\u0bc8\u0b95\u0bb3\u0bcd",
+ "description": "\u0b87\u0ba8\u0bcd\u0ba4 \u0baa\u0baf\u0ba9\u0bcd\u0baa\u0bbe\u0b9f\u0bcd\u0b9f\u0bc8\u0baa\u0bcd \u0baa\u0baf\u0ba9\u0bcd\u0baa\u0b9f\u0bc1\u0ba4\u0bcd\u0ba4, \u0baa\u0bbf\u0ba9\u0bcd\u0bb5\u0bb0\u0bc1\u0bae\u0bcd API \u0bb5\u0bbf\u0b9a\u0bc8\u0b95\u0bb3\u0bcd \u0ba4\u0bc7\u0bb5\u0bc8. \u0bb5\u0bbf\u0b9a\u0bc8\u0b95\u0bb3\u0bcd \u0b89\u0b99\u0bcd\u0b95\u0bb3\u0bcd \u0b9a\u0bbe\u0ba4\u0ba9\u0ba4\u0bcd\u0ba4\u0bbf\u0ba9\u0bcd \u0b89\u0bb3\u0bcd\u0bb3\u0bc2\u0bb0\u0bcd \u0b9a\u0bc7\u0bae\u0bbf\u0baa\u0bcd\u0baa\u0b95\u0ba4\u0bcd\u0ba4\u0bbf\u0bb2\u0bcd \u0b9a\u0bc7\u0bae\u0bbf\u0b95\u0bcd\u0b95\u0baa\u0bcd\u0baa\u0b9f\u0bc1\u0bae\u0bcd.",
+ "success": {
+ "saved": "\u0bb5\u0bc6\u0bb1\u0bcd\u0bb1\u0bbf\u0b95\u0bb0\u0bae\u0bbe\u0b95 \u0b9a\u0bc7\u0bae\u0bbf\u0b95\u0bcd\u0b95\u0baa\u0bcd\u0baa\u0b9f\u0bcd\u0b9f\u0ba4\u0bc1"
+ }
+ },
+ "alerts": {
+ "info": "Info",
+ "note": "Note",
+ "tip": "Tip",
+ "important": "Important",
+ "warning": "Warning",
+ "caution": "Caution",
+ "debug": "Debug",
+ "example": "Example",
+ "success": "Success",
+ "help": "Help",
+ "idea": "Idea",
+ "pending": "Pending",
+ "security": "Security",
+ "beta": "Beta",
+ "best-practice": "Best Practice"
+ }
+}
\ No newline at end of file
diff --git a/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/te.json b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/te.json
new file mode 100644
index 0000000..820c939
--- /dev/null
+++ b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/te.json
@@ -0,0 +1,219 @@
+{
+ "common": {
+ "actions": {
+ "cancel": "\u0c30\u0c26\u0c4d\u0c26\u0c41 \u0c1a\u0c47\u0c2f\u0c02\u0c21\u0c3f",
+ "confirm": "\u0c28\u0c3f\u0c30\u0c4d\u0c27\u0c3e\u0c30\u0c3f\u0c02\u0c1a\u0c02\u0c21\u0c3f",
+ "continue": "\u0c15\u0c4a\u0c28\u0c38\u0c3e\u0c17\u0c3f\u0c02\u0c1a\u0c02\u0c21\u0c3f",
+ "goBack": "\u0c35\u0c46\u0c28\u0c15\u0c4d\u0c15\u0c3f \u0c35\u0c46\u0c33\u0c4d\u0c33\u0c02\u0c21\u0c3f",
+ "reset": "\u0c30\u0c40\u0c38\u0c46\u0c1f\u0c4d \u0c1a\u0c47\u0c2f\u0c02\u0c21\u0c3f",
+ "submit": "\u0c38\u0c2e\u0c30\u0c4d\u0c2a\u0c3f\u0c02\u0c1a\u0c02\u0c21\u0c3f"
+ },
+ "status": {
+ "loading": "\u0c32\u0c4b\u0c21\u0c4d \u0c05\u0c35\u0c41\u0c24\u0c4b\u0c02\u0c26\u0c3f...",
+ "error": {
+ "default": "\u0c32\u0c4b\u0c2a\u0c02 \u0c38\u0c02\u0c2d\u0c35\u0c3f\u0c02\u0c1a\u0c3f\u0c02\u0c26\u0c3f",
+ "serverConnection": "\u0c38\u0c30\u0c4d\u0c35\u0c30\u0c4d\u200c\u0c28\u0c3f \u0c1a\u0c47\u0c30\u0c41\u0c15\u0c4b\u0c32\u0c47\u0c15\u0c2a\u0c4b\u0c2f\u0c3e\u0c2e\u0c41"
+ }
+ }
+ },
+ "auth": {
+ "login": {
+ "title": "\u0c2f\u0c3e\u0c2a\u0c4d\u200c\u0c28\u0c3f \u0c09\u0c2a\u0c2f\u0c4b\u0c17\u0c3f\u0c02\u0c1a\u0c21\u0c3e\u0c28\u0c3f\u0c15\u0c3f \u0c32\u0c3e\u0c17\u0c3f\u0c28\u0c4d \u0c1a\u0c47\u0c2f\u0c02\u0c21\u0c3f",
+ "form": {
+ "email": {
+ "label": "\u0c07\u0c2e\u0c46\u0c2f\u0c3f\u0c32\u0c4d \u0c1a\u0c3f\u0c30\u0c41\u0c28\u0c3e\u0c2e\u0c3e",
+ "required": "\u0c07\u0c2e\u0c46\u0c2f\u0c3f\u0c32\u0c4d \u0c24\u0c2a\u0c4d\u0c2a\u0c28\u0c3f\u0c38\u0c30\u0c3f"
+ },
+ "password": {
+ "label": "\u0c2a\u0c3e\u0c38\u0c4d\u200c\u0c35\u0c30\u0c4d\u0c21\u0c4d",
+ "required": "\u0c2a\u0c3e\u0c38\u0c4d\u200c\u0c35\u0c30\u0c4d\u0c21\u0c4d \u0c24\u0c2a\u0c4d\u0c2a\u0c28\u0c3f\u0c38\u0c30\u0c3f"
+ },
+ "actions": {
+ "signin": "\u0c38\u0c48\u0c28\u0c4d \u0c07\u0c28\u0c4d \u0c1a\u0c47\u0c2f\u0c02\u0c21\u0c3f"
+ },
+ "alternativeText": {
+ "or": "\u0c32\u0c47\u0c26\u0c3e"
+ }
+ },
+ "errors": {
+ "default": "\u0c38\u0c48\u0c28\u0c4d \u0c07\u0c28\u0c4d \u0c1a\u0c47\u0c2f\u0c32\u0c47\u0c15\u0c2a\u0c4b\u0c2f\u0c3e\u0c2e\u0c41",
+ "signin": "\u0c35\u0c47\u0c30\u0c47 \u0c16\u0c3e\u0c24\u0c3e\u0c24\u0c4b \u0c38\u0c48\u0c28\u0c4d \u0c07\u0c28\u0c4d \u0c1a\u0c47\u0c2f\u0c21\u0c3e\u0c28\u0c3f\u0c15\u0c3f \u0c2a\u0c4d\u0c30\u0c2f\u0c24\u0c4d\u0c28\u0c3f\u0c02\u0c1a\u0c02\u0c21\u0c3f",
+ "oauthSignin": "\u0c35\u0c47\u0c30\u0c47 \u0c16\u0c3e\u0c24\u0c3e\u0c24\u0c4b \u0c38\u0c48\u0c28\u0c4d \u0c07\u0c28\u0c4d \u0c1a\u0c47\u0c2f\u0c21\u0c3e\u0c28\u0c3f\u0c15\u0c3f \u0c2a\u0c4d\u0c30\u0c2f\u0c24\u0c4d\u0c28\u0c3f\u0c02\u0c1a\u0c02\u0c21\u0c3f",
+ "redirectUriMismatch": "\u0c30\u0c40\u0c21\u0c48\u0c30\u0c46\u0c15\u0c4d\u0c1f\u0c4d URI oauth \u0c2f\u0c3e\u0c2a\u0c4d \u0c15\u0c3e\u0c28\u0c4d\u0c2b\u0c3f\u0c17\u0c30\u0c47\u0c37\u0c28\u0c4d\u200c\u0c24\u0c4b \u0c38\u0c30\u0c3f\u0c2a\u0c4b\u0c32\u0c21\u0c02 \u0c32\u0c47\u0c26\u0c41",
+ "oauthCallback": "\u0c35\u0c47\u0c30\u0c47 \u0c16\u0c3e\u0c24\u0c3e\u0c24\u0c4b \u0c38\u0c48\u0c28\u0c4d \u0c07\u0c28\u0c4d \u0c1a\u0c47\u0c2f\u0c21\u0c3e\u0c28\u0c3f\u0c15\u0c3f \u0c2a\u0c4d\u0c30\u0c2f\u0c24\u0c4d\u0c28\u0c3f\u0c02\u0c1a\u0c02\u0c21\u0c3f",
+ "oauthCreateAccount": "\u0c35\u0c47\u0c30\u0c47 \u0c16\u0c3e\u0c24\u0c3e\u0c24\u0c4b \u0c38\u0c48\u0c28\u0c4d \u0c07\u0c28\u0c4d \u0c1a\u0c47\u0c2f\u0c21\u0c3e\u0c28\u0c3f\u0c15\u0c3f \u0c2a\u0c4d\u0c30\u0c2f\u0c24\u0c4d\u0c28\u0c3f\u0c02\u0c1a\u0c02\u0c21\u0c3f",
+ "emailCreateAccount": "\u0c35\u0c47\u0c30\u0c47 \u0c16\u0c3e\u0c24\u0c3e\u0c24\u0c4b \u0c38\u0c48\u0c28\u0c4d \u0c07\u0c28\u0c4d \u0c1a\u0c47\u0c2f\u0c21\u0c3e\u0c28\u0c3f\u0c15\u0c3f \u0c2a\u0c4d\u0c30\u0c2f\u0c24\u0c4d\u0c28\u0c3f\u0c02\u0c1a\u0c02\u0c21\u0c3f",
+ "callback": "\u0c35\u0c47\u0c30\u0c47 \u0c16\u0c3e\u0c24\u0c3e\u0c24\u0c4b \u0c38\u0c48\u0c28\u0c4d \u0c07\u0c28\u0c4d \u0c1a\u0c47\u0c2f\u0c21\u0c3e\u0c28\u0c3f\u0c15\u0c3f \u0c2a\u0c4d\u0c30\u0c2f\u0c24\u0c4d\u0c28\u0c3f\u0c02\u0c1a\u0c02\u0c21\u0c3f",
+ "oauthAccountNotLinked": "\u0c2e\u0c40 \u0c17\u0c41\u0c30\u0c4d\u0c24\u0c3f\u0c02\u0c2a\u0c41\u0c28\u0c41 \u0c28\u0c3f\u0c30\u0c4d\u0c27\u0c3e\u0c30\u0c3f\u0c02\u0c1a\u0c21\u0c3e\u0c28\u0c3f\u0c15\u0c3f, \u0c2e\u0c40\u0c30\u0c41 \u0c2e\u0c4a\u0c26\u0c1f \u0c09\u0c2a\u0c2f\u0c4b\u0c17\u0c3f\u0c02\u0c1a\u0c3f\u0c28 \u0c05\u0c26\u0c47 \u0c16\u0c3e\u0c24\u0c3e\u0c24\u0c4b \u0c38\u0c48\u0c28\u0c4d \u0c07\u0c28\u0c4d \u0c1a\u0c47\u0c2f\u0c02\u0c21\u0c3f",
+ "emailSignin": "\u0c07\u0c2e\u0c46\u0c2f\u0c3f\u0c32\u0c4d \u0c2a\u0c02\u0c2a\u0c21\u0c02 \u0c38\u0c3e\u0c27\u0c4d\u0c2f\u0c02 \u0c15\u0c3e\u0c32\u0c47\u0c26\u0c41",
+ "emailVerify": "\u0c26\u0c2f\u0c1a\u0c47\u0c38\u0c3f \u0c2e\u0c40 \u0c07\u0c2e\u0c46\u0c2f\u0c3f\u0c32\u0c4d\u200c\u0c28\u0c3f \u0c27\u0c43\u0c35\u0c40\u0c15\u0c30\u0c3f\u0c02\u0c1a\u0c02\u0c21\u0c3f, \u0c15\u0c4a\u0c24\u0c4d\u0c24 \u0c07\u0c2e\u0c46\u0c2f\u0c3f\u0c32\u0c4d \u0c2a\u0c02\u0c2a\u0c2c\u0c21\u0c3f\u0c02\u0c26\u0c3f",
+ "credentialsSignin": "\u0c38\u0c48\u0c28\u0c4d \u0c07\u0c28\u0c4d \u0c35\u0c3f\u0c2b\u0c32\u0c2e\u0c48\u0c02\u0c26\u0c3f. \u0c2e\u0c40\u0c30\u0c41 \u0c05\u0c02\u0c26\u0c3f\u0c02\u0c1a\u0c3f\u0c28 \u0c35\u0c3f\u0c35\u0c30\u0c3e\u0c32\u0c41 \u0c38\u0c30\u0c48\u0c28\u0c35\u0c47\u0c28\u0c3e \u0c05\u0c28\u0c3f \u0c24\u0c28\u0c3f\u0c16\u0c40 \u0c1a\u0c47\u0c2f\u0c02\u0c21\u0c3f",
+ "sessionRequired": "\u0c08 \u0c2a\u0c47\u0c1c\u0c40\u0c28\u0c3f \u0c2f\u0c3e\u0c15\u0c4d\u0c38\u0c46\u0c38\u0c4d \u0c1a\u0c47\u0c2f\u0c21\u0c3e\u0c28\u0c3f\u0c15\u0c3f \u0c26\u0c2f\u0c1a\u0c47\u0c38\u0c3f \u0c38\u0c48\u0c28\u0c4d \u0c07\u0c28\u0c4d \u0c1a\u0c47\u0c2f\u0c02\u0c21\u0c3f"
+ }
+ },
+ "provider": {
+ "continue": "{{provider}}\u0c24\u0c4b \u0c15\u0c4a\u0c28\u0c38\u0c3e\u0c17\u0c3f\u0c02\u0c1a\u0c02\u0c21\u0c3f"
+ }
+ },
+ "chat": {
+ "input": {
+ "placeholder": "\u0c2e\u0c40 \u0c38\u0c02\u0c26\u0c47\u0c36\u0c3e\u0c28\u0c4d\u0c28\u0c3f \u0c07\u0c15\u0c4d\u0c15\u0c21 \u0c1f\u0c48\u0c2a\u0c4d \u0c1a\u0c47\u0c2f\u0c02\u0c21\u0c3f...",
+ "actions": {
+ "send": "\u0c38\u0c02\u0c26\u0c47\u0c36\u0c02 \u0c2a\u0c02\u0c2a\u0c02\u0c21\u0c3f",
+ "stop": "\u0c2a\u0c28\u0c3f \u0c06\u0c2a\u0c02\u0c21\u0c3f",
+ "attachFiles": "\u0c2b\u0c48\u0c32\u0c4d\u0c38\u0c4d \u0c1c\u0c4b\u0c21\u0c3f\u0c02\u0c1a\u0c02\u0c21\u0c3f"
+ }
+ },
+ "speech": {
+ "start": "\u0c30\u0c3f\u0c15\u0c3e\u0c30\u0c4d\u0c21\u0c3f\u0c02\u0c17\u0c4d \u0c2a\u0c4d\u0c30\u0c3e\u0c30\u0c02\u0c2d\u0c3f\u0c02\u0c1a\u0c02\u0c21\u0c3f",
+ "stop": "\u0c30\u0c3f\u0c15\u0c3e\u0c30\u0c4d\u0c21\u0c3f\u0c02\u0c17\u0c4d \u0c06\u0c2a\u0c02\u0c21\u0c3f",
+ "connecting": "\u0c05\u0c28\u0c41\u0c38\u0c02\u0c27\u0c3e\u0c28\u0c3f\u0c38\u0c4d\u0c24\u0c4b\u0c02\u0c26\u0c3f"
+ },
+ "commands": {
+ "button": "\u0c2a\u0c30\u0c3f\u0c15\u0c30\u0c3e\u0c32\u0c41",
+ "changeTool": "\u0c2a\u0c30\u0c3f\u0c15\u0c30\u0c3e\u0c28\u0c4d\u0c28\u0c3f \u0c2e\u0c3e\u0c30\u0c4d\u0c1a\u0c02\u0c21\u0c3f",
+ "availableTools": "\u0c32\u0c2d\u0c4d\u0c2f\u0c2e\u0c48\u0c28 \u0c2a\u0c30\u0c3f\u0c15\u0c30\u0c3e\u0c32\u0c41"
+ },
+ "fileUpload": {
+ "dragDrop": "\u0c2b\u0c48\u0c32\u0c4d\u0c38\u0c4d\u200c\u0c28\u0c3f \u0c07\u0c15\u0c4d\u0c15\u0c21 \u0c21\u0c4d\u0c30\u0c3e\u0c17\u0c4d \u0c1a\u0c47\u0c38\u0c3f \u0c21\u0c4d\u0c30\u0c3e\u0c2a\u0c4d \u0c1a\u0c47\u0c2f\u0c02\u0c21\u0c3f",
+ "browse": "\u0c2b\u0c48\u0c32\u0c4d\u0c38\u0c4d \u0c2c\u0c4d\u0c30\u0c4c\u0c1c\u0c4d \u0c1a\u0c47\u0c2f\u0c02\u0c21\u0c3f",
+ "sizeLimit": "\u0c2a\u0c30\u0c3f\u0c2e\u0c3f\u0c24\u0c3f:",
+ "errors": {
+ "failed": "\u0c05\u0c2a\u0c4d\u200c\u0c32\u0c4b\u0c21\u0c4d \u0c35\u0c3f\u0c2b\u0c32\u0c2e\u0c48\u0c02\u0c26\u0c3f",
+ "cancelled": "\u0c05\u0c2a\u0c4d\u200c\u0c32\u0c4b\u0c21\u0c4d \u0c30\u0c26\u0c4d\u0c26\u0c41 \u0c1a\u0c47\u0c2f\u0c2c\u0c21\u0c3f\u0c02\u0c26\u0c3f"
+ }
+ },
+ "messages": {
+ "status": {
+ "using": "\u0c09\u0c2a\u0c2f\u0c4b\u0c17\u0c3f\u0c38\u0c4d\u0c24\u0c4b\u0c02\u0c26\u0c3f",
+ "used": "\u0c09\u0c2a\u0c2f\u0c4b\u0c17\u0c3f\u0c02\u0c1a\u0c2c\u0c21\u0c3f\u0c02\u0c26\u0c3f"
+ },
+ "actions": {
+ "copy": {
+ "button": "\u0c15\u0c4d\u0c32\u0c3f\u0c2a\u0c4d\u200c\u0c2c\u0c4b\u0c30\u0c4d\u0c21\u0c4d\u200c\u0c15\u0c3f \u0c15\u0c3e\u0c2a\u0c40 \u0c1a\u0c47\u0c2f\u0c02\u0c21\u0c3f",
+ "success": "\u0c15\u0c3e\u0c2a\u0c40 \u0c1a\u0c47\u0c2f\u0c2c\u0c21\u0c3f\u0c02\u0c26\u0c3f!"
+ }
+ },
+ "feedback": {
+ "positive": "\u0c38\u0c39\u0c3e\u0c2f\u0c15\u0c30\u0c02",
+ "negative": "\u0c38\u0c39\u0c3e\u0c2f\u0c15\u0c30\u0c02 \u0c15\u0c3e\u0c26\u0c41",
+ "edit": "\u0c05\u0c2d\u0c3f\u0c2a\u0c4d\u0c30\u0c3e\u0c2f\u0c3e\u0c28\u0c4d\u0c28\u0c3f \u0c38\u0c35\u0c30\u0c3f\u0c02\u0c1a\u0c02\u0c21\u0c3f",
+ "dialog": {
+ "title": "\u0c35\u0c4d\u0c2f\u0c3e\u0c16\u0c4d\u0c2f \u0c1c\u0c4b\u0c21\u0c3f\u0c02\u0c1a\u0c02\u0c21\u0c3f",
+ "submit": "\u0c05\u0c2d\u0c3f\u0c2a\u0c4d\u0c30\u0c3e\u0c2f\u0c3e\u0c28\u0c4d\u0c28\u0c3f \u0c38\u0c2e\u0c30\u0c4d\u0c2a\u0c3f\u0c02\u0c1a\u0c02\u0c21\u0c3f"
+ },
+ "status": {
+ "updating": "\u0c28\u0c35\u0c40\u0c15\u0c30\u0c3f\u0c38\u0c4d\u0c24\u0c4b\u0c02\u0c26\u0c3f",
+ "updated": "\u0c05\u0c2d\u0c3f\u0c2a\u0c4d\u0c30\u0c3e\u0c2f\u0c02 \u0c28\u0c35\u0c40\u0c15\u0c30\u0c3f\u0c02\u0c1a\u0c2c\u0c21\u0c3f\u0c02\u0c26\u0c3f"
+ }
+ }
+ },
+ "history": {
+ "title": "\u0c1a\u0c3f\u0c35\u0c30\u0c3f \u0c07\u0c28\u0c4d\u200c\u0c2a\u0c41\u0c1f\u0c4d\u200c\u0c32\u0c41",
+ "empty": "\u0c16\u0c3e\u0c33\u0c40\u0c17\u0c3e \u0c09\u0c02\u0c26\u0c3f...",
+ "show": "\u0c1a\u0c30\u0c3f\u0c24\u0c4d\u0c30\u0c28\u0c41 \u0c1a\u0c42\u0c2a\u0c3f\u0c02\u0c1a\u0c41"
+ },
+ "settings": {
+ "title": "\u0c38\u0c46\u0c1f\u0c4d\u0c1f\u0c3f\u0c02\u0c17\u0c4d\u200c\u0c32 \u0c2a\u0c4d\u0c2f\u0c3e\u0c28\u0c46\u0c32\u0c4d"
+ },
+ "watermark": "LLM\u0c32\u0c41 \u0c24\u0c2a\u0c4d\u0c2a\u0c41\u0c32\u0c41 \u0c1a\u0c47\u0c2f\u0c35\u0c1a\u0c4d\u0c1a\u0c41. \u0c2e\u0c41\u0c16\u0c4d\u0c2f\u0c2e\u0c48\u0c28 \u0c38\u0c2e\u0c3e\u0c1a\u0c3e\u0c30\u0c3e\u0c28\u0c4d\u0c28\u0c3f \u0c24\u0c28\u0c3f\u0c16\u0c40 \u0c1a\u0c47\u0c2f\u0c21\u0c3e\u0c28\u0c4d\u0c28\u0c3f \u0c2a\u0c30\u0c3f\u0c17\u0c23\u0c3f\u0c02\u0c1a\u0c02\u0c21\u0c3f."
+ },
+ "threadHistory": {
+ "sidebar": {
+ "title": "\u0c17\u0c24 \u0c1a\u0c3e\u0c1f\u0c4d\u200c\u0c32\u0c41",
+ "filters": {
+ "search": "\u0c35\u0c46\u0c24\u0c15\u0c02\u0c21\u0c3f",
+ "placeholder": "Search conversations..."
+ },
+ "timeframes": {
+ "today": "\u0c08\u0c30\u0c4b\u0c1c\u0c41",
+ "yesterday": "\u0c28\u0c3f\u0c28\u0c4d\u0c28",
+ "previous7days": "\u0c17\u0c24 7 \u0c30\u0c4b\u0c1c\u0c41\u0c32\u0c41",
+ "previous30days": "\u0c17\u0c24 30 \u0c30\u0c4b\u0c1c\u0c41\u0c32\u0c41"
+ },
+ "empty": "\u0c25\u0c4d\u0c30\u0c46\u0c21\u0c4d\u200c\u0c32\u0c41 \u0c15\u0c28\u0c41\u0c17\u0c4a\u0c28\u0c2c\u0c21\u0c32\u0c47\u0c26\u0c41",
+ "actions": {
+ "close": "\u0c38\u0c48\u0c21\u0c4d\u200c\u0c2c\u0c3e\u0c30\u0c4d \u0c2e\u0c42\u0c38\u0c3f\u0c35\u0c47\u0c2f\u0c02\u0c21\u0c3f",
+ "open": "\u0c38\u0c48\u0c21\u0c4d\u200c\u0c2c\u0c3e\u0c30\u0c4d \u0c24\u0c46\u0c30\u0c35\u0c02\u0c21\u0c3f"
+ }
+ },
+ "thread": {
+ "untitled": "\u0c2a\u0c47\u0c30\u0c41 \u0c32\u0c47\u0c28\u0c3f \u0c38\u0c02\u0c2d\u0c3e\u0c37\u0c23",
+ "menu": {
+ "rename": "Rename",
+ "delete": "Delete"
+ },
+ "actions": {
+ "delete": {
+ "title": "\u0c24\u0c4a\u0c32\u0c17\u0c3f\u0c02\u0c2a\u0c41\u0c28\u0c41 \u0c28\u0c3f\u0c30\u0c4d\u0c27\u0c3e\u0c30\u0c3f\u0c02\u0c1a\u0c02\u0c21\u0c3f",
+ "description": "\u0c07\u0c26\u0c3f \u0c25\u0c4d\u0c30\u0c46\u0c21\u0c4d\u200c\u0c24\u0c4b \u0c2a\u0c3e\u0c1f\u0c41 \u0c26\u0c3e\u0c28\u0c3f \u0c38\u0c02\u0c26\u0c47\u0c36\u0c3e\u0c32\u0c28\u0c41 \u0c2e\u0c30\u0c3f\u0c2f\u0c41 \u0c05\u0c02\u0c36\u0c3e\u0c32\u0c28\u0c41 \u0c24\u0c4a\u0c32\u0c17\u0c3f\u0c38\u0c4d\u0c24\u0c41\u0c02\u0c26\u0c3f. \u0c08 \u0c1a\u0c30\u0c4d\u0c2f\u0c28\u0c41 \u0c30\u0c26\u0c4d\u0c26\u0c41 \u0c1a\u0c47\u0c2f\u0c32\u0c47\u0c30\u0c41",
+ "success": "\u0c1a\u0c3e\u0c1f\u0c4d \u0c24\u0c4a\u0c32\u0c17\u0c3f\u0c02\u0c1a\u0c2c\u0c21\u0c3f\u0c02\u0c26\u0c3f",
+ "inProgress": "\u0c1a\u0c3e\u0c1f\u0c4d\u200c\u0c28\u0c3f \u0c24\u0c4a\u0c32\u0c17\u0c3f\u0c38\u0c4d\u0c24\u0c4b\u0c02\u0c26\u0c3f"
+ },
+ "rename": {
+ "title": "\u0c25\u0c4d\u0c30\u0c46\u0c21\u0c4d \u0c2a\u0c47\u0c30\u0c41 \u0c2e\u0c3e\u0c30\u0c4d\u0c1a\u0c02\u0c21\u0c3f",
+ "description": "\u0c08 \u0c25\u0c4d\u0c30\u0c46\u0c21\u0c4d \u0c15\u0c4b\u0c38\u0c02 \u0c15\u0c4a\u0c24\u0c4d\u0c24 \u0c2a\u0c47\u0c30\u0c41\u0c28\u0c41 \u0c28\u0c2e\u0c4b\u0c26\u0c41 \u0c1a\u0c47\u0c2f\u0c02\u0c21\u0c3f",
+ "form": {
+ "name": {
+ "label": "\u0c2a\u0c47\u0c30\u0c41",
+ "placeholder": "\u0c15\u0c4a\u0c24\u0c4d\u0c24 \u0c2a\u0c47\u0c30\u0c41\u0c28\u0c41 \u0c28\u0c2e\u0c4b\u0c26\u0c41 \u0c1a\u0c47\u0c2f\u0c02\u0c21\u0c3f"
+ }
+ },
+ "success": "\u0c25\u0c4d\u0c30\u0c46\u0c21\u0c4d \u0c2a\u0c47\u0c30\u0c41 \u0c2e\u0c3e\u0c30\u0c4d\u0c1a\u0c2c\u0c21\u0c3f\u0c02\u0c26\u0c3f!",
+ "inProgress": "\u0c25\u0c4d\u0c30\u0c46\u0c21\u0c4d \u0c2a\u0c47\u0c30\u0c41 \u0c2e\u0c3e\u0c30\u0c41\u0c38\u0c4d\u0c24\u0c4b\u0c02\u0c26\u0c3f"
+ }
+ }
+ }
+ },
+ "navigation": {
+ "header": {
+ "chat": "\u0c1a\u0c3e\u0c1f\u0c4d",
+ "readme": "\u0c1a\u0c26\u0c35\u0c02\u0c21\u0c3f",
+ "theme": {
+ "light": "Light Theme",
+ "dark": "Dark Theme",
+ "system": "Follow System"
+ }
+ },
+ "newChat": {
+ "button": "\u0c15\u0c4a\u0c24\u0c4d\u0c24 \u0c1a\u0c3e\u0c1f\u0c4d",
+ "dialog": {
+ "title": "\u0c15\u0c4a\u0c24\u0c4d\u0c24 \u0c1a\u0c3e\u0c1f\u0c4d \u0c38\u0c43\u0c37\u0c4d\u0c1f\u0c3f\u0c02\u0c1a\u0c02\u0c21\u0c3f",
+ "description": "\u0c07\u0c26\u0c3f \u0c2e\u0c40 \u0c2a\u0c4d\u0c30\u0c38\u0c4d\u0c24\u0c41\u0c24 \u0c1a\u0c3e\u0c1f\u0c4d \u0c1a\u0c30\u0c3f\u0c24\u0c4d\u0c30\u0c28\u0c41 \u0c24\u0c41\u0c21\u0c3f\u0c1a\u0c3f\u0c35\u0c47\u0c38\u0c4d\u0c24\u0c41\u0c02\u0c26\u0c3f. \u0c2e\u0c40\u0c30\u0c41 \u0c15\u0c4a\u0c28\u0c38\u0c3e\u0c17\u0c3f\u0c02\u0c1a\u0c3e\u0c32\u0c28\u0c41\u0c15\u0c41\u0c02\u0c1f\u0c41\u0c28\u0c4d\u0c28\u0c3e\u0c30\u0c3e?",
+ "tooltip": "\u0c15\u0c4a\u0c24\u0c4d\u0c24 \u0c1a\u0c3e\u0c1f\u0c4d"
+ }
+ },
+ "user": {
+ "menu": {
+ "settings": "\u0c38\u0c46\u0c1f\u0c4d\u0c1f\u0c3f\u0c02\u0c17\u0c4d\u200c\u0c32\u0c41",
+ "settingsKey": "S",
+ "apiKeys": "API \u0c15\u0c40\u0c32\u0c41",
+ "logout": "\u0c32\u0c3e\u0c17\u0c4d \u0c05\u0c35\u0c41\u0c1f\u0c4d"
+ }
+ }
+ },
+ "apiKeys": {
+ "title": "\u0c05\u0c35\u0c38\u0c30\u0c2e\u0c48\u0c28 API \u0c15\u0c40\u0c32\u0c41",
+ "description": "\u0c08 \u0c2f\u0c3e\u0c2a\u0c4d\u200c\u0c28\u0c3f \u0c09\u0c2a\u0c2f\u0c4b\u0c17\u0c3f\u0c02\u0c1a\u0c21\u0c3e\u0c28\u0c3f\u0c15\u0c3f, \u0c15\u0c3f\u0c02\u0c26\u0c3f API \u0c15\u0c40\u0c32\u0c41 \u0c05\u0c35\u0c38\u0c30\u0c02. \u0c15\u0c40\u0c32\u0c41 \u0c2e\u0c40 \u0c2a\u0c30\u0c3f\u0c15\u0c30\u0c02 \u0c2f\u0c4a\u0c15\u0c4d\u0c15 \u0c38\u0c4d\u0c25\u0c3e\u0c28\u0c3f\u0c15 \u0c28\u0c3f\u0c32\u0c4d\u0c35\u0c32\u0c4b \u0c28\u0c3f\u0c32\u0c4d\u0c35 \u0c1a\u0c47\u0c2f\u0c2c\u0c21\u0c24\u0c3e\u0c2f\u0c3f.",
+ "success": {
+ "saved": "\u0c35\u0c3f\u0c1c\u0c2f\u0c35\u0c02\u0c24\u0c02\u0c17\u0c3e \u0c38\u0c47\u0c35\u0c4d \u0c1a\u0c47\u0c2f\u0c2c\u0c21\u0c3f\u0c02\u0c26\u0c3f"
+ }
+ },
+ "alerts": {
+ "info": "Info",
+ "note": "Note",
+ "tip": "Tip",
+ "important": "Important",
+ "warning": "Warning",
+ "caution": "Caution",
+ "debug": "Debug",
+ "example": "Example",
+ "success": "Success",
+ "help": "Help",
+ "idea": "Idea",
+ "pending": "Pending",
+ "security": "Security",
+ "beta": "Beta",
+ "best-practice": "Best Practice"
+ }
+}
\ No newline at end of file
diff --git a/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/zh-CN.json b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/zh-CN.json
new file mode 100644
index 0000000..513aac4
--- /dev/null
+++ b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/zh-CN.json
@@ -0,0 +1,219 @@
+{
+ "common": {
+ "actions": {
+ "cancel": "\u53d6\u6d88",
+ "confirm": "\u786e\u8ba4",
+ "continue": "\u7ee7\u7eed",
+ "goBack": "\u8fd4\u56de",
+ "reset": "\u91cd\u7f6e",
+ "submit": "\u63d0\u4ea4"
+ },
+ "status": {
+ "loading": "\u52a0\u8f7d\u4e2d...",
+ "error": {
+ "default": "\u53d1\u751f\u9519\u8bef",
+ "serverConnection": "\u65e0\u6cd5\u8fde\u63a5\u5230\u670d\u52a1\u5668"
+ }
+ }
+ },
+ "auth": {
+ "login": {
+ "title": "\u767b\u5f55\u4ee5\u8bbf\u95ee\u5e94\u7528",
+ "form": {
+ "email": {
+ "label": "\u7535\u5b50\u90ae\u7bb1",
+ "required": "\u90ae\u7bb1\u662f\u5fc5\u586b\u9879"
+ },
+ "password": {
+ "label": "\u5bc6\u7801",
+ "required": "\u5bc6\u7801\u662f\u5fc5\u586b\u9879"
+ },
+ "actions": {
+ "signin": "\u767b\u5f55"
+ },
+ "alternativeText": {
+ "or": "\u6216"
+ }
+ },
+ "errors": {
+ "default": "\u65e0\u6cd5\u767b\u5f55",
+ "signin": "\u8bf7\u5c1d\u8bd5\u4f7f\u7528\u5176\u4ed6\u8d26\u53f7\u767b\u5f55",
+ "oauthSignin": "\u8bf7\u5c1d\u8bd5\u4f7f\u7528\u5176\u4ed6\u8d26\u53f7\u767b\u5f55",
+ "redirectUriMismatch": "\u91cd\u5b9a\u5411URI\u4e0eOAuth\u5e94\u7528\u914d\u7f6e\u4e0d\u5339\u914d",
+ "oauthCallback": "\u8bf7\u5c1d\u8bd5\u4f7f\u7528\u5176\u4ed6\u8d26\u53f7\u767b\u5f55",
+ "oauthCreateAccount": "\u8bf7\u5c1d\u8bd5\u4f7f\u7528\u5176\u4ed6\u8d26\u53f7\u767b\u5f55",
+ "emailCreateAccount": "\u8bf7\u5c1d\u8bd5\u4f7f\u7528\u5176\u4ed6\u8d26\u53f7\u767b\u5f55",
+ "callback": "\u8bf7\u5c1d\u8bd5\u4f7f\u7528\u5176\u4ed6\u8d26\u53f7\u767b\u5f55",
+ "oauthAccountNotLinked": "\u4e3a\u786e\u8ba4\u60a8\u7684\u8eab\u4efd\uff0c\u8bf7\u4f7f\u7528\u539f\u59cb\u8d26\u53f7\u767b\u5f55",
+ "emailSignin": "\u90ae\u4ef6\u53d1\u9001\u5931\u8d25",
+ "emailVerify": "\u8bf7\u9a8c\u8bc1\u60a8\u7684\u90ae\u7bb1\uff0c\u65b0\u7684\u9a8c\u8bc1\u90ae\u4ef6\u5df2\u53d1\u9001",
+ "credentialsSignin": "\u767b\u5f55\u5931\u8d25\u3002\u8bf7\u68c0\u67e5\u60a8\u63d0\u4f9b\u7684\u4fe1\u606f\u662f\u5426\u6b63\u786e",
+ "sessionRequired": "\u8bf7\u767b\u5f55\u4ee5\u8bbf\u95ee\u6b64\u9875\u9762"
+ }
+ },
+ "provider": {
+ "continue": "\u7ee7\u7eed\u4f7f\u7528{{provider}}"
+ }
+ },
+ "chat": {
+ "input": {
+ "placeholder": "\u5728\u6b64\u8f93\u5165\u60a8\u7684\u6d88\u606f...",
+ "actions": {
+ "send": "\u53d1\u9001\u6d88\u606f",
+ "stop": "\u505c\u6b62\u4efb\u52a1",
+ "attachFiles": "\u9644\u52a0\u6587\u4ef6"
+ }
+ },
+ "speech": {
+ "start": "\u5f00\u59cb\u5f55\u97f3",
+ "stop": "\u505c\u6b62\u5f55\u97f3",
+ "connecting": "\u8fde\u63a5\u4e2d"
+ },
+ "fileUpload": {
+ "dragDrop": "\u5c06\u6587\u4ef6\u62d6\u653e\u5230\u8fd9\u91cc",
+ "browse": "\u6d4f\u89c8\u6587\u4ef6",
+ "sizeLimit": "\u9650\u5236\uff1a",
+ "errors": {
+ "failed": "\u4e0a\u4f20\u5931\u8d25",
+ "cancelled": "\u5df2\u53d6\u6d88\u4e0a\u4f20"
+ }
+ },
+ "commands": {
+ "button": "\u5de5\u5177",
+ "changeTool": "\u66f4\u6362\u5de5\u5177",
+ "availableTools": "\u53ef\u7528\u5de5\u5177"
+ },
+ "messages": {
+ "status": {
+ "using": "\u4f7f\u7528\u4e2d",
+ "used": "\u5df2\u4f7f\u7528"
+ },
+ "actions": {
+ "copy": {
+ "button": "\u590d\u5236\u5230\u526a\u8d34\u677f",
+ "success": "\u5df2\u590d\u5236\uff01"
+ }
+ },
+ "feedback": {
+ "positive": "\u6709\u5e2e\u52a9",
+ "negative": "\u6ca1\u6709\u5e2e\u52a9",
+ "edit": "\u7f16\u8f91\u53cd\u9988",
+ "dialog": {
+ "title": "\u6dfb\u52a0\u8bc4\u8bba",
+ "submit": "\u63d0\u4ea4\u53cd\u9988"
+ },
+ "status": {
+ "updating": "\u66f4\u65b0\u4e2d",
+ "updated": "\u53cd\u9988\u5df2\u66f4\u65b0"
+ }
+ }
+ },
+ "history": {
+ "title": "\u6700\u8fd1\u8f93\u5165",
+ "empty": "\u7a7a\u7a7a\u5982\u4e5f...",
+ "show": "\u663e\u793a\u5386\u53f2"
+ },
+ "settings": {
+ "title": "\u8bbe\u7f6e\u9762\u677f"
+ },
+ "watermark": "\u5927\u8bed\u8a00\u6a21\u578b\u53ef\u80fd\u4f1a\u72af\u9519\u3002\u8bf7\u6838\u5b9e\u91cd\u8981\u4fe1\u606f\u3002"
+ },
+ "threadHistory": {
+ "sidebar": {
+ "title": "\u5386\u53f2\u5bf9\u8bdd",
+ "filters": {
+ "search": "\u641c\u7d22",
+ "placeholder": "\u641c\u7d22\u4f1a\u8bdd..."
+ },
+ "timeframes": {
+ "today": "\u4eca\u5929",
+ "yesterday": "\u6628\u5929",
+ "previous7days": "\u8fc7\u53bb7\u5929",
+ "previous30days": "\u8fc7\u53bb30\u5929"
+ },
+ "empty": "\u672a\u627e\u5230\u5bf9\u8bdd",
+ "actions": {
+ "close": "\u5173\u95ed\u4fa7\u8fb9\u680f",
+ "open": "\u6253\u5f00\u4fa7\u8fb9\u680f"
+ }
+ },
+ "thread": {
+ "untitled": "\u672a\u547d\u540d\u5bf9\u8bdd",
+ "menu": {
+ "rename": "\u91cd\u547d\u540d",
+ "delete": "\u5220\u9664"
+ },
+ "actions": {
+ "delete": {
+ "title": "\u786e\u8ba4\u5220\u9664",
+ "description": "\u8fd9\u5c06\u5220\u9664\u8be5\u5bf9\u8bdd\u53ca\u5176\u6240\u6709\u6d88\u606f\u548c\u5143\u7d20\u3002\u6b64\u64cd\u4f5c\u65e0\u6cd5\u64a4\u9500",
+ "success": "\u5bf9\u8bdd\u5df2\u5220\u9664",
+ "inProgress": "\u6b63\u5728\u5220\u9664\u5bf9\u8bdd"
+ },
+ "rename": {
+ "title": "\u91cd\u547d\u540d\u5bf9\u8bdd",
+ "description": "\u4e3a\u6b64\u5bf9\u8bdd\u8f93\u5165\u65b0\u540d\u79f0",
+ "form": {
+ "name": {
+ "label": "\u540d\u79f0",
+ "placeholder": "\u8f93\u5165\u65b0\u540d\u79f0"
+ }
+ },
+ "success": "\u5bf9\u8bdd\u5df2\u91cd\u547d\u540d\uff01",
+ "inProgress": "\u6b63\u5728\u91cd\u547d\u540d\u5bf9\u8bdd"
+ }
+ }
+ }
+ },
+ "navigation": {
+ "header": {
+ "chat": "\u804a\u5929",
+ "readme": "\u8bf4\u660e",
+ "theme": {
+ "light": "\u6d45\u8272\u4e3b\u9898",
+ "dark": "\u6df1\u8272\u4e3b\u9898",
+ "system": "\u8ddf\u968f\u7cfb\u7edf"
+ }
+ },
+ "newChat": {
+ "button": "\u65b0\u5efa\u5bf9\u8bdd",
+ "dialog": {
+ "title": "\u521b\u5efa\u65b0\u5bf9\u8bdd",
+ "description": "\u8fd9\u5c06\u6e05\u9664\u60a8\u5f53\u524d\u7684\u804a\u5929\u8bb0\u5f55\u3002\u786e\u5b9a\u8981\u7ee7\u7eed\u5417\uff1f",
+ "tooltip": "\u65b0\u5efa\u5bf9\u8bdd"
+ }
+ },
+ "user": {
+ "menu": {
+ "settings": "\u8bbe\u7f6e",
+ "settingsKey": "S",
+ "apiKeys": "API\u5bc6\u94a5",
+ "logout": "\u9000\u51fa\u767b\u5f55"
+ }
+ }
+ },
+ "apiKeys": {
+ "title": "\u6240\u9700API\u5bc6\u94a5",
+ "description": "\u4f7f\u7528\u6b64\u5e94\u7528\u9700\u8981\u4ee5\u4e0bAPI\u5bc6\u94a5\u3002\u8fd9\u4e9b\u5bc6\u94a5\u5b58\u50a8\u5728\u60a8\u8bbe\u5907\u7684\u672c\u5730\u5b58\u50a8\u4e2d\u3002",
+ "success": {
+ "saved": "\u4fdd\u5b58\u6210\u529f"
+ }
+ },
+ "alerts": {
+ "info": "\u4fe1\u606f",
+ "note": "\u6ce8\u91ca",
+ "tip": "\u63d0\u793a",
+ "important": "\u91cd\u8981",
+ "warning": "\u8b66\u544a",
+ "caution": "\u6ce8\u610f",
+ "debug": "\u8c03\u8bd5",
+ "example": "\u793a\u4f8b",
+ "success": "\u6210\u529f",
+ "help": "\u5e2e\u52a9",
+ "idea": "\u60f3\u6cd5",
+ "pending": "\u5f85\u5904\u7406",
+ "security": "\u5b89\u5168",
+ "beta": "\u6d4b\u8bd5",
+ "best-practice": "\u6700\u4f73\u5b9e\u8df5"
+ }
+}
\ No newline at end of file
diff --git a/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/zh-TW.json b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/zh-TW.json
new file mode 100644
index 0000000..90d4250
--- /dev/null
+++ b/ch05/11_qwen3/qwen3-chat-interface/.chainlit/translations/zh-TW.json
@@ -0,0 +1,219 @@
+{
+ "common": {
+ "actions": {
+ "cancel": "\u53d6\u6d88",
+ "confirm": "\u78ba\u8a8d",
+ "continue": "\u7e7c\u7e8c",
+ "goBack": "\u8fd4\u56de",
+ "reset": "\u91cd\u8a2d",
+ "submit": "\u9001\u51fa"
+ },
+ "status": {
+ "loading": "\u8f09\u5165\u4e2d...",
+ "error": {
+ "default": "\u767c\u751f\u932f\u8aa4",
+ "serverConnection": "\u7121\u6cd5\u9023\u7dda\u5230\u4f3a\u670d\u5668"
+ }
+ }
+ },
+ "auth": {
+ "login": {
+ "title": "\u767b\u5165\u4ee5\u5b58\u53d6\u61c9\u7528\u7a0b\u5f0f",
+ "form": {
+ "email": {
+ "label": "\u96fb\u5b50\u4fe1\u7bb1",
+ "required": "\u4fe1\u7bb1\u662f\u5fc5\u586b\u9805\u76ee"
+ },
+ "password": {
+ "label": "\u5bc6\u78bc",
+ "required": "\u5bc6\u78bc\u662f\u5fc5\u586b\u9805\u76ee"
+ },
+ "actions": {
+ "signin": "\u767b\u5165"
+ },
+ "alternativeText": {
+ "or": "\u6216"
+ }
+ },
+ "errors": {
+ "default": "\u7121\u6cd5\u767b\u5165",
+ "signin": "\u8acb\u5617\u8a66\u4f7f\u7528\u5176\u5b83\u5e33\u865f\u767b\u5165",
+ "oauthSignin": "\u8acb\u5617\u8a66\u4f7f\u7528\u5176\u5b83\u5e33\u865f\u767b\u5165",
+ "redirectUriMismatch": "\u91cd\u65b0\u5c0e\u5411URI\u8207OAuth App\u8a2d\u5b9a\u4e0d\u76f8\u7b26",
+ "oauthCallback": "\u8acb\u5617\u8a66\u4f7f\u7528\u5176\u5b83\u5e33\u865f\u767b\u5165",
+ "oauthCreateAccount": "\u8acb\u5617\u8a66\u4f7f\u7528\u5176\u5b83\u5e33\u865f\u767b\u5165",
+ "emailCreateAccount": "\u8acb\u5617\u8a66\u4f7f\u7528\u5176\u5b83\u5e33\u865f\u767b\u5165",
+ "callback": "\u8acb\u5617\u8a66\u4f7f\u7528\u5176\u5b83\u5e33\u865f\u767b\u5165",
+ "oauthAccountNotLinked": "\u70ba\u78ba\u8a8d\u60a8\u7684\u8eab\u4efd\uff0c\u8acb\u4ee5\u539f\u672c\u4f7f\u7528\u7684\u5e33\u865f\u767b\u5165",
+ "emailSignin": "\u96fb\u5b50\u90f5\u4ef6\u767c\u9001\u5931\u6557",
+ "emailVerify": "\u8acb\u9a57\u8b49\u60a8\u7684\u96fb\u5b50\u4fe1\u7bb1\uff0c\u65b0\u7684\u9a57\u8b49\u90f5\u4ef6\u5df2\u767c\u9001",
+ "credentialsSignin": "\u767b\u5165\u5931\u6557\u3002\u8acb\u6aa2\u67e5\u60a8\u63d0\u4f9b\u7684\u8cc7\u8a0a\u662f\u5426\u6b63\u78ba",
+ "sessionRequired": "\u8acb\u767b\u5165\u4ee5\u5b58\u53d6\u6b64\u9801\u9762"
+ }
+ },
+ "provider": {
+ "continue": "\u7e7c\u7e8c\u4f7f\u7528{{provider}}"
+ }
+ },
+ "chat": {
+ "input": {
+ "placeholder": "\u5728\u6b64\u8f38\u5165\u60a8\u7684\u8a0a\u606f...",
+ "actions": {
+ "send": "\u767c\u9001\u8a0a\u606f",
+ "stop": "\u505c\u6b62\u4efb\u52d9",
+ "attachFiles": "\u9644\u52a0\u6a94\u6848"
+ }
+ },
+ "speech": {
+ "start": "\u958b\u59cb\u9304\u97f3",
+ "stop": "\u505c\u6b62\u9304\u97f3",
+ "connecting": "\u9023\u7dda\u4e2d"
+ },
+ "fileUpload": {
+ "dragDrop": "\u62d6\u66f3\u6a94\u6848\u5230\u9019\u88e1",
+ "browse": "\u700f\u89bd\u6a94\u6848",
+ "sizeLimit": "\u9650\u5236\uff1a",
+ "errors": {
+ "failed": "\u4e0a\u50b3\u5931\u6557",
+ "cancelled": "\u5df2\u53d6\u6d88\u4e0a\u50b3"
+ }
+ },
+ "commands": {
+ "button": "\u5de5\u5177",
+ "changeTool": "\u66f4\u63db\u5de5\u5177",
+ "availableTools": "\u53ef\u7528\u5de5\u5177"
+ },
+ "messages": {
+ "status": {
+ "using": "\u6b63\u5728\u4f7f\u7528",
+ "used": "\u5df2\u4f7f\u7528"
+ },
+ "actions": {
+ "copy": {
+ "button": "\u8907\u88fd\u5230\u526a\u8cbc\u7c3f",
+ "success": "\u5df2\u8907\u88fd\uff01"
+ }
+ },
+ "feedback": {
+ "positive": "\u6709\u5e6b\u52a9",
+ "negative": "\u6c92\u6709\u5e6b\u52a9",
+ "edit": "\u7de8\u8f2f\u56de\u994b",
+ "dialog": {
+ "title": "\u65b0\u589e\u8a55\u8ad6",
+ "submit": "\u9001\u51fa\u56de\u994b"
+ },
+ "status": {
+ "updating": "\u66f4\u65b0\u4e2d",
+ "updated": "\u56de\u994b\u5df2\u66f4\u65b0"
+ }
+ }
+ },
+ "history": {
+ "title": "\u6700\u8fd1\u8f38\u5165",
+ "empty": "\u7a7a\u7a7a\u5982\u4e5f...",
+ "show": "\u986f\u793a\u6b77\u53f2"
+ },
+ "settings": {
+ "title": "\u8a2d\u5b9a\u9762\u677f"
+ },
+ "watermark": "\u5927\u578b\u8a9e\u8a00\u6a21\u578b\u53ef\u80fd\u6703\u72af\u932f\u3002\u8acb\u6838\u5be6\u91cd\u8981\u8cc7\u8a0a\u3002"
+ },
+ "threadHistory": {
+ "sidebar": {
+ "title": "\u6b77\u53f2\u5c0d\u8a71",
+ "filters": {
+ "search": "\u641c\u5c0b",
+ "placeholder": "\u641c\u5c0b\u5c0d\u8a71..."
+ },
+ "timeframes": {
+ "today": "\u4eca\u5929",
+ "yesterday": "\u6628\u5929",
+ "previous7days": "\u904e\u53bb7\u5929",
+ "previous30days": "\u904e\u53bb30\u5929"
+ },
+ "empty": "\u672a\u627e\u5230\u5c0d\u8a71",
+ "actions": {
+ "close": "\u95dc\u9589\u5074\u908a\u6b04",
+ "open": "\u6253\u958b\u5074\u908a\u6b04"
+ }
+ },
+ "thread": {
+ "untitled": "\u672a\u547d\u540d\u5c0d\u8a71",
+ "menu": {
+ "rename": "\u91cd\u65b0\u547d\u540d",
+ "delete": "\u522a\u9664"
+ },
+ "actions": {
+ "delete": {
+ "title": "\u78ba\u8a8d\u522a\u9664",
+ "description": "\u9019\u5c07\u522a\u9664\u8a72\u5c0d\u8a71\u53ca\u5176\u6240\u6709\u8a0a\u606f\u548c\u5143\u4ef6\u3002\u6b64\u64cd\u4f5c\u7121\u6cd5\u5fa9\u539f\u3002",
+ "success": "\u5c0d\u8a71\u5df2\u522a\u9664",
+ "inProgress": "\u6b63\u5728\u522a\u9664\u5c0d\u8a71"
+ },
+ "rename": {
+ "title": "\u91cd\u65b0\u547d\u540d\u5c0d\u8a71",
+ "description": "\u70ba\u6b64\u5c0d\u8a71\u8f38\u5165\u65b0\u540d\u7a31",
+ "form": {
+ "name": {
+ "label": "\u540d\u7a31",
+ "placeholder": "\u8f38\u5165\u65b0\u540d\u7a31"
+ }
+ },
+ "success": "\u5c0d\u8a71\u5df2\u91cd\u65b0\u547d\u540d\uff01",
+ "inProgress": "\u6b63\u5728\u91cd\u65b0\u547d\u540d\u5c0d\u8a71"
+ }
+ }
+ }
+ },
+ "navigation": {
+ "header": {
+ "chat": "\u804a\u5929",
+ "readme": "\u8aaa\u660e",
+ "theme": {
+ "light": "\u6dfa\u8272\u4e3b\u984c",
+ "dark": "\u6df1\u8272\u4e3b\u984c",
+ "system": "\u8ddf\u96a8\u7cfb\u7d71"
+ }
+ },
+ "newChat": {
+ "button": "\u65b0\u5efa\u5c0d\u8a71",
+ "dialog": {
+ "title": "\u5275\u5efa\u65b0\u5c0d\u8a71",
+ "description": "\u9019\u5c07\u6e05\u9664\u60a8\u7576\u524d\u7684\u804a\u5929\u8a18\u9304\u3002\u78ba\u5b9a\u8981\u7e7c\u7e8c\u55ce\uff1f",
+ "tooltip": "\u65b0\u5efa\u5c0d\u8a71"
+ }
+ },
+ "user": {
+ "menu": {
+ "settings": "\u8a2d\u5b9a",
+ "settingsKey": "S",
+ "apiKeys": "API\u91d1\u9470",
+ "logout": "\u767b\u51fa"
+ }
+ }
+ },
+ "apiKeys": {
+ "title": "\u6240\u9700API\u91d1\u9470",
+ "description": "\u4f7f\u7528\u6b64\u61c9\u7528\u7a0b\u5f0f\u9700\u8981\u4ee5\u4e0bAPI\u91d1\u9470\u3002\u9019\u4e9b\u91d1\u9470\u5132\u5b58\u5728\u60a8\u8a2d\u5099\u7684\u672c\u5730\u5132\u5b58\u7a7a\u9593\u4e2d\u3002",
+ "success": {
+ "saved": "\u5132\u5b58\u6210\u529f"
+ }
+ },
+ "alerts": {
+ "info": "\u8cc7\u8a0a",
+ "note": "\u6ce8\u91cb",
+ "tip": "\u63d0\u793a",
+ "important": "\u91cd\u8981",
+ "warning": "\u8b66\u544a",
+ "caution": "\u6ce8\u610f",
+ "debug": "\u9664\u932f",
+ "example": "\u7bc4\u4f8b",
+ "success": "\u6210\u529f",
+ "help": "\u5e6b\u52a9",
+ "idea": "\u60f3\u6cd5",
+ "pending": "\u5f85\u8655\u7406",
+ "security": "\u5b89\u5168",
+ "beta": "\u6e2c\u8a66",
+ "best-practice": "\u6700\u4f73\u5be6\u8e10"
+ }
+}
\ No newline at end of file
diff --git a/ch05/11_qwen3/qwen3-chat-interface/README.md b/ch05/11_qwen3/qwen3-chat-interface/README.md
new file mode 100644
index 0000000..cc840dc
--- /dev/null
+++ b/ch05/11_qwen3/qwen3-chat-interface/README.md
@@ -0,0 +1,55 @@
+# Qwen3 From Scratch with Chat Interface
+
+
+
+This bonus folder contains code for running a ChatGPT-like user interface to interact with the pretrained LLMs from chapter 5, as shown below.
+
+
+
+
+
+
+
+To implement this user interface, we use the open-source [Chainlit Python package](https://github.com/Chainlit/chainlit).
+
+
+## Step 1: Install dependencies
+
+First, we install the `chainlit` package and dependencies from the [requirements-extra.txt](requirements-extra.txt) list via
+
+```bash
+pip install install -r requirements-extra.txt
+```
+
+Or, if you are using `uv`:
+
+```bash
+uv pip install install -r requirements-extra.txt
+```
+
+
+
+
+
+## Step 2: Run `app` code
+
+This folder contains 2 files:
+
+1. [`qwen3-chat-interface.py`](qwen3-chat-interface.py): This file loads and uses the Qwen3 0.6B model in thinking mode.
+2. [`qwen3-chat-interface-multiturn.py`](qwen3-chat-interface-multiturn.py): The same as above, but configured to remember the message history.
+
+(Open and inspect these files to learn more.)
+
+Run one of the following commands from the terminal to start the UI server:
+
+```bash
+chainlit run qwen3-chat-interface.py
+```
+
+or, if you are using `uv`:
+
+```bash
+uv run chainlit run qwen3-chat-interface.py
+```
+
+Running one of the commands above should open a new browser tab where you can interact with the model. If the browser tab does not open automatically, inspect the terminal command and copy the local address into your browser address bar (usually, the address is `http://localhost:8000`).
\ No newline at end of file
diff --git a/ch05/11_qwen3/qwen3-chat-interface/public/logo_dark.webp b/ch05/11_qwen3/qwen3-chat-interface/public/logo_dark.webp
new file mode 100644
index 0000000..fbfc655
Binary files /dev/null and b/ch05/11_qwen3/qwen3-chat-interface/public/logo_dark.webp differ
diff --git a/ch05/11_qwen3/qwen3-chat-interface/public/logo_light.webp b/ch05/11_qwen3/qwen3-chat-interface/public/logo_light.webp
new file mode 100644
index 0000000..c7eb29a
Binary files /dev/null and b/ch05/11_qwen3/qwen3-chat-interface/public/logo_light.webp differ
diff --git a/ch05/11_qwen3/qwen3-chat-interface/qwen3-chat-interface-multiturn.py b/ch05/11_qwen3/qwen3-chat-interface/qwen3-chat-interface-multiturn.py
new file mode 100644
index 0000000..064e970
--- /dev/null
+++ b/ch05/11_qwen3/qwen3-chat-interface/qwen3-chat-interface-multiturn.py
@@ -0,0 +1,169 @@
+# Copyright (c) Sebastian Raschka under Apache License 2.0 (see LICENSE.txt).
+# Source for "Build a Large Language Model From Scratch"
+# - https://www.manning.com/books/build-a-large-language-model-from-scratch
+# Code: https://github.com/rasbt/LLMs-from-scratch
+
+import torch
+import chainlit
+
+# For llms_from_scratch installation instructions, see:
+# https://github.com/rasbt/LLMs-from-scratch/tree/main/pkg
+from llms_from_scratch.kv_cache.qwen3 import (
+ Qwen3Model,
+ Qwen3Tokenizer,
+ download_from_huggingface_from_snapshots,
+ load_weights_into_qwen
+)
+from llms_from_scratch.kv_cache.generate import (
+ generate_text_simple_stream
+)
+
+# ============================================================
+# EDIT ME: Simple configuration
+# ============================================================
+MODEL = "0.6B" # options: "0.6B","1.7B","4B","8B","14B","32B","30B-A3B"
+REASONING = True # True = "thinking" chat model, False = Base
+DEVICE = "auto" # "auto" | "cuda" | "mps" | "cpu"
+MAX_NEW_TOKENS = 38912
+LOCAL_DIR = None # e.g., "Qwen3-0.6B-Base"; None auto-selects
+# ============================================================
+
+
+def get_qwen_config(name):
+ if name == "0.6B":
+ from llms_from_scratch.qwen3 import QWEN_CONFIG_06_B as QWEN3_CONFIG
+ elif name == "1.7B":
+ from llms_from_scratch.qwen3 import QWEN3_CONFIG_1_7B as QWEN3_CONFIG
+ elif name == "4B":
+ from llms_from_scratch.qwen3 import QWEN3_CONFIG_4B as QWEN3_CONFIG
+ elif name == "8B":
+ from llms_from_scratch.qwen3 import QWEN3_CONFIG_8B as QWEN3_CONFIG
+ elif name == "14B":
+ from llms_from_scratch.qwen3 import QWEN3_CONFIG_14B as QWEN3_CONFIG
+ elif name == "32B":
+ from llms_from_scratch.qwen3 import QWEN3_CONFIG_32B as QWEN3_CONFIG
+ elif name == "30B-A3B":
+ from llms_from_scratch.qwen3 import QWEN3_CONFIG_30B_A3B as QWEN3_CONFIG
+ else:
+ raise ValueError(f"Invalid model name: {name}")
+ return QWEN3_CONFIG
+
+
+def build_repo_and_local(model_name, reasoning, local_dir_arg):
+ base = f"Qwen3-{model_name}"
+ repo_id = f"Qwen/{base}-Base" if not reasoning else f"Qwen/{base}"
+ local_dir = local_dir_arg if local_dir_arg else (f"{base}-Base" if not reasoning else base)
+ return repo_id, local_dir
+
+
+def get_device(name):
+ if name == "auto":
+ if torch.cuda.is_available():
+ return torch.device("cuda")
+ elif torch.backends.mps.is_available():
+ return torch.device("mps")
+ else:
+ return torch.device("cpu")
+ elif name == "cuda":
+ return torch.device("cuda")
+ elif name == "mps":
+ return torch.device("mps")
+ else:
+ return torch.device("cpu")
+
+
+def get_model_and_tokenizer(qwen3_config, repo_id, local_dir, device, use_reasoning):
+ model = Qwen3Model(qwen3_config)
+ weights_dict = download_from_huggingface_from_snapshots(
+ repo_id=repo_id,
+ local_dir=local_dir
+ )
+ load_weights_into_qwen(model, qwen3_config, weights_dict)
+ del weights_dict
+
+ model.to(device) # safe for all but required by the MoE model
+ model.eval()
+
+ tok_filename = "tokenizer.json"
+ tokenizer = Qwen3Tokenizer(
+ tokenizer_file_path=tok_filename,
+ repo_id=repo_id,
+ apply_chat_template=False, # disable to avoid double-wrapping prompts in history
+ add_generation_prompt=False, # we add the assistant header manually
+ add_thinking=use_reasoning
+ )
+ return model, tokenizer
+
+
+def build_prompt_from_history(history, add_assistant_header=True):
+ """
+ history: [{"role": "system"|"user"|"assistant", "content": str}, ...]
+ """
+ parts = []
+ for m in history:
+ role = m["role"]
+ content = m["content"]
+ parts.append(f"<|im_start|>{role}\n{content}<|im_end|>\n")
+
+ if add_assistant_header:
+ parts.append("<|im_start|>assistant\n")
+ return "".join(parts)
+
+
+QWEN3_CONFIG = get_qwen_config(MODEL)
+REPO_ID, LOCAL_DIR = build_repo_and_local(MODEL, REASONING, LOCAL_DIR)
+DEVICE = get_device(DEVICE)
+MODEL, TOKENIZER = get_model_and_tokenizer(QWEN3_CONFIG, REPO_ID, LOCAL_DIR, DEVICE, REASONING)
+
+
+@chainlit.on_chat_start
+async def on_start():
+ chainlit.user_session.set("history", [])
+ chainlit.user_session.get("history").append(
+ {"role": "system", "content": "You are a helpful assistant."}
+ )
+
+
+@chainlit.on_message
+async def main(message: chainlit.Message):
+ """
+ The main Chainlit function.
+ """
+ # 0) Get and track chat history
+ history = chainlit.user_session.get("history")
+ history.append({"role": "user", "content": message.content})
+
+ # 1) Encode input
+ prompt = build_prompt_from_history(history, add_assistant_header=True)
+ input_ids = TOKENIZER.encode(prompt)
+ input_ids_tensor = torch.tensor(input_ids, device=DEVICE).unsqueeze(0)
+
+ # 2) Start an outgoing message we can stream into
+ out_msg = chainlit.Message(content="")
+ await out_msg.send()
+
+ # 3) Stream generation
+ with torch.no_grad():
+ for tok in generate_text_simple_stream(
+ model=MODEL,
+ token_ids=input_ids_tensor,
+ max_new_tokens=MAX_NEW_TOKENS,
+ # eos_token_id=TOKENIZER.eos_token_id
+ ):
+ # Normalize token to int
+ if torch.is_tensor(tok):
+ tok = int(tok.view(-1)[0].item())
+ else:
+ tok = int(tok)
+
+ piece = TOKENIZER.decode([tok])
+ if piece in ("<|endoftext|>", "<|im_end|>"):
+ break
+ await out_msg.stream_token(piece)
+
+ # 4) Finalize the streamed message
+ await out_msg.update()
+
+ # 5) Update chat history
+ history.append({"role": "assistant", "content": out_msg.content})
+ chainlit.user_session.set("history", history)
diff --git a/ch05/11_qwen3/qwen3-chat-interface/qwen3-chat-interface.py b/ch05/11_qwen3/qwen3-chat-interface/qwen3-chat-interface.py
new file mode 100644
index 0000000..2eac62b
--- /dev/null
+++ b/ch05/11_qwen3/qwen3-chat-interface/qwen3-chat-interface.py
@@ -0,0 +1,145 @@
+# Copyright (c) Sebastian Raschka under Apache License 2.0 (see LICENSE.txt).
+# Source for "Build a Large Language Model From Scratch"
+# - https://www.manning.com/books/build-a-large-language-model-from-scratch
+# Code: https://github.com/rasbt/LLMs-from-scratch
+
+import torch
+import chainlit
+
+# For llms_from_scratch installation instructions, see:
+# https://github.com/rasbt/LLMs-from-scratch/tree/main/pkg
+from llms_from_scratch.kv_cache.qwen3 import (
+ Qwen3Model,
+ Qwen3Tokenizer,
+ download_from_huggingface_from_snapshots,
+ load_weights_into_qwen
+)
+from llms_from_scratch.kv_cache.generate import (
+ generate_text_simple_stream
+)
+
+# ============================================================
+# EDIT ME: Simple configuration
+# ============================================================
+MODEL = "0.6B" # options: "0.6B","1.7B","4B","8B","14B","32B","30B-A3B"
+REASONING = True # True = "thinking" chat model, False = Base
+DEVICE = "auto" # "auto" | "cuda" | "mps" | "cpu"
+MAX_NEW_TOKENS = 38912
+LOCAL_DIR = None # e.g., "Qwen3-0.6B-Base"; None auto-selects
+# ============================================================
+
+
+def get_qwen_config(name):
+ if name == "0.6B":
+ from llms_from_scratch.qwen3 import QWEN_CONFIG_06_B as QWEN3_CONFIG
+ elif name == "1.7B":
+ from llms_from_scratch.qwen3 import QWEN3_CONFIG_1_7B as QWEN3_CONFIG
+ elif name == "4B":
+ from llms_from_scratch.qwen3 import QWEN3_CONFIG_4B as QWEN3_CONFIG
+ elif name == "8B":
+ from llms_from_scratch.qwen3 import QWEN3_CONFIG_8B as QWEN3_CONFIG
+ elif name == "14B":
+ from llms_from_scratch.qwen3 import QWEN3_CONFIG_14B as QWEN3_CONFIG
+ elif name == "32B":
+ from llms_from_scratch.qwen3 import QWEN3_CONFIG_32B as QWEN3_CONFIG
+ elif name == "30B-A3B":
+ from llms_from_scratch.qwen3 import QWEN3_CONFIG_30B_A3B as QWEN3_CONFIG
+ else:
+ raise ValueError(f"Invalid model name: {name}")
+ return QWEN3_CONFIG
+
+
+def build_repo_and_local(model_name, reasoning, local_dir_arg):
+ base = f"Qwen3-{model_name}"
+ repo_id = f"Qwen/{base}-Base" if not reasoning else f"Qwen/{base}"
+ local_dir = local_dir_arg if local_dir_arg else (f"{base}-Base" if not reasoning else base)
+ return repo_id, local_dir
+
+
+def get_device(name):
+ if name == "auto":
+ if torch.cuda.is_available():
+ return torch.device("cuda")
+ elif torch.backends.mps.is_available():
+ return torch.device("mps")
+ else:
+ return torch.device("cpu")
+ elif name == "cuda":
+ return torch.device("cuda")
+ elif name == "mps":
+ return torch.device("mps")
+ else:
+ return torch.device("cpu")
+
+
+def get_model_and_tokenizer(qwen3_config, repo_id, local_dir, device, use_reasoning):
+ model = Qwen3Model(qwen3_config)
+ weights_dict = download_from_huggingface_from_snapshots(
+ repo_id=repo_id,
+ local_dir=local_dir
+ )
+ load_weights_into_qwen(model, qwen3_config, weights_dict)
+ del weights_dict
+
+ model.to(device) # safe for all but required by the MoE model
+ model.eval()
+
+ tok_filename = "tokenizer.json"
+ tokenizer = Qwen3Tokenizer(
+ tokenizer_file_path=tok_filename,
+ repo_id=repo_id,
+ apply_chat_template=use_reasoning,
+ add_generation_prompt=use_reasoning,
+ add_thinking=use_reasoning
+ )
+ return model, tokenizer
+
+
+QWEN3_CONFIG = get_qwen_config(MODEL)
+REPO_ID, LOCAL_DIR = build_repo_and_local(MODEL, REASONING, LOCAL_DIR)
+DEVICE = get_device(DEVICE)
+MODEL, TOKENIZER = get_model_and_tokenizer(QWEN3_CONFIG, REPO_ID, LOCAL_DIR, DEVICE, REASONING)
+
+
+@chainlit.on_chat_start
+async def on_start():
+ chainlit.user_session.set("history", [])
+ chainlit.user_session.get("history").append(
+ {"role": "system", "content": "You are a helpful assistant."}
+ )
+
+
+@chainlit.on_message
+async def main(message: chainlit.Message):
+ """
+ The main Chainlit function.
+ """
+ # 1) Encode input
+ input_ids = TOKENIZER.encode(message.content)
+ input_ids_tensor = torch.tensor(input_ids, device=DEVICE).unsqueeze(0)
+
+ # 2) Start an outgoing message we can stream into
+ out_msg = chainlit.Message(content="")
+ await out_msg.send()
+
+ # 3) Stream generation
+ with torch.no_grad():
+ for tok in generate_text_simple_stream(
+ model=MODEL,
+ token_ids=input_ids_tensor,
+ max_new_tokens=MAX_NEW_TOKENS,
+ ):
+ # Normalize token to int
+ if torch.is_tensor(tok):
+ tok = int(tok.view(-1)[0].item())
+ else:
+ tok = int(tok)
+
+ piece = TOKENIZER.decode([tok])
+ if piece in ("<|endoftext|>", "<|im_end|>"):
+ break
+
+ await out_msg.stream_token(piece)
+
+ # 4) Finalize the streamed message
+ await out_msg.update()
diff --git a/ch05/11_qwen3/qwen3-chat-interface/requirements-extra.txt b/ch05/11_qwen3/qwen3-chat-interface/requirements-extra.txt
new file mode 100644
index 0000000..e30c39b
--- /dev/null
+++ b/ch05/11_qwen3/qwen3-chat-interface/requirements-extra.txt
@@ -0,0 +1,5 @@
+chainlit>=1.2.0
+huggingface_hub>=0.34.4
+llms_from_scratch>=1.0.18 # to import code from this repo
+safetensors>=0.6.2
+tokenizers>=0.21.1
\ No newline at end of file
diff --git a/ch05/11_qwen3/standalone-qwen3-moe-plus-kvcache.ipynb b/ch05/11_qwen3/standalone-qwen3-moe-plus-kvcache.ipynb
index fc11c0f..6323253 100644
--- a/ch05/11_qwen3/standalone-qwen3-moe-plus-kvcache.ipynb
+++ b/ch05/11_qwen3/standalone-qwen3-moe-plus-kvcache.ipynb
@@ -977,7 +977,6 @@
"import re\n",
"from tokenizers import Tokenizer\n",
"\n",
- "\n",
"class Qwen3Tokenizer:\n",
" _SPECIALS = [\n",
" \"<|endoftext|>\",\n",
@@ -987,8 +986,9 @@
" \"<|quad_start|>\", \"<|quad_end|>\",\n",
" \"<|vision_start|>\", \"<|vision_end|>\",\n",
" \"<|vision_pad|>\", \"<|image_pad|>\", \"<|video_pad|>\",\n",
+ " \"\", \"\"\n",
" ]\n",
- " _SPLIT_RE = re.compile(r\"(<\\|[^>]+?\\|>)\")\n",
+ " _SPLIT_RE = re.compile(r\"(<\\|[^>]+?\\|>||)\")\n",
"\n",
" def __init__(self, tokenizer_file_path=\"tokenizer.json\", repo_id=None,\n",
" apply_chat_template=True, add_generation_prompt=False, add_thinking=False):\n",
@@ -999,9 +999,13 @@
"\n",
" tok_file = Path(tokenizer_file_path)\n",
" self._tok = Tokenizer.from_file(str(tok_file))\n",
- " self._special_to_id = {t: self._tok.token_to_id(t) for t in self._SPECIALS}\n",
+ " self._special_to_id = {}\n",
+ " for t in self._SPECIALS:\n",
+ " tid = self._tok.token_to_id(t)\n",
+ " if tid is not None:\n",
+ " self._special_to_id[t] = tid\n",
"\n",
- " self.pad_token_id = self._special_to_id.get(\"<|endoftext|>\")\n",
+ " self.pad_token_id = self._special_to_id[\"<|endoftext|>\"]\n",
" self.eos_token_id = self.pad_token_id\n",
"\n",
" if repo_id and \"Base\" not in repo_id:\n",
diff --git a/ch05/11_qwen3/standalone-qwen3-moe.ipynb b/ch05/11_qwen3/standalone-qwen3-moe.ipynb
index 76a66fc..69f1e8e 100644
--- a/ch05/11_qwen3/standalone-qwen3-moe.ipynb
+++ b/ch05/11_qwen3/standalone-qwen3-moe.ipynb
@@ -917,7 +917,6 @@
"import re\n",
"from tokenizers import Tokenizer\n",
"\n",
- "\n",
"class Qwen3Tokenizer:\n",
" _SPECIALS = [\n",
" \"<|endoftext|>\",\n",
@@ -927,8 +926,9 @@
" \"<|quad_start|>\", \"<|quad_end|>\",\n",
" \"<|vision_start|>\", \"<|vision_end|>\",\n",
" \"<|vision_pad|>\", \"<|image_pad|>\", \"<|video_pad|>\",\n",
+ " \"\", \"\"\n",
" ]\n",
- " _SPLIT_RE = re.compile(r\"(<\\|[^>]+?\\|>)\")\n",
+ " _SPLIT_RE = re.compile(r\"(<\\|[^>]+?\\|>||)\")\n",
"\n",
" def __init__(self, tokenizer_file_path=\"tokenizer.json\", repo_id=None,\n",
" apply_chat_template=True, add_generation_prompt=False, add_thinking=False):\n",
@@ -939,9 +939,13 @@
"\n",
" tok_file = Path(tokenizer_file_path)\n",
" self._tok = Tokenizer.from_file(str(tok_file))\n",
- " self._special_to_id = {t: self._tok.token_to_id(t) for t in self._SPECIALS}\n",
+ " self._special_to_id = {}\n",
+ " for t in self._SPECIALS:\n",
+ " tid = self._tok.token_to_id(t)\n",
+ " if tid is not None:\n",
+ " self._special_to_id[t] = tid\n",
"\n",
- " self.pad_token_id = self._special_to_id.get(\"<|endoftext|>\")\n",
+ " self.pad_token_id = self._special_to_id[\"<|endoftext|>\"]\n",
" self.eos_token_id = self.pad_token_id\n",
"\n",
" if repo_id and \"Base\" not in repo_id:\n",
diff --git a/ch05/11_qwen3/standalone-qwen3-plus-kvcache.ipynb b/ch05/11_qwen3/standalone-qwen3-plus-kvcache.ipynb
index a2a889a..9b0f987 100644
--- a/ch05/11_qwen3/standalone-qwen3-plus-kvcache.ipynb
+++ b/ch05/11_qwen3/standalone-qwen3-plus-kvcache.ipynb
@@ -964,7 +964,6 @@
"import re\n",
"from tokenizers import Tokenizer\n",
"\n",
- "\n",
"class Qwen3Tokenizer:\n",
" _SPECIALS = [\n",
" \"<|endoftext|>\",\n",
@@ -974,8 +973,9 @@
" \"<|quad_start|>\", \"<|quad_end|>\",\n",
" \"<|vision_start|>\", \"<|vision_end|>\",\n",
" \"<|vision_pad|>\", \"<|image_pad|>\", \"<|video_pad|>\",\n",
+ " \"\", \"\"\n",
" ]\n",
- " _SPLIT_RE = re.compile(r\"(<\\|[^>]+?\\|>)\")\n",
+ " _SPLIT_RE = re.compile(r\"(<\\|[^>]+?\\|>||)\")\n",
"\n",
" def __init__(self, tokenizer_file_path=\"tokenizer.json\", repo_id=None,\n",
" apply_chat_template=True, add_generation_prompt=False, add_thinking=False):\n",
@@ -986,9 +986,13 @@
"\n",
" tok_file = Path(tokenizer_file_path)\n",
" self._tok = Tokenizer.from_file(str(tok_file))\n",
- " self._special_to_id = {t: self._tok.token_to_id(t) for t in self._SPECIALS}\n",
+ " self._special_to_id = {}\n",
+ " for t in self._SPECIALS:\n",
+ " tid = self._tok.token_to_id(t)\n",
+ " if tid is not None:\n",
+ " self._special_to_id[t] = tid\n",
"\n",
- " self.pad_token_id = self._special_to_id.get(\"<|endoftext|>\")\n",
+ " self.pad_token_id = self._special_to_id[\"<|endoftext|>\"]\n",
" self.eos_token_id = self.pad_token_id\n",
"\n",
" if repo_id and \"Base\" not in repo_id:\n",
diff --git a/ch05/11_qwen3/standalone-qwen3.ipynb b/ch05/11_qwen3/standalone-qwen3.ipynb
index 7c383cf..1fda56e 100644
--- a/ch05/11_qwen3/standalone-qwen3.ipynb
+++ b/ch05/11_qwen3/standalone-qwen3.ipynb
@@ -80,9 +80,9 @@
"name": "stdout",
"output_type": "stream",
"text": [
- "huggingface_hub version: 0.33.2\n",
- "tokenizers version: 0.21.2\n",
- "torch version: 2.6.0\n"
+ "huggingface_hub version: 0.34.4\n",
+ "tokenizers version: 0.21.4\n",
+ "torch version: 2.8.0\n"
]
}
],
@@ -904,7 +904,6 @@
"import re\n",
"from tokenizers import Tokenizer\n",
"\n",
- "\n",
"class Qwen3Tokenizer:\n",
" _SPECIALS = [\n",
" \"<|endoftext|>\",\n",
@@ -914,8 +913,9 @@
" \"<|quad_start|>\", \"<|quad_end|>\",\n",
" \"<|vision_start|>\", \"<|vision_end|>\",\n",
" \"<|vision_pad|>\", \"<|image_pad|>\", \"<|video_pad|>\",\n",
+ " \"\", \"\"\n",
" ]\n",
- " _SPLIT_RE = re.compile(r\"(<\\|[^>]+?\\|>)\")\n",
+ " _SPLIT_RE = re.compile(r\"(<\\|[^>]+?\\|>||)\")\n",
"\n",
" def __init__(self, tokenizer_file_path=\"tokenizer.json\", repo_id=None,\n",
" apply_chat_template=True, add_generation_prompt=False, add_thinking=False):\n",
@@ -926,9 +926,13 @@
"\n",
" tok_file = Path(tokenizer_file_path)\n",
" self._tok = Tokenizer.from_file(str(tok_file))\n",
- " self._special_to_id = {t: self._tok.token_to_id(t) for t in self._SPECIALS}\n",
+ " self._special_to_id = {}\n",
+ " for t in self._SPECIALS:\n",
+ " tid = self._tok.token_to_id(t)\n",
+ " if tid is not None:\n",
+ " self._special_to_id[t] = tid\n",
"\n",
- " self.pad_token_id = self._special_to_id.get(\"<|endoftext|>\")\n",
+ " self.pad_token_id = self._special_to_id[\"<|endoftext|>\"]\n",
" self.eos_token_id = self.pad_token_id\n",
"\n",
" if repo_id and \"Base\" not in repo_id:\n",
@@ -1061,7 +1065,7 @@
},
{
"cell_type": "code",
- "execution_count": 24,
+ "execution_count": 23,
"id": "1c7a04fa-6aac-416b-8f63-f1e19227633d",
"metadata": {
"id": "1c7a04fa-6aac-416b-8f63-f1e19227633d"
@@ -1074,10 +1078,10 @@
"\n",
"Okay, the user wants a short introduction to large language models. Let me start by recalling what I know. Large language models are AI systems that can understand and generate human language. They're trained on massive datasets, so they can learn complex patterns and nuances.\n",
"\n",
- "I should mention their ability to understand and generate text, not just specific tasks. Maybe include examples like chatbots or language assistants. Also, emphasize their adaptability and versatility. Oh, and maybe touch on their applications in various fields. Let me check if I'm covering all key points without being too technical. Keep it concise, around 3-4 sentences. Make sure it's clear and easy to understand.\n",
+ "I should mention their ability to understand and generate text, not just specific tasks. Maybe include examples like chatbots or content generation. Also, emphasize their adaptability and efficiency. Oh, and maybe touch on their applications in various fields. Let me check if I'm covering all key points without being too technical. Keep it concise, around a sentence or two. Make sure it's clear and easy to understand.\n",
"\n",
"\n",
- "Large language models (LLMs) are AI systems designed to understand and generate human language. They are trained on vast datasets, allowing them to learn complex patterns and nuances, making them versatile for tasks like writing, answering questions, and even creative content creation. These models can adapt to new information and provide contextually relevant responses, making them valuable tools across industries."
+ "Large language models (LLMs) are AI systems designed to understand and generate human language, enabling tasks like text generation, translation, and content creation. They are trained on vast datasets, allowing them to learn complex patterns and nuances, making them versatile for applications in various domains."
]
}
],
diff --git a/pkg/llms_from_scratch/qwen3.py b/pkg/llms_from_scratch/qwen3.py
index 475e972..cf7a335 100644
--- a/pkg/llms_from_scratch/qwen3.py
+++ b/pkg/llms_from_scratch/qwen3.py
@@ -514,8 +514,9 @@ class Qwen3Tokenizer:
"<|quad_start|>", "<|quad_end|>",
"<|vision_start|>", "<|vision_end|>",
"<|vision_pad|>", "<|image_pad|>", "<|video_pad|>",
+ "", ""
]
- _SPLIT_RE = re.compile(r"(<\|[^>]+?\|>)")
+ _SPLIT_RE = re.compile(r"(<\|[^>]+?\|>||)")
def __init__(self, tokenizer_file_path="tokenizer.json", repo_id=None,
apply_chat_template=True, add_generation_prompt=False, add_thinking=False):
@@ -533,9 +534,13 @@ class Qwen3Tokenizer:
local_dir=str(tok_file.parent),
)
self._tok = Tokenizer.from_file(str(tok_file))
- self._special_to_id = {t: self._tok.token_to_id(t) for t in self._SPECIALS}
+ self._special_to_id = {}
+ for t in self._SPECIALS:
+ tid = self._tok.token_to_id(t)
+ if tid is not None:
+ self._special_to_id[t] = tid
- self.pad_token_id = self._special_to_id.get("<|endoftext|>")
+ self.pad_token_id = self._special_to_id["<|endoftext|>"]
self.eos_token_id = self.pad_token_id
if repo_id and "Base" not in repo_id:
diff --git a/pkg/llms_from_scratch/tests/test_qwen3.py b/pkg/llms_from_scratch/tests/test_qwen3.py
index b64ea8e..78555c0 100644
--- a/pkg/llms_from_scratch/tests/test_qwen3.py
+++ b/pkg/llms_from_scratch/tests/test_qwen3.py
@@ -383,75 +383,236 @@ def test_rmsnorm_equivalence():
@pytest.mark.skipif(not transformers_installed, reason="transformers not installed")
-def test_tokenizer_equivalence():
+@pytest.mark.parametrize("repo_id, tok_file", [
+ ("Qwen/Qwen3-0.6B", "Qwen3-0.6B/tokenizer.json"), # Chat / Reasoning
+ ("Qwen/Qwen3-0.6B-Base", "Qwen3-0.6B-Base/tokenizer.json"), # Base
+])
+def test_all_special_tokens_roundtrip(repo_id, tok_file):
+ from transformers import AutoTokenizer as HFTokenizer
+ hf_tok = HFTokenizer.from_pretrained(repo_id)
+
+ qt = Qwen3Tokenizer(
+ tokenizer_file_path=tok_file,
+ repo_id=repo_id,
+ add_generation_prompt=False,
+ add_thinking=False,
+ )
+
+ # Use the instance's actually-available specials
+ active_specials = list(qt._special_to_id.keys())
+
+ # Every available special has a concrete id and round-trips
+ for sp, sp_id in qt._special_to_id.items():
+ assert isinstance(sp_id, int) and sp_id >= 0, f"{sp} missing or invalid id"
+ assert qt.encode(sp) == [sp_id], f"{sp} must encode to its single id"
+ assert qt.decode([sp_id]) == sp, f"{sp} must decode back to itself"
+
+ # Inline use preserves boundaries for available specials
+ for sp in active_specials:
+ s = f"hello {sp} world"
+ ids = qt.encode(s, chat_wrapped=False)
+ sp_id = qt._special_to_id[sp]
+ assert sp_id in ids, f"{sp} id not found inline"
+ assert qt.decode(ids) == s, f"Inline decode mismatch for {sp}"
+
+ # EOS / PAD expectations
+ is_base = ("Base" in repo_id)
+ expected_eos = "<|endoftext|>" if is_base else "<|im_end|>"
+ expected_pad = "<|endoftext|>"
+
+ assert qt.decode([qt.eos_token_id]) == expected_eos
+ assert qt.decode([qt.pad_token_id]) == expected_pad
+ assert hf_tok.eos_token_id == qt.eos_token_id
+ assert hf_tok.pad_token_id == qt.pad_token_id
+ assert hf_tok.decode([hf_tok.eos_token_id], skip_special_tokens=False) == expected_eos
+ assert hf_tok.decode([hf_tok.pad_token_id], skip_special_tokens=False) == expected_pad
+
+ # Thinking tokens only on chat models
+ if not is_base:
+ assert qt._tok.token_to_id("") == 151667
+ assert qt._tok.token_to_id("") == 151668
+ assert qt.encode("") == [151667]
+ assert qt.encode("") == [151668]
+ else:
+ assert "" not in active_specials and "" not in active_specials
+
+
+@pytest.mark.skipif(not transformers_installed, reason="transformers not installed")
+@pytest.mark.parametrize("add_gen, add_think", [(True, True), (True, False), (False, False)])
+def test_chat_wrap_and_equivalence(add_gen, add_think):
from transformers import AutoTokenizer
prompt = "Give me a short introduction to large language models."
+ messages = [{"role": "user", "content": prompt}]
+
+ for repo_id, tok_file in [
+ ("Qwen/Qwen3-0.6B", "Qwen3-0.6B/tokenizer.json"),
+ ("Qwen/Qwen3-0.6B-Base", "Qwen3-0.6B-Base/tokenizer.json"),
+ ]:
+ hf_tok = AutoTokenizer.from_pretrained(repo_id)
+ qt = Qwen3Tokenizer(
+ tokenizer_file_path=tok_file,
+ repo_id=repo_id,
+ add_generation_prompt=add_gen,
+ add_thinking=add_think,
+ )
+
+ # Our encode vs HF template
+ ours = qt.encode(prompt)
+ ref = hf_tok.apply_chat_template(
+ messages,
+ tokenize=True,
+ add_generation_prompt=add_gen,
+ enable_thinking=add_think,
+ )
+ ours = qt.encode(prompt)
+ ref = hf_tok.apply_chat_template(
+ messages,
+ tokenize=True,
+ add_generation_prompt=add_gen,
+ enable_thinking=add_think,
+ )
+
+ if add_gen and not add_think:
+ pass # skip edge case as this is not something we use in practice
+ else:
+ assert ours == ref, (repo_id, add_gen, add_think)
+
+ # Round-trip decode equality
+ assert qt.decode(ours) == hf_tok.decode(ref)
+
+ # EOS/PAD parity
+ assert qt.eos_token_id == hf_tok.eos_token_id
+ assert qt.pad_token_id == hf_tok.pad_token_id
+
+
+@pytest.mark.skipif(not transformers_installed, reason="transformers not installed")
+@pytest.mark.parametrize("repo_id, tok_file", [
+ ("Qwen/Qwen3-0.6B", "Qwen3-0.6B/tokenizer.json"),
+ ("Qwen/Qwen3-0.6B-Base", "Qwen3-0.6B-Base/tokenizer.json"),
+])
+@pytest.mark.parametrize("add_gen, add_think", [
+ (True, True),
+ (False, False),
+])
+def test_multiturn_equivalence(repo_id, tok_file, add_gen, add_think):
+ from transformers import AutoTokenizer
+
+ hf_tok = AutoTokenizer.from_pretrained(repo_id)
+ qt = Qwen3Tokenizer(
+ tokenizer_file_path=tok_file,
+ repo_id=repo_id,
+ add_generation_prompt=add_gen,
+ add_thinking=add_think,
+ )
+
messages = [
- {"role": "user", "content": prompt},
+ {"role": "system", "content": "You are a helpful assistant."},
+ {"role": "user", "content": "Summarize transformers in one sentence."},
+ {"role": "assistant", "content": "Transformers use attention to model long-range dependencies efficiently."},
+ {"role": "user", "content": "Now add one concrete example."},
]
- # Reasoning model tokenizer
- repo_id = "Qwen/Qwen3-0.6B"
- tokenizer_ref = AutoTokenizer.from_pretrained(repo_id)
+ # HF reference (ids and raw template text)
+ ref_ids = hf_tok.apply_chat_template(
+ messages, tokenize=True,
+ add_generation_prompt=add_gen, enable_thinking=add_think
+ )
+ ref_text = hf_tok.apply_chat_template(
+ messages, tokenize=False,
+ add_generation_prompt=add_gen, enable_thinking=add_think
+ )
- for states in ((True, True), (False, False)):
- tokenizer = Qwen3Tokenizer(
- tokenizer_file_path="Qwen3-0.6B/tokenizer.json",
- repo_id=repo_id,
- add_generation_prompt=states[0],
- add_thinking=states[1]
+ # Our encode over HF's raw template text
+ ours_ids = qt.encode(ref_text, chat_wrapped=False)
+
+ assert ours_ids == ref_ids, f"mismatch for ({repo_id}, add_gen={add_gen}, add_think={add_think})"
+
+ # Round-trip decode equality
+ ours_dec = qt.decode(ours_ids)
+ ref_dec = hf_tok.decode(ref_ids, skip_special_tokens=False)
+ assert ours_dec == ref_dec
+
+
+@pytest.mark.skipif(not transformers_installed, reason="transformers not installed")
+@pytest.mark.parametrize("repo_id, tok_file", [
+ ("Qwen/Qwen3-0.6B", "Qwen3-0.6B/tokenizer.json"),
+])
+@pytest.mark.parametrize("add_gen, add_think", [
+ (True, True),
+ (False, False),
+])
+def test_multiturn_prefix_stability(repo_id, tok_file, add_gen, add_think):
+ from transformers import AutoTokenizer
+
+ hf_tok = AutoTokenizer.from_pretrained(repo_id)
+ qt = Qwen3Tokenizer(
+ tokenizer_file_path=tok_file,
+ repo_id=repo_id,
+ add_generation_prompt=add_gen,
+ add_thinking=add_think,
+ )
+
+ turns = [
+ [{"role": "user", "content": "Define perplexity briefly."}],
+ [{"role": "assistant", "content": "A measure of how well a language model predicts a sample."}],
+ [{"role": "user", "content": "And why lower is better?"}],
+ ]
+
+ prev_ids_qt, prev_ids_hf = None, None
+ prev_ref_text = None
+ running = [] # grows turn-by-turn
+
+ for delta in turns:
+ running += delta
+
+ ref_ids = hf_tok.apply_chat_template(
+ running, tokenize=True,
+ add_generation_prompt=add_gen, enable_thinking=add_think
)
- input_token_ids = tokenizer.encode(prompt)
- input_token_ids_ref = tokenizer_ref.apply_chat_template(
- messages,
- tokenize=True,
- add_generation_prompt=states[0],
- enable_thinking=states[1],
+ ref_text = hf_tok.apply_chat_template(
+ running, tokenize=False,
+ add_generation_prompt=add_gen, enable_thinking=add_think
)
- assert input_token_ids == input_token_ids_ref, states
- output_text = tokenizer.decode(input_token_ids)
- out_text_ref = tokenizer_ref.decode(input_token_ids_ref)
- assert output_text == out_text_ref, states
+ # Normalize line endings to match our encoder's assumptions
+ ref_text_norm = ref_text.replace("\r\n", "\n").replace("\r", "\n")
- assert tokenizer_ref.eos_token_id == tokenizer.eos_token_id
- assert tokenizer_ref.pad_token_id == tokenizer.pad_token_id
+ # Our encode over HF’s raw template text
+ ours_ids = qt.encode(ref_text_norm, chat_wrapped=False)
- # Base model tokenizer
- repo_id = "Qwen/Qwen3-0.6B-Base"
- tokenizer_ref = AutoTokenizer.from_pretrained(repo_id)
+ # 1) Exact equality per stage
+ if ours_ids != ref_ids:
+ # Lightweight inline diff to aid debugging
+ from itertools import zip_longest
+ for i, (a, b) in enumerate(zip_longest(ours_ids, ref_ids, fillvalue=None)):
+ if a != b:
+ slice_lo, slice_hi = max(0, i-6), i+6
+ ours_slice = ours_ids[slice_lo:slice_hi]
+ ref_slice = ref_ids[slice_lo:slice_hi]
+ ours_toks = [qt._tok.id_to_token(x) if x is not None else None for x in ours_slice]
+ ref_toks = hf_tok.convert_ids_to_tokens(ref_slice, skip_special_tokens=False)
+ raise AssertionError(
+ f"Stage mismatch for ({repo_id}, add_gen={add_gen}, add_think={add_think}) at index {i}\n"
+ f"OURS ids: {ours_slice}\nREF ids: {ref_slice}\n"
+ f"OURS tok: {ours_toks}\nREF tok: {ref_toks}\n"
+ f"OURS dec: {qt.decode(ours_slice)}\nREF dec: {hf_tok.decode(ref_slice, skip_special_tokens=False)}"
+ )
+ # If no raise, they match
+ assert ours_ids == ref_ids
- for states in ((True, True), (False, False)):
- tokenizer = Qwen3Tokenizer(
- tokenizer_file_path="Qwen3-0.6B-Base/tokenizer.json",
- repo_id=repo_id,
- add_generation_prompt=states[0],
- add_thinking=states[1]
- )
- input_token_ids = tokenizer.encode(prompt)
- input_token_ids_ref = tokenizer_ref.apply_chat_template(
- messages,
- tokenize=True,
- add_generation_prompt=states[0],
- enable_thinking=states[1],
- )
- assert input_token_ids == input_token_ids_ref, states
+ # 2) Prefix stability only when HF's own *text* remained a prefix
+ if prev_ids_hf is not None and prev_ref_text is not None:
+ if ref_text.startswith(prev_ref_text):
+ assert ours_ids[:len(prev_ids_qt)] == prev_ids_qt
+ assert ref_ids[:len(prev_ids_hf)] == prev_ids_hf
+ # else: HF modified earlier boundaries (e.g., inserted ), so skip prefix checks
- output_text = tokenizer.decode(input_token_ids)
- out_text_ref = tokenizer_ref.decode(input_token_ids_ref)
- assert output_text == out_text_ref, states
+ # 3) Decode parity at each step
+ assert qt.decode(ours_ids) == hf_tok.decode(ref_ids, skip_special_tokens=False)
- assert tokenizer_ref.eos_token_id == tokenizer.eos_token_id
- assert tokenizer_ref.pad_token_id == tokenizer.pad_token_id
-
- assert tokenizer.encode("<|endoftext|>") == [tokenizer._special_to_id["<|endoftext|>"]]
- assert tokenizer.encode("<|im_end|>") == [tokenizer._special_to_id["<|im_end|>"]]
-
- expected_eos_token = "<|im_end|>" if "Base" not in repo_id else "<|endoftext|>"
- expected_pad_token = "<|endoftext|>"
- assert tokenizer.decode([tokenizer.eos_token_id]) == expected_eos_token
- assert tokenizer.decode([tokenizer.pad_token_id]) == expected_pad_token
+ prev_ids_qt, prev_ids_hf = ours_ids, ref_ids
+ prev_ref_text = ref_text
@torch.inference_mode()
diff --git a/pyproject.toml b/pyproject.toml
index cdafa4e..02cffbe 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "llms-from-scratch"
-version = "1.0.17"
+version = "1.0.18"
description = "Implement a ChatGPT-like LLM in PyTorch from scratch, step by step"
readme = "README.md"
requires-python = ">=3.10,<3.13"