Quincy Hsieh commited on
Commit
53cab5b
·
1 Parent(s): f66fdd0

Add team yml and endpoint LLM models

Browse files
Files changed (5) hide show
  1. README.md +150 -58
  2. app.py +42 -19
  3. config.json +4 -0
  4. requirements.txt +0 -1
  5. team.yml +6 -0
README.md CHANGED
@@ -111,7 +111,7 @@ Persist embeddings in a vector store optimized for similarity search.
111
  ```python
112
  import chromadb
113
 
114
- client = chromadb.PersistentClient(path="./chroma_db")
115
  collection = client.get_or_create_collection(
116
  name="rag_documents",
117
  metadata={"hnsw:space": "cosine"},
@@ -336,89 +336,101 @@ curl -X POST http://localhost:7860/ingest \
336
 
337
  ## Adding Binary Files to the HF Space
338
 
339
- Large or binary files (e.g., pre-built ChromaDB databases, PDFs, images, model weights) cannot be pushed with regular `git push` because Hugging Face repositories enforce a **10 MB file-size limit** for standard Git. Use one of the methods below to make them available to your Space at runtime.
340
 
341
- ### Method 1: Git LFS (recommended for files < 5 GB)
342
 
343
- Hugging Face repos support [Git Large File Storage (LFS)](https://git-lfs.com/). Files tracked by LFS are stored in a dedicated bucket and downloaded transparently when the Space starts.
344
 
345
  ```bash
346
- # 1. Install Git LFS (once per machine)
347
- git lfs install
348
 
349
- # 2. Track the binary patterns you need
350
- git lfs track "*.pdf"
351
- git lfs track "*.sqlite3"
352
- git lfs track "chroma_db/**"
353
- git lfs track "DataSet/**"
354
 
355
- # This updates .gitattributes commit it
356
- git add .gitattributes
357
- git commit -m "chore: track binary files with Git LFS"
358
 
359
- # 3. Add and push the binary files
360
- git add chroma_db/ DataSet/
361
- git commit -m "feat: add pre-built vector store and datasets"
362
- git push
363
- ```
364
 
365
- > **Verify:** After pushing, open your Space repo on huggingface.co and click on an LFS file it should show `Stored with Git LFS` instead of raw content.
366
 
367
- ### Method 2: Upload via the `huggingface_hub` Python SDK
368
 
369
- Use this when you want to upload files programmatically (e.g., from a CI pipeline or a notebook) without cloning the full repo.
 
 
 
 
 
 
 
 
 
 
 
370
 
371
- ```python
372
- from huggingface_hub import HfApi
373
 
374
- api = HfApi()
 
 
375
 
376
- # Upload a single file
377
- api.upload_file(
378
- path_or_fileobj="./chroma_db/chroma.sqlite3",
379
- path_in_repo="chroma_db/chroma.sqlite3",
380
- repo_id="YOUR_USERNAME/Example-App-Hackathon-Gustave-Eiffel-2026",
381
- repo_type="space",
382
- )
383
 
384
- # Upload an entire folder
385
- api.upload_folder(
386
- folder_path="./DataSet",
387
- path_in_repo="DataSet",
388
- repo_id="YOUR_USERNAME/Example-App-Hackathon-Gustave-Eiffel-2026",
389
- repo_type="space",
390
- )
391
  ```
392
 
393
- > **Authentication:** Set `HF_TOKEN` in your environment or call `huggingface_hub.login()` first. The token needs **write** access to the Space.
 
 
394
 
395
- ### Method 3: Hugging Face Hub UI (quick one-off uploads)
 
 
 
 
396
 
397
- 1. Open your Space repository on huggingface.co
398
- 2. Navigate to **Files and versions**
399
- 3. Click **Add file → Upload files**
400
- 4. Drag-and-drop your binary files (up to 50 GB per file via the UI)
401
- 5. Commit directly to `main`
402
 
403
- ### Accessing Uploaded Files in Your Application
404
 
405
- Once binary files are in the repo (via any method above), they are available at their relative path inside the Space container:
406
 
407
  ```python
408
- import chromadb
 
 
 
409
 
410
- # Files land at the repo root, same relative path you committed them at
411
- client = chromadb.PersistentClient(path="./chroma_db")
412
  ```
413
 
414
- No extra download logic is needed Hugging Face clones the full repo (including LFS objects) into the Space container on startup.
415
 
416
- ### Tips
417
 
418
- - **`.gitattributes`** is the source of truth for LFS tracking. Verify your patterns are listed there before pushing.
419
- - For files **> 5 GB**, prefer uploading via the Hub UI or the SDK (Git LFS CLI may time out on slow connections).
420
- - If you update a binary file, push the new version the same way — LFS handles versioning automatically.
421
- - To exclude files from the Space build (e.g., test data not needed at runtime), add them to `.gitignore` instead.
 
 
 
 
 
 
 
422
 
423
  ---
424
 
@@ -429,7 +441,9 @@ No extra download logic is needed — Hugging Face clones the full repo (includi
429
  | `HF_TOKEN` | (Space Secret) | Hugging Face API token for Inference API |
430
  | `EMBEDDING_MODEL_NAME` | `sentence-transformers/all-MiniLM-L6-v2` | Model for text embeddings |
431
  | `LLM_MODEL_NAME` | `Qwen/Qwen2.5-72B-Instruct` | LLM for answer generation |
432
- | `CHROMA_PERSIST_DIR` | `./chroma_db` | ChromaDB storage path |
 
 
433
  | `CHUNK_SIZE` | `512` | Text chunk size in characters |
434
  | `CHUNK_OVERLAP` | `50` | Overlap between chunks |
435
  | `TOP_K_RESULTS` | `3` | Number of context chunks to retrieve |
@@ -507,6 +521,84 @@ Set the variable **before** running `python app.py`. Both `huggingface_hub` and
507
  > **How to export your corporate CA certificate:**
508
  > Open the failing URL (`https://huggingface.co`) in your browser, click the padlock icon → View Certificate → export the root CA as a `.crt` / `.pem` file, then point `REQUESTS_CA_BUNDLE` to that file.
509
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
510
  ---
511
 
512
  ## License
 
111
  ```python
112
  import chromadb
113
 
114
+ client = chromadb.PersistentClient(path="./data/chroma_db")
115
  collection = client.get_or_create_collection(
116
  name="rag_documents",
117
  metadata={"hnsw:space": "cosine"},
 
336
 
337
  ## Adding Binary Files to the HF Space
338
 
339
+ Large or binary files (PDFs, pre-built ChromaDB databases, datasets, model weights) are stored in a **Hugging Face bucket** and mounted into the Space container at `/data`. The `hf sync` command keeps your local folder in sync with the bucket.
340
 
341
+ > **Note:** Git LFS is not supported for Hugging Face Spaces persistent storage. Use the bucket + `hf sync` workflow described here instead.
342
 
343
+ ### Prerequisites
344
 
345
  ```bash
346
+ # Install the hf CLI (requires uv)
347
+ uv tool install "huggingface_hub[cli]"
348
 
349
+ # Authenticate (needs Write access to the bucket)
350
+ export HF_TOKEN="hf_your_token_here"
351
+ # or interactively:
352
+ hf auth login
353
+ ```
354
 
355
+ ### Step 1Attach the Storage Bucket to Your Space
 
 
356
 
357
+ 1. Open your Space on huggingface.co
358
+ 2. Go to **Settings → Persistent Storage**
359
+ 3. Under **"Attach storage"**, select the existing bucket **`millimanfrance/Example-App-Hackathon-Gustave-Eiffel-2026-storage`** (or create a new one)
360
+ 4. Save — Hugging Face will mount the bucket at `/data` inside the Space container
 
361
 
362
+ ### Step 2Upload Files from Your Local Machine
363
 
364
+ Place all persistent files under a local `./data` folder. The expected structure is:
365
 
366
+ ```
367
+ ./data/
368
+ ├── chroma_db/ # Pre-built ChromaDB vector store
369
+ │ └── chroma.sqlite3
370
+ ├── sample_documents/ # Text/PDF files ingested on startup
371
+ │ ├── eiffel_tower.txt
372
+ │ └── gustave_eiffel.txt
373
+ └── DataSet/ # Training/test datasets (PDFs, CSVs, etc.)
374
+ ├── Automobile/
375
+ ├── Climatique/
376
+ └── ...
377
+ ```
378
 
379
+ Then push:
 
380
 
381
+ ```bash
382
+ # Sync the entire ./data folder to the bucket
383
+ hf sync ./data hf://buckets/millimanfrance/Example-App-Hackathon-Gustave-Eiffel-2026-storage
384
 
385
+ # Sync only a specific sub-folder (e.g., the vector store)
386
+ hf sync ./data/chroma_db hf://buckets/millimanfrance/Example-App-Hackathon-Gustave-Eiffel-2026-storage/chroma_db
 
 
 
 
 
387
 
388
+ # Sync only specific file types
389
+ hf sync ./data hf://buckets/millimanfrance/Example-App-Hackathon-Gustave-Eiffel-2026-storage \
390
+ --include "*.pdf" --include "*.sqlite3"
 
 
 
 
391
  ```
392
 
393
+ `hf sync` is **incremental** it computes checksums and only uploads files that have changed.
394
+
395
+ ### Step 3 — Download the Bucket to Another Machine
396
 
397
+ To pull the latest bucket contents back to a local `./data` folder (e.g., on a new dev machine):
398
+
399
+ ```bash
400
+ hf sync hf://buckets/millimanfrance/Example-App-Hackathon-Gustave-Eiffel-2026-storage ./data
401
+ ```
402
 
403
+ ### Accessing Files in the Space Application
 
 
 
 
404
 
405
+ Once the bucket is mounted, files appear under `/data` inside the Space container regardless of their path in the bucket.
406
 
407
+ The application resolves this automatically via a single `DATA_DIR` constant in `app.py`:
408
 
409
  ```python
410
+ from pathlib import Path
411
+
412
+ # /data when running in HF Spaces (bucket mount), ./data for local dev
413
+ DATA_DIR = Path("/data") if Path("/data").is_dir() else Path("./data")
414
 
415
+ CHROMA_PERSIST_DIR = str(DATA_DIR / "chroma_db")
416
+ SAMPLE_DOCS_DIR = DATA_DIR / "sample_documents"
417
  ```
418
 
419
+ All persistent data the vector store, sample documents, datasets lives under `DATA_DIR` so a single `hf sync ./data ...` covers everything.
420
 
421
+ ### Useful `hf sync` Flags
422
 
423
+ | Flag | Description |
424
+ |---|---|
425
+ | `--include "*.pdf"` | Only sync files matching the pattern |
426
+ | `--exclude "*.tmp"` | Skip files matching the pattern |
427
+ | `--delete` | Remove files in the destination that no longer exist in the source |
428
+ | `--dry-run` | Preview what would be transferred without actually doing it |
429
+
430
+ ```bash
431
+ # Preview before committing
432
+ hf sync ./data hf://buckets/millimanfrance/Example-App-Hackathon-Gustave-Eiffel-2026-storage --dry-run
433
+ ```
434
 
435
  ---
436
 
 
441
  | `HF_TOKEN` | (Space Secret) | Hugging Face API token for Inference API |
442
  | `EMBEDDING_MODEL_NAME` | `sentence-transformers/all-MiniLM-L6-v2` | Model for text embeddings |
443
  | `LLM_MODEL_NAME` | `Qwen/Qwen2.5-72B-Instruct` | LLM for answer generation |
444
+ | `DATA_DIR` | `/data` (HF Spaces) or `./data` (local) | Root directory for all persistent data |
445
+ | `CHROMA_PERSIST_DIR` | `DATA_DIR/chroma_db` | ChromaDB storage path |
446
+ | `SAMPLE_DOCS_DIR` | `DATA_DIR/sample_documents` | Documents ingested on startup |
447
  | `CHUNK_SIZE` | `512` | Text chunk size in characters |
448
  | `CHUNK_OVERLAP` | `50` | Overlap between chunks |
449
  | `TOP_K_RESULTS` | `3` | Number of context chunks to retrieve |
 
521
  > **How to export your corporate CA certificate:**
522
  > Open the failing URL (`https://huggingface.co`) in your browser, click the padlock icon → View Certificate → export the root CA as a `.crt` / `.pem` file, then point `REQUESTS_CA_BUNDLE` to that file.
523
 
524
+ ### `hf sync` 401 Unauthorized Error
525
+
526
+ If `hf sync` fails with:
527
+
528
+ ```
529
+ Error: Client error '401 Unauthorized' for url
530
+ 'https://huggingface.co/api/buckets/.../tree?recursive=true'
531
+ Invalid username or password.
532
+ ```
533
+
534
+ the `hf` CLI has not been authenticated. Log in with your Hugging Face token:
535
+
536
+ ```bash
537
+ hf auth login
538
+ # Paste your token when prompted (needs read + write access to the bucket)
539
+ ```
540
+
541
+ Or set the token as an environment variable so the CLI picks it up automatically without an interactive prompt:
542
+
543
+ ```bash
544
+ export HF_TOKEN="hf_your_token_here"
545
+ hf sync ./data hf://buckets/millimanfrance/Example-App-Hackathon-Gustave-Eiffel-2026-storage
546
+ ```
547
+
548
+ > **Generate a token:** Go to huggingface.co → Settings → Access Tokens → New token. Select **Write** role so the CLI can both read and upload to the bucket.
549
+
550
+ > **Check current login state:**
551
+ > ```bash
552
+ > hf auth whoami
553
+ > ```
554
+
555
+ ---
556
+
557
+ ### `hf sync` SSL Certificate Verification Error
558
+
559
+ The `hf` CLI (installed via `uv tool install huggingface_hub`) uses `httpx` internally instead of `requests`, so it ignores `REQUESTS_CA_BUNDLE`. If `hf sync` fails with:
560
+
561
+ ```
562
+ httpcore.ConnectError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed:
563
+ unable to get local issuer certificate
564
+ ```
565
+
566
+ you must set the certificate bundle through the variables that `httpx` (and the underlying `ssl` module) respects:
567
+
568
+ ```bash
569
+ # Option A — point to your corporate CA bundle file (recommended)
570
+ export SSL_CERT_FILE=/path/to/corporate-ca.crt
571
+ export REQUESTS_CA_BUNDLE=/path/to/corporate-ca.crt # keep this too for other tools
572
+
573
+ hf sync ./data hf://buckets/millimanfrance/Example-App-Hackathon-Gustave-Eiffel-2026-storage
574
+
575
+ # Option B — append your CA cert to the system bundle and point there
576
+ cat /path/to/corporate-ca.crt >> /etc/ssl/certs/ca-certificates.crt
577
+ export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
578
+ ```
579
+
580
+ `SSL_CERT_FILE` overrides the default CA store for Python's `ssl` module, which `httpx` / `httpcore` uses directly.
581
+
582
+ **If you need to set these variables permanently** (e.g., in a shared dev environment), add them to your shell profile:
583
+
584
+ ```bash
585
+ # ~/.bashrc or ~/.zshrc
586
+ export SSL_CERT_FILE=/path/to/corporate-ca.crt
587
+ export REQUESTS_CA_BUNDLE=/path/to/corporate-ca.crt
588
+ ```
589
+
590
+ > **Finding your corporate CA cert on Linux:**
591
+ > ```bash
592
+ > # List all trusted CAs and look for your company's entry
593
+ > awk -v cmd='openssl x509 -noout -subject' '/BEGIN CERT/{close(cmd)}; {print | cmd}' \
594
+ > /etc/ssl/certs/ca-certificates.crt | grep -i "your-company-name"
595
+ >
596
+ > # Or export the cert directly from the proxy
597
+ > echo | openssl s_client -connect huggingface.co:443 -showcerts 2>/dev/null \
598
+ > | openssl x509 -outform PEM > /tmp/hf-chain.pem
599
+ > export SSL_CERT_FILE=/tmp/hf-chain.pem
600
+ > ```
601
+
602
  ---
603
 
604
  ## License
app.py CHANGED
@@ -32,7 +32,6 @@ from fastapi.responses import JSONResponse
32
  from pydantic import BaseModel
33
  import chromadb
34
  from chromadb.config import Settings
35
- from sentence_transformers import SentenceTransformer
36
  from langchain_text_splitters import RecursiveCharacterTextSplitter
37
  from pypdf import PdfReader
38
 
@@ -46,42 +45,49 @@ logging.getLogger("chromadb.telemetry.product.posthog").setLevel(logging.CRITICA
46
  # Configuration
47
  # ---------------------------------------------------------------------------
48
 
49
- EMBEDDING_MODEL_NAME = "sentence-transformers/all-MiniLM-L6-v2"
50
- CHROMA_PERSIST_DIR = "./chroma_db"
 
 
 
 
51
  COLLECTION_NAME = "rag_documents"
52
  CHUNK_SIZE = 512
53
  CHUNK_OVERLAP = 50
54
  TOP_K_RESULTS = 3
55
 
56
- # LLM settings loaded from config.json
57
  _CONFIG_PATH = Path(__file__).parent / "config.json"
58
  with open(_CONFIG_PATH, encoding="utf-8") as _f:
59
  _config = json.load(_f)
60
 
 
 
 
 
 
61
  LLM_ENDPOINT_URL = _config["llm"]["endpoint_url"]
62
  LLM_MODEL_NAME = _config["llm"]["model"]
63
  LLM_MAX_TOKENS = _config["llm"].get("max_tokens", 512)
64
  LLM_TEMPERATURE = _config["llm"].get("temperature", 0.7)
65
  LLM_TOP_P = _config["llm"].get("top_p", 0.95)
66
 
67
- # Azure Foundry API key from environment variable
68
  AZURE_API_KEY = os.environ.get("AZURE_API_KEY")
69
  if not AZURE_API_KEY:
70
- logger.warning("AZURE_API_KEY is not set — LLM calls will fail.")
71
 
72
  # Prompt template loaded from file so it can be edited without touching application code
73
  _PROMPT_TEMPLATE_PATH = Path(__file__).parent / "prompts" / "rag_prompt.txt"
74
  RAG_PROMPT_TEMPLATE = _PROMPT_TEMPLATE_PATH.read_text(encoding="utf-8")
75
 
76
  # ---------------------------------------------------------------------------
77
- # Step 1: Initialize the Embedding Model
78
  # ---------------------------------------------------------------------------
79
- # We use sentence-transformers to convert text chunks into dense vector embeddings.
80
- # The model runs locally inside the Space — no external API call needed.
81
 
82
- logger.info(f"Loading embedding model: {EMBEDDING_MODEL_NAME}")
83
- embedding_model = SentenceTransformer(EMBEDDING_MODEL_NAME)
84
- logger.info("Embedding model loaded successfully.")
85
 
86
  # ---------------------------------------------------------------------------
87
  # Step 2: Initialize the Vector Store (ChromaDB)
@@ -152,13 +158,32 @@ def chunk_text(text: str, source: str = "unknown") -> list[dict]:
152
 
153
  def generate_embeddings(texts: list[str]) -> list[list[float]]:
154
  """
155
- Transform text chunks into vector embeddings using sentence-transformers.
156
 
157
- This demonstrates Step 2a: How to convert documents into embeddings.
158
- The model maps each text string to a 384-dimensional dense vector.
159
  """
160
- embeddings = embedding_model.encode(texts, show_progress_bar=False)
161
- return embeddings.tolist()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
 
163
 
164
  def add_documents_to_vectorstore(documents: list[dict]) -> int:
@@ -311,8 +336,6 @@ def rag_query(query: str, top_k: int = TOP_K_RESULTS) -> dict:
311
  # ---------------------------------------------------------------------------
312
  # Load sample documents so the demo works out of the box.
313
 
314
- SAMPLE_DOCS_DIR = Path("./sample_documents")
315
-
316
 
317
  def ingest_sample_documents():
318
  """Load and embed sample documents into the vector store on first run."""
 
32
  from pydantic import BaseModel
33
  import chromadb
34
  from chromadb.config import Settings
 
35
  from langchain_text_splitters import RecursiveCharacterTextSplitter
36
  from pypdf import PdfReader
37
 
 
45
  # Configuration
46
  # ---------------------------------------------------------------------------
47
 
48
+ # Resolve the data directory: /data when running inside HF Spaces (bucket mount),
49
+ # ./data for local development.
50
+ DATA_DIR = Path("/data") if Path("/data").is_dir() else Path("./data")
51
+
52
+ CHROMA_PERSIST_DIR = str(DATA_DIR / "chroma_db")
53
+ SAMPLE_DOCS_DIR = DATA_DIR / "sample_documents"
54
  COLLECTION_NAME = "rag_documents"
55
  CHUNK_SIZE = 512
56
  CHUNK_OVERLAP = 50
57
  TOP_K_RESULTS = 3
58
 
59
+ # Settings loaded from config.json
60
  _CONFIG_PATH = Path(__file__).parent / "config.json"
61
  with open(_CONFIG_PATH, encoding="utf-8") as _f:
62
  _config = json.load(_f)
63
 
64
+ # Embedding model (Azure OpenAI)
65
+ EMBEDDING_ENDPOINT_URL = _config["embedding"]["endpoint_url"]
66
+ EMBEDDING_MODEL_NAME = _config["embedding"]["model"]
67
+
68
+ # LLM (Azure OpenAI)
69
  LLM_ENDPOINT_URL = _config["llm"]["endpoint_url"]
70
  LLM_MODEL_NAME = _config["llm"]["model"]
71
  LLM_MAX_TOKENS = _config["llm"].get("max_tokens", 512)
72
  LLM_TEMPERATURE = _config["llm"].get("temperature", 0.7)
73
  LLM_TOP_P = _config["llm"].get("top_p", 0.95)
74
 
75
+ # Azure API key from environment variable (shared by both LLM and embedding endpoints)
76
  AZURE_API_KEY = os.environ.get("AZURE_API_KEY")
77
  if not AZURE_API_KEY:
78
+ logger.warning("AZURE_API_KEY is not set — LLM and embedding calls will fail.")
79
 
80
  # Prompt template loaded from file so it can be edited without touching application code
81
  _PROMPT_TEMPLATE_PATH = Path(__file__).parent / "prompts" / "rag_prompt.txt"
82
  RAG_PROMPT_TEMPLATE = _PROMPT_TEMPLATE_PATH.read_text(encoding="utf-8")
83
 
84
  # ---------------------------------------------------------------------------
85
+ # Step 1: Embedding via Azure OpenAI
86
  # ---------------------------------------------------------------------------
87
+ # Embeddings are generated by calling the Azure OpenAI /embeddings endpoint.
88
+ # No local model is loaded the API handles all inference.
89
 
90
+ logger.info(f"Embedding model configured: {EMBEDDING_MODEL_NAME} via Azure OpenAI")
 
 
91
 
92
  # ---------------------------------------------------------------------------
93
  # Step 2: Initialize the Vector Store (ChromaDB)
 
158
 
159
  def generate_embeddings(texts: list[str]) -> list[list[float]]:
160
  """
161
+ Generate vector embeddings via the Azure OpenAI /embeddings endpoint.
162
 
163
+ The endpoint, model name, and API key are loaded from config.json
164
+ and the AZURE_API_KEY environment variable.
165
  """
166
+ headers = {
167
+ "api-key": AZURE_API_KEY,
168
+ "Content-Type": "application/json",
169
+ }
170
+ payload = {
171
+ "input": texts,
172
+ "model": EMBEDDING_MODEL_NAME,
173
+ }
174
+ try:
175
+ resp = http_requests.post(
176
+ EMBEDDING_ENDPOINT_URL, headers=headers, json=payload, timeout=60,
177
+ )
178
+ resp.raise_for_status()
179
+ data = resp.json()
180
+ return [item["embedding"] for item in data["data"]]
181
+ except http_requests.exceptions.HTTPError as e:
182
+ logger.error(f"Embedding API call failed: {e} — {resp.text}")
183
+ raise HTTPException(status_code=503, detail=f"Embedding service unavailable: {str(e)}")
184
+ except (KeyError, IndexError) as e:
185
+ logger.error(f"Unexpected embedding response format: {e}")
186
+ raise HTTPException(status_code=502, detail="Unexpected response from embedding service")
187
 
188
 
189
  def add_documents_to_vectorstore(documents: list[dict]) -> int:
 
336
  # ---------------------------------------------------------------------------
337
  # Load sample documents so the demo works out of the box.
338
 
 
 
339
 
340
  def ingest_sample_documents():
341
  """Load and embed sample documents into the vector store on first run."""
config.json CHANGED
@@ -1,4 +1,8 @@
1
  {
 
 
 
 
2
  "llm": {
3
  "endpoint_url": "https://<your-resource>.openai.azure.com/openai/deployments/<your-deployment>/chat/completions?api-version=2024-12-01-preview",
4
  "model": "gpt-5",
 
1
  {
2
+ "embedding": {
3
+ "endpoint_url": "https://<your-resource>.openai.azure.com/openai/deployments/<your-embedding-deployment>/embeddings?api-version=2024-12-01-preview",
4
+ "model": "text-embedding-3-small"
5
+ },
6
  "llm": {
7
  "endpoint_url": "https://<your-resource>.openai.azure.com/openai/deployments/<your-deployment>/chat/completions?api-version=2024-12-01-preview",
8
  "model": "gpt-5",
requirements.txt CHANGED
@@ -2,7 +2,6 @@ fastapi==0.115.0
2
  uvicorn==0.30.0
3
  gradio==4.44.0
4
  chromadb==0.5.0
5
- sentence-transformers==3.0.0
6
  huggingface-hub==0.25.0
7
  langchain==0.3.0
8
  langchain-community==0.3.0
 
2
  uvicorn==0.30.0
3
  gradio==4.44.0
4
  chromadb==0.5.0
 
5
  huggingface-hub==0.25.0
6
  langchain==0.3.0
7
  langchain-community==0.3.0
team.yml ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ display_name: "Sample Team Name"
2
+ members:
3
+ - name: "Quincy"
4
+ email: "quincy@example.com"
5
+ - name: "Alice"
6
+ email: "alice@example.com"