Spaces:
Sleeping
Sleeping
Update api/config.py
Browse files- api/config.py +91 -18
api/config.py
CHANGED
|
@@ -1,36 +1,100 @@
|
|
| 1 |
-
# config.py
|
| 2 |
import os
|
| 3 |
from typing import List, Dict
|
|
|
|
|
|
|
| 4 |
from openai import OpenAI
|
| 5 |
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
|
| 6 |
|
| 7 |
-
#
|
| 8 |
-
|
|
|
|
|
|
|
|
|
|
| 9 |
if not OPENAI_API_KEY:
|
| 10 |
-
raise RuntimeError(
|
| 11 |
-
|
| 12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
|
| 14 |
-
#
|
| 15 |
-
|
| 16 |
-
EMBEDDING_MODEL = "text-embedding-3-small"
|
| 17 |
|
| 18 |
-
# ---------- OpenAI 原生 Client(老代码还在用) ----------
|
| 19 |
-
client = OpenAI(api_key=OPENAI_API_KEY)
|
| 20 |
|
| 21 |
-
#
|
| 22 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
llm_default = ChatOpenAI(
|
| 24 |
model=DEFAULT_MODEL,
|
| 25 |
temperature=0.5,
|
| 26 |
-
timeout=
|
|
|
|
| 27 |
)
|
| 28 |
|
| 29 |
embedding_client = OpenAIEmbeddings(
|
| 30 |
model=EMBEDDING_MODEL,
|
| 31 |
)
|
| 32 |
|
| 33 |
-
#
|
|
|
|
|
|
|
|
|
|
| 34 |
DEFAULT_COURSE_TOPICS: List[str] = [
|
| 35 |
"Week 0 – Welcome & What is Generative AI; course outcomes LO1–LO5.",
|
| 36 |
"Week 1 – Foundations of GenAI: LLMs, Transformer & self-attention, perplexity.",
|
|
@@ -45,7 +109,10 @@ DEFAULT_COURSE_TOPICS: List[str] = [
|
|
| 45 |
"Week 10 – Responsible AI; risks, governance, EU AI Act-style ideas.",
|
| 46 |
]
|
| 47 |
|
| 48 |
-
#
|
|
|
|
|
|
|
|
|
|
| 49 |
LEARNING_MODES: List[str] = [
|
| 50 |
"Concept Explainer",
|
| 51 |
"Socratic Tutor",
|
|
@@ -82,7 +149,10 @@ LEARNING_MODE_INSTRUCTIONS: Dict[str, str] = {
|
|
| 82 |
),
|
| 83 |
}
|
| 84 |
|
| 85 |
-
#
|
|
|
|
|
|
|
|
|
|
| 86 |
DOC_TYPES: List[str] = [
|
| 87 |
"Syllabus",
|
| 88 |
"Lecture Slides / PPT",
|
|
@@ -90,7 +160,10 @@ DOC_TYPES: List[str] = [
|
|
| 90 |
"Other Course Document",
|
| 91 |
]
|
| 92 |
|
| 93 |
-
#
|
|
|
|
|
|
|
|
|
|
| 94 |
CLARE_SYSTEM_PROMPT = """
|
| 95 |
You are Clare, an AI teaching assistant for Hanbridge University.
|
| 96 |
|
|
|
|
| 1 |
+
# api/config.py
|
| 2 |
import os
|
| 3 |
from typing import List, Dict
|
| 4 |
+
|
| 5 |
+
import httpx
|
| 6 |
from openai import OpenAI
|
| 7 |
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
|
| 8 |
|
| 9 |
+
# ============================
|
| 10 |
+
# Environment & Core Settings
|
| 11 |
+
# ============================
|
| 12 |
+
|
| 13 |
+
OPENAI_API_KEY = (os.getenv("OPENAI_API_KEY") or "").strip()
|
| 14 |
if not OPENAI_API_KEY:
|
| 15 |
+
raise RuntimeError("OPENAI_API_KEY is not set. Please go to Settings → Secrets and add it.")
|
| 16 |
+
|
| 17 |
+
# Optional: allow overriding base URL (useful for gateways / proxies)
|
| 18 |
+
OPENAI_BASE_URL = (os.getenv("OPENAI_BASE_URL") or "").strip() or None
|
| 19 |
+
|
| 20 |
+
# Models
|
| 21 |
+
DEFAULT_MODEL = (os.getenv("CLARE_DEFAULT_MODEL") or "gpt-4.1-mini").strip()
|
| 22 |
+
EMBEDDING_MODEL = (os.getenv("CLARE_EMBEDDING_MODEL") or "text-embedding-3-small").strip()
|
| 23 |
+
|
| 24 |
+
# Timeout (seconds) - single source of truth
|
| 25 |
+
OPENAI_TIMEOUT_SECONDS = float(os.getenv("CLARE_OPENAI_TIMEOUT_SECONDS", "20").strip())
|
| 26 |
+
|
| 27 |
+
# Connection pooling / keep-alive
|
| 28 |
+
HTTP_MAX_CONNECTIONS = int(os.getenv("CLARE_HTTP_MAX_CONNECTIONS", "20").strip())
|
| 29 |
+
HTTP_MAX_KEEPALIVE = int(os.getenv("CLARE_HTTP_MAX_KEEPALIVE", "10").strip())
|
| 30 |
+
HTTP_KEEPALIVE_EXPIRY = float(os.getenv("CLARE_HTTP_KEEPALIVE_EXPIRY", "30").strip())
|
| 31 |
|
| 32 |
+
# Network retries (transport-level)
|
| 33 |
+
HTTP_RETRIES = int(os.getenv("CLARE_HTTP_RETRIES", "2").strip())
|
|
|
|
| 34 |
|
|
|
|
|
|
|
| 35 |
|
| 36 |
+
# ============================
|
| 37 |
+
# Shared HTTP client (singleton)
|
| 38 |
+
# ============================
|
| 39 |
+
|
| 40 |
+
# httpx Timeout object (connect/read/write/pool)
|
| 41 |
+
_httpx_timeout = httpx.Timeout(
|
| 42 |
+
timeout=OPENAI_TIMEOUT_SECONDS,
|
| 43 |
+
connect=min(10.0, OPENAI_TIMEOUT_SECONDS),
|
| 44 |
+
read=OPENAI_TIMEOUT_SECONDS,
|
| 45 |
+
write=OPENAI_TIMEOUT_SECONDS,
|
| 46 |
+
pool=min(10.0, OPENAI_TIMEOUT_SECONDS),
|
| 47 |
+
)
|
| 48 |
+
|
| 49 |
+
_limits = httpx.Limits(
|
| 50 |
+
max_connections=HTTP_MAX_CONNECTIONS,
|
| 51 |
+
max_keepalive_connections=HTTP_MAX_KEEPALIVE,
|
| 52 |
+
keepalive_expiry=HTTP_KEEPALIVE_EXPIRY,
|
| 53 |
+
)
|
| 54 |
+
|
| 55 |
+
# A single httpx client reused across the process
|
| 56 |
+
_http_client = httpx.Client(
|
| 57 |
+
timeout=_httpx_timeout,
|
| 58 |
+
limits=_limits,
|
| 59 |
+
headers={
|
| 60 |
+
# Helps some proxies; safe default
|
| 61 |
+
"Connection": "keep-alive",
|
| 62 |
+
},
|
| 63 |
+
follow_redirects=True,
|
| 64 |
+
)
|
| 65 |
+
|
| 66 |
+
# ============================
|
| 67 |
+
# OpenAI SDK client (singleton)
|
| 68 |
+
# ============================
|
| 69 |
+
|
| 70 |
+
# Keep naming as `client` to avoid touching call sites
|
| 71 |
+
client = OpenAI(
|
| 72 |
+
api_key=OPENAI_API_KEY,
|
| 73 |
+
base_url=OPENAI_BASE_URL,
|
| 74 |
+
http_client=_http_client,
|
| 75 |
+
max_retries=HTTP_RETRIES,
|
| 76 |
+
)
|
| 77 |
+
|
| 78 |
+
# ============================
|
| 79 |
+
# LangChain wrappers (optional)
|
| 80 |
+
# ============================
|
| 81 |
+
|
| 82 |
+
# If you use LangChain later, reuse the same timeout policy
|
| 83 |
llm_default = ChatOpenAI(
|
| 84 |
model=DEFAULT_MODEL,
|
| 85 |
temperature=0.5,
|
| 86 |
+
timeout=OPENAI_TIMEOUT_SECONDS,
|
| 87 |
+
# Note: LangChain uses its own http stack; keep it simple.
|
| 88 |
)
|
| 89 |
|
| 90 |
embedding_client = OpenAIEmbeddings(
|
| 91 |
model=EMBEDDING_MODEL,
|
| 92 |
)
|
| 93 |
|
| 94 |
+
# ============================
|
| 95 |
+
# Default course outline
|
| 96 |
+
# ============================
|
| 97 |
+
|
| 98 |
DEFAULT_COURSE_TOPICS: List[str] = [
|
| 99 |
"Week 0 – Welcome & What is Generative AI; course outcomes LO1–LO5.",
|
| 100 |
"Week 1 – Foundations of GenAI: LLMs, Transformer & self-attention, perplexity.",
|
|
|
|
| 109 |
"Week 10 – Responsible AI; risks, governance, EU AI Act-style ideas.",
|
| 110 |
]
|
| 111 |
|
| 112 |
+
# ============================
|
| 113 |
+
# Learning modes
|
| 114 |
+
# ============================
|
| 115 |
+
|
| 116 |
LEARNING_MODES: List[str] = [
|
| 117 |
"Concept Explainer",
|
| 118 |
"Socratic Tutor",
|
|
|
|
| 149 |
),
|
| 150 |
}
|
| 151 |
|
| 152 |
+
# ============================
|
| 153 |
+
# Upload doc types
|
| 154 |
+
# ============================
|
| 155 |
+
|
| 156 |
DOC_TYPES: List[str] = [
|
| 157 |
"Syllabus",
|
| 158 |
"Lecture Slides / PPT",
|
|
|
|
| 160 |
"Other Course Document",
|
| 161 |
]
|
| 162 |
|
| 163 |
+
# ============================
|
| 164 |
+
# Clare system prompt
|
| 165 |
+
# ============================
|
| 166 |
+
|
| 167 |
CLARE_SYSTEM_PROMPT = """
|
| 168 |
You are Clare, an AI teaching assistant for Hanbridge University.
|
| 169 |
|