Pro-Coder commited on
Commit
8f9afd8
·
verified ·
1 Parent(s): bbd6411

Upload 34 files

Browse files
README.md CHANGED
@@ -27,16 +27,23 @@ metrics on held-out test data.
27
 
28
  1. **💬 AI Assistant** — ask free-text warehouse-ops questions; answers are
29
  grounded via TF-IDF retrieval over a small knowledge base and generated
30
- by a hosted LLM (Hugging Face Inference API), with a transparent
31
- retrieval-only fallback if no API key is configured.
 
 
 
32
  2. **📦 Inventory & Order Query** — natural-language queries over synthetic
33
- inventory / order tables (SKU, zone, order-id extraction).
 
34
  3. **⚠️ Predictive Maintenance** — Isolation Forest anomaly detector over
35
  conveyor/crane motor sensor readings (temperature, vibration, current,
36
- belt speed).
 
37
  4. **📊 Model Evaluation** — accuracy, macro-F1, confusion matrices,
38
  ROC-AUC, retrieval hit-rate, and latency benchmarks, all computed on
39
- held-out data by `build_artifacts.py`.
 
 
40
  5. **ℹ️ About** — project write-up, architecture diagram, tech stack.
41
 
42
  ## Quick start (local)
 
27
 
28
  1. **💬 AI Assistant** — ask free-text warehouse-ops questions; answers are
29
  grounded via TF-IDF retrieval over a small knowledge base and generated
30
+ by a hosted LLM (Hugging Face Inference API, with a multi-model fallback
31
+ chain), with a transparent retrieval-only fallback and a built-in
32
+ **"Test LLM connection" diagnostics button** if no API key is configured
33
+ or the call fails. Includes an "About the data" panel explaining the
34
+ knowledge base and training data.
35
  2. **📦 Inventory & Order Query** — natural-language queries over synthetic
36
+ inventory / order tables (SKU, zone, order-id extraction), with an
37
+ "About the data" panel describing the synthetic tables.
38
  3. **⚠️ Predictive Maintenance** — Isolation Forest anomaly detector over
39
  conveyor/crane motor sensor readings (temperature, vibration, current,
40
+ belt speed), with an "About the data" panel describing the synthetic
41
+ sensor dataset and failure patterns.
42
  4. **📊 Model Evaluation** — accuracy, macro-F1, confusion matrices,
43
  ROC-AUC, retrieval hit-rate, and latency benchmarks, all computed on
44
+ held-out data by `build_artifacts.py` and rendered as charts (bar
45
+ charts, confusion matrices, ROC curve, feature-distribution histograms)
46
+ alongside the underlying tables.
47
  5. **ℹ️ About** — project write-up, architecture diagram, tech stack.
48
 
49
  ## Quick start (local)
app.py CHANGED
@@ -30,7 +30,7 @@ from src.anomaly_model import score_reading
30
  from src.data_generation import generate_inventory_db, generate_orders_db
31
  from src.intent_model import INTENT_DESCRIPTIONS, load_pipeline, predict as intent_predict
32
  from src.inventory_db import query_inventory, query_orders
33
- from src.llm_client import answer_query
34
  from src.retriever import KBRetriever
35
 
36
  ROOT = os.path.dirname(os.path.abspath(__file__))
@@ -146,11 +146,33 @@ def chat_fn(message, history):
146
  f"**Generation:** {'LLM (' + response.model_id + ')' if response.used_llm else 'retrieval-only fallback'}"
147
  f" · {response.latency_s * 1000:.0f} ms"
148
  )
 
 
 
149
 
150
  full_reply = response.answer + "\n\n---\n" + "\n".join(meta_lines)
151
  return full_reply
152
 
153
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  ASSISTANT_EXAMPLES = [
155
  "The conveyor belt in Zone C is making noise",
156
  "How many units of SKU-1042 are in Zone B?",
@@ -226,7 +248,7 @@ def load_preset(name):
226
  # TAB 4 -- Model Evaluation
227
  # ==========================================================================
228
 
229
- def build_evaluation_markdown():
230
  cls_report = intent_eval.get("classification_report", {})
231
  per_class_rows = []
232
  for cls in intent_eval.get("classes", []):
@@ -236,19 +258,22 @@ def build_evaluation_markdown():
236
  f"{stats.get('f1-score', 0):.2f} | {int(stats.get('support', 0))} |"
237
  )
238
  per_class_table = "\n".join(per_class_rows)
 
 
239
 
240
- retrieval_rows = "\n".join(
241
- f"| {r['query']} | {r['expected']} | {r['retrieved_top1']} | "
242
- f"{'✅' if r['hit@1'] else ('〰️' if r['hit@2'] else '❌')} | {r['top1_score']:.2f} |"
243
- for r in retrieval_eval.get("rows", [])
244
- )
245
 
246
- md = f"""
247
- ## 1. Intent Classifier (TF-IDF + Logistic Regression)
 
 
 
248
 
249
- Trained on {intent_eval.get('n_train', '?')} examples, evaluated on a held-out
250
- stratified test split of {intent_eval.get('n_test', '?')} examples across
251
- {intent_eval.get('n_classes', '?')} intent classes.
252
 
253
  | Metric | Score |
254
  |---|---|
@@ -260,16 +285,28 @@ stratified test split of {intent_eval.get('n_test', '?')} examples across
260
  | Intent | Precision | Recall | F1 | Support |
261
  |---|---|---|---|---|
262
  {per_class_table}
 
263
 
264
- ![Confusion Matrix](assets/intent_confusion_matrix.png)
265
-
266
- ---
267
 
 
 
268
  ## 2. Predictive Maintenance Anomaly Detector (Isolation Forest)
269
 
270
- Trained unsupervised on scaled sensor features ({', '.join(SENSOR_FEATURES)}),
271
- evaluated against held-out ground-truth anomaly labels ({anomaly_eval.get('n_test', '?')} test readings,
272
- {anomaly_eval.get('test_anomaly_rate', 0):.1%} true anomaly rate).
 
 
 
 
 
 
 
 
 
 
 
 
273
 
274
  | Metric | Score |
275
  |---|---|
@@ -278,17 +315,27 @@ evaluated against held-out ground-truth anomaly labels ({anomaly_eval.get('n_tes
278
  | **F1 Score** | **{anomaly_eval.get('f1', 0):.2%}** |
279
  | **ROC-AUC** | **{anomaly_eval.get('roc_auc', 0):.3f}** |
280
  | Accuracy | {anomaly_eval.get('accuracy', 0):.2%} |
 
281
 
282
- ![Anomaly Confusion Matrix](assets/anomaly_confusion_matrix.png)
283
- ![ROC Curve](assets/anomaly_roc_curve.png)
284
-
285
- ---
286
 
 
 
 
 
 
 
 
287
  ## 3. Retrieval (RAG) Evaluation
288
 
289
- Hit-rate of the TF-IDF retriever against a hand-labelled query -> expected-document
290
- evaluation set (higher is better; hit@1 = correct doc ranked first, hit@2 = correct
291
- doc within top 2).
 
 
 
 
 
 
292
 
293
  | Metric | Score |
294
  |---|---|
@@ -298,20 +345,25 @@ doc within top 2).
298
  | Query | Expected Doc | Retrieved (top-1) | Hit | Score |
299
  |---|---|---|---|---|
300
  {retrieval_rows}
 
301
 
302
- ---
303
 
 
 
304
  ## 4. Latency Benchmark (per-request, CPU)
305
 
 
 
306
  | Component | Avg. latency |
307
  |---|---|
308
  | Intent classification | {latency_eval.get('intent_classifier_ms', '?')} ms |
309
  | Anomaly scoring | {latency_eval.get('anomaly_detector_ms', '?')} ms |
310
  | KB retrieval (TF-IDF) | {latency_eval.get('kb_retrieval_ms', '?')} ms |
311
- | LLM generation | Depends on hosted Inference API (measured live per-request in the Assistant tab) |
 
312
 
313
- ---
314
 
 
315
  ### Evaluation methodology notes
316
 
317
  - All datasets are **synthetically generated** (see `src/data_generation.py`) using
@@ -326,7 +378,8 @@ doc within top 2).
326
  - In a production deployment, all three components would be continuously
327
  re-evaluated against real WMS/WCS/sensor logs rather than synthetic data.
328
  """
329
- return md
 
330
 
331
 
332
  # ==========================================================================
@@ -452,6 +505,20 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue"), css=CUSTOM_CSS, title="
452
  "AGV routing, picking strategy, or general warehouse-automation concepts. "
453
  "Answers are grounded (RAG) in a small warehouse-operations knowledge base."
454
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
455
  gr.ChatInterface(
456
  fn=chat_fn,
457
  type="messages",
@@ -459,6 +526,15 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue"), css=CUSTOM_CSS, title="
459
  chatbot=gr.Chatbot(height=430, label="Warehouse Assistant", type="messages"),
460
  textbox=gr.Textbox(placeholder="e.g. The conveyor belt in Zone C is making noise"),
461
  )
 
 
 
 
 
 
 
 
 
462
 
463
  with gr.Tab("📦 Inventory & Order Query"):
464
  gr.Markdown(
@@ -466,6 +542,22 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue"), css=CUSTOM_CSS, title="
466
  "decides whether to query the inventory table or the orders table, then "
467
  "extracts SKU / order-id / zone slots to filter the result."
468
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
469
  with gr.Row():
470
  inv_input = gr.Textbox(label="Query", placeholder="How many units of SKU-1042 are in Zone B?", scale=4)
471
  inv_btn = gr.Button("Search", variant="primary", scale=1)
@@ -495,6 +587,21 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue"), css=CUSTOM_CSS, title="
495
  "for anomalous behaviour using an Isolation Forest model trained on "
496
  "historical sensor patterns."
497
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
498
  preset_dropdown = gr.Dropdown(
499
  choices=list(ANOMALY_PRESETS.keys()), label="Load a preset reading", value="Normal reading"
500
  )
@@ -518,10 +625,48 @@ with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue"), css=CUSTOM_CSS, title="
518
  )
519
 
520
  with gr.Tab("📊 Model Evaluation"):
521
- gr.Markdown(build_evaluation_markdown())
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
522
 
523
  with gr.Tab("ℹ️ About"):
524
  gr.Markdown(ABOUT_MD)
525
 
 
526
  if __name__ == "__main__":
527
  demo.launch(server_name="0.0.0.0", server_port=int(os.environ.get("PORT", 7860)))
 
30
  from src.data_generation import generate_inventory_db, generate_orders_db
31
  from src.intent_model import INTENT_DESCRIPTIONS, load_pipeline, predict as intent_predict
32
  from src.inventory_db import query_inventory, query_orders
33
+ from src.llm_client import answer_query, test_connection
34
  from src.retriever import KBRetriever
35
 
36
  ROOT = os.path.dirname(os.path.abspath(__file__))
 
146
  f"**Generation:** {'LLM (' + response.model_id + ')' if response.used_llm else 'retrieval-only fallback'}"
147
  f" · {response.latency_s * 1000:.0f} ms"
148
  )
149
+ if not response.used_llm and response.debug_errors:
150
+ err_lines = "\n".join(f" - `{e}`" for e in response.debug_errors)
151
+ meta_lines.append(f"**Why the LLM wasn't used:**\n{err_lines}")
152
 
153
  full_reply = response.answer + "\n\n---\n" + "\n".join(meta_lines)
154
  return full_reply
155
 
156
 
157
+ def test_llm_fn():
158
+ response = test_connection(retriever)
159
+ if response.used_llm:
160
+ return (
161
+ f"✅ **LLM connection working.** Model: `{response.model_id}` · "
162
+ f"{response.latency_s * 1000:.0f} ms\n\nSample answer: {response.answer}"
163
+ )
164
+ err_lines = "\n".join(f"- `{e}`" for e in response.debug_errors) or "(no error detail captured)"
165
+ return (
166
+ "❌ **LLM connection failed** — running in retrieval-only fallback mode.\n\n"
167
+ f"**Errors from each candidate model tried:**\n{err_lines}\n\n"
168
+ "**Common causes:** missing/invalid `HF_TOKEN` secret, the token's account "
169
+ "lacking Inference API access, or the candidate models being temporarily "
170
+ "unavailable on HF's free serverless tier. See `src/llm_client.py` to add "
171
+ "or reorder candidate models, or set the `LLM_MODEL_ID` secret to force a "
172
+ "specific one."
173
+ )
174
+
175
+
176
  ASSISTANT_EXAMPLES = [
177
  "The conveyor belt in Zone C is making noise",
178
  "How many units of SKU-1042 are in Zone B?",
 
248
  # TAB 4 -- Model Evaluation
249
  # ==========================================================================
250
 
251
+ def eval_intent_section_md():
252
  cls_report = intent_eval.get("classification_report", {})
253
  per_class_rows = []
254
  for cls in intent_eval.get("classes", []):
 
258
  f"{stats.get('f1-score', 0):.2f} | {int(stats.get('support', 0))} |"
259
  )
260
  per_class_table = "\n".join(per_class_rows)
261
+ return f"""
262
+ ## 1. Intent Classifier (TF-IDF + Logistic Regression)
263
 
264
+ **What it does:** routes a free-text query (e.g. *"The conveyor belt in Zone C
265
+ is making noise"*) into one of 8 operational categories, used by both the
266
+ AI Assistant and Inventory & Order Query tabs to decide how to handle a
267
+ request.
 
268
 
269
+ **Training data:** {intent_eval.get('n_train', '?') } synthetically generated
270
+ example queries (see chart below), built from ~8 hand-written templates per
271
+ category with randomised SKU codes, zone names, order IDs, and equipment IDs
272
+ slotted in -- e.g. *"How many units of {{sku}} are in {{zone}}?"*. This keeps
273
+ the language varied while being fully reproducible (`src/data_generation.py`).
274
 
275
+ Evaluated on a **held-out stratified test split** of {intent_eval.get('n_test', '?')}
276
+ examples the model never saw during training.
 
277
 
278
  | Metric | Score |
279
  |---|---|
 
285
  | Intent | Precision | Recall | F1 | Support |
286
  |---|---|---|---|---|
287
  {per_class_table}
288
+ """
289
 
 
 
 
290
 
291
+ def eval_anomaly_section_md():
292
+ return f"""
293
  ## 2. Predictive Maintenance Anomaly Detector (Isolation Forest)
294
 
295
+ **What it does:** flags abnormal conveyor/crane motor sensor readings
296
+ (temperature, vibration, current, belt speed) before they cause an
297
+ unplanned stoppage -- powers the Predictive Maintenance tab.
298
+
299
+ **Training data:** {900 + 100} synthetic sensor readings (900 "normal"
300
+ + 100 "anomaly" patterns), each with 4 features. Normal readings are drawn
301
+ from realistic operating ranges (e.g. ~55°C motor temp, ~2.2 mm/s vibration);
302
+ anomalies simulate bearing wear / misalignment / overload (elevated temp,
303
+ vibration, and current with reduced belt speed). See the distribution chart
304
+ below for exactly how these two classes differ.
305
+
306
+ The model itself is trained **unsupervised** (Isolation Forest never sees
307
+ the anomaly label during fitting) -- labels are used only to *evaluate* it
308
+ afterward, on a held-out test split of {anomaly_eval.get('n_test', '?')}
309
+ readings ({anomaly_eval.get('test_anomaly_rate', 0):.1%} true anomaly rate).
310
 
311
  | Metric | Score |
312
  |---|---|
 
315
  | **F1 Score** | **{anomaly_eval.get('f1', 0):.2%}** |
316
  | **ROC-AUC** | **{anomaly_eval.get('roc_auc', 0):.3f}** |
317
  | Accuracy | {anomaly_eval.get('accuracy', 0):.2%} |
318
+ """
319
 
 
 
 
 
320
 
321
+ def eval_retrieval_section_md():
322
+ retrieval_rows = "\n".join(
323
+ f"| {r['query']} | {r['expected']} | {r['retrieved_top1']} | "
324
+ f"{'✅' if r['hit@1'] else ('〰️' if r['hit@2'] else '❌')} | {r['top1_score']:.2f} |"
325
+ for r in retrieval_eval.get("rows", [])
326
+ )
327
+ return f"""
328
  ## 3. Retrieval (RAG) Evaluation
329
 
330
+ **What it does:** before the LLM answers a question, this component finds
331
+ the most relevant passages from a 10-article warehouse-operations knowledge
332
+ base (AS/RS, AGV/AMR, WMS, sortation, picking strategy, safety, etc. -- see
333
+ `src/knowledge_base.py`) using TF-IDF + cosine similarity, so the LLM answers
334
+ from real context rather than guessing.
335
+
336
+ **Evaluation data:** {retrieval_eval.get('n_queries', '?')} hand-labelled
337
+ (query, expected-article) pairs -- a small ground-truth set built by hand to
338
+ check the retriever finds the *right* article, not just *an* article.
339
 
340
  | Metric | Score |
341
  |---|---|
 
345
  | Query | Expected Doc | Retrieved (top-1) | Hit | Score |
346
  |---|---|---|---|---|
347
  {retrieval_rows}
348
+ """
349
 
 
350
 
351
+ def eval_latency_section_md():
352
+ return f"""
353
  ## 4. Latency Benchmark (per-request, CPU)
354
 
355
+ Average of 50 runs each, measured on the same CPU hardware the Space runs on.
356
+
357
  | Component | Avg. latency |
358
  |---|---|
359
  | Intent classification | {latency_eval.get('intent_classifier_ms', '?')} ms |
360
  | Anomaly scoring | {latency_eval.get('anomaly_detector_ms', '?')} ms |
361
  | KB retrieval (TF-IDF) | {latency_eval.get('kb_retrieval_ms', '?')} ms |
362
+ | LLM generation | Depends on the hosted Inference API (measured live per-request in the Assistant tab, not benchmarked here) |
363
+ """
364
 
 
365
 
366
+ EVAL_METHODOLOGY_MD = """
367
  ### Evaluation methodology notes
368
 
369
  - All datasets are **synthetically generated** (see `src/data_generation.py`) using
 
378
  - In a production deployment, all three components would be continuously
379
  re-evaluated against real WMS/WCS/sensor logs rather than synthetic data.
380
  """
381
+
382
+
383
 
384
 
385
  # ==========================================================================
 
505
  "AGV routing, picking strategy, or general warehouse-automation concepts. "
506
  "Answers are grounded (RAG) in a small warehouse-operations knowledge base."
507
  )
508
+ with gr.Accordion("ℹ️ About the data behind this tab", open=False):
509
+ gr.Markdown(
510
+ "- **Knowledge base (RAG source):** 10 original, hand-written articles "
511
+ "covering AS/RS, AGV/AMR, WMS, conveyor/sortation, picking strategy, "
512
+ "predictive maintenance, safety protocol, inventory accuracy, KPIs, and "
513
+ "energy efficiency (`src/knowledge_base.py`). Every answer's *Retrieved "
514
+ "context* line shows exactly which article(s) it drew on.\n"
515
+ "- **Intent classifier:** trained on ~480 synthetically generated example "
516
+ "queries across 8 categories (see the Model Evaluation tab for accuracy).\n"
517
+ "- **LLM:** a hosted instruct model called via the Hugging Face Inference "
518
+ "API — not run locally. If no `HF_TOKEN` is configured, or the API call "
519
+ "fails, this tab automatically falls back to showing the retrieved "
520
+ "knowledge-base passages directly, so it never just breaks."
521
+ )
522
  gr.ChatInterface(
523
  fn=chat_fn,
524
  type="messages",
 
526
  chatbot=gr.Chatbot(height=430, label="Warehouse Assistant", type="messages"),
527
  textbox=gr.Textbox(placeholder="e.g. The conveyor belt in Zone C is making noise"),
528
  )
529
+ with gr.Accordion("🔧 LLM connection diagnostics", open=False):
530
+ gr.Markdown(
531
+ "If the assistant keeps answering in retrieval-only fallback mode, "
532
+ "click below to test the LLM connection directly and see the exact "
533
+ "error from each candidate model."
534
+ )
535
+ test_llm_btn = gr.Button("Test LLM connection")
536
+ test_llm_output = gr.Markdown()
537
+ test_llm_btn.click(test_llm_fn, inputs=None, outputs=test_llm_output)
538
 
539
  with gr.Tab("📦 Inventory & Order Query"):
540
  gr.Markdown(
 
542
  "decides whether to query the inventory table or the orders table, then "
543
  "extracts SKU / order-id / zone slots to filter the result."
544
  )
545
+ with gr.Accordion("ℹ️ About the data behind this tab", open=False):
546
+ gr.Markdown(
547
+ f"- **Inventory table:** {len(inventory_df)} synthetic SKUs across 5 "
548
+ "categories (Electronics, Apparel, Automotive Parts, Food & Beverage, "
549
+ "Household) and 4 warehouse zones, with randomised on-hand quantities, "
550
+ "reorder points, and unit costs.\n"
551
+ f"- **Orders table:** {len(orders_df)} synthetic orders with randomised "
552
+ "status (Received / Picking / Packed / Shipped / Delayed), line count, "
553
+ "priority, and zone.\n"
554
+ "- Both tables are generated by `src/data_generation.py` with a fixed "
555
+ "random seed, so they're reproducible but **not real operational data** "
556
+ "-- this is a stand-in for a live WMS/WCS query interface.\n"
557
+ "- Query parsing is regex-based slot extraction (SKU codes like `SKU-1042`, "
558
+ "order IDs like `#10007`, zone names) combined with the same intent "
559
+ "classifier used in the AI Assistant tab (`src/inventory_db.py`)."
560
+ )
561
  with gr.Row():
562
  inv_input = gr.Textbox(label="Query", placeholder="How many units of SKU-1042 are in Zone B?", scale=4)
563
  inv_btn = gr.Button("Search", variant="primary", scale=1)
 
587
  "for anomalous behaviour using an Isolation Forest model trained on "
588
  "historical sensor patterns."
589
  )
590
+ with gr.Accordion("ℹ️ About the data behind this tab", open=False):
591
+ gr.Markdown(
592
+ "- **Training data:** 1,000 synthetic sensor readings (900 normal + 100 "
593
+ "anomalous) across 4 features -- motor temperature, vibration, motor "
594
+ "current, and belt speed -- generated by `src/data_generation.py`. "
595
+ "Anomalies simulate realistic failure signatures: elevated temperature, "
596
+ "vibration, and current combined with reduced/erratic belt speed (the "
597
+ "pattern of bearing wear, belt misalignment, or motor overload).\n"
598
+ "- **Model:** Isolation Forest (unsupervised) trained on scaled features "
599
+ "-- it never sees a 'this is an anomaly' label during training, only "
600
+ "learns what 'normal' looks like and flags deviations from it.\n"
601
+ "- See the **Model Evaluation** tab for the feature-distribution chart "
602
+ "showing exactly how normal vs. anomalous readings differ, plus "
603
+ "precision/recall/F1/ROC-AUC on held-out data."
604
+ )
605
  preset_dropdown = gr.Dropdown(
606
  choices=list(ANOMALY_PRESETS.keys()), label="Load a preset reading", value="Normal reading"
607
  )
 
625
  )
626
 
627
  with gr.Tab("📊 Model Evaluation"):
628
+ gr.Markdown(
629
+ "Every metric on this tab is computed on **held-out test data** by "
630
+ "`build_artifacts.py` (not cherry-picked from a live demo run) -- "
631
+ "re-run that script any time to reproduce these numbers from scratch."
632
+ )
633
+
634
+ gr.Markdown(eval_intent_section_md())
635
+ gr.Markdown("**Dataset composition** (how many training examples per intent):")
636
+ gr.Image(os.path.join(ASSETS_DIR, "intent_dataset_composition.png"), show_label=False, container=False)
637
+ gr.Markdown("**Per-class precision / recall / F1:**")
638
+ gr.Image(os.path.join(ASSETS_DIR, "intent_per_class_bar.png"), show_label=False, container=False)
639
+ gr.Markdown("**Confusion matrix:**")
640
+ gr.Image(os.path.join(ASSETS_DIR, "intent_confusion_matrix.png"), show_label=False, container=False)
641
+
642
+ gr.Markdown("---")
643
+ gr.Markdown(eval_anomaly_section_md())
644
+ gr.Markdown("**Sensor feature distributions (normal vs. anomaly):**")
645
+ gr.Image(os.path.join(ASSETS_DIR, "sensor_distributions.png"), show_label=False, container=False)
646
+ with gr.Row():
647
+ with gr.Column():
648
+ gr.Markdown("**Evaluation metrics:**")
649
+ gr.Image(os.path.join(ASSETS_DIR, "anomaly_metrics_bar.png"), show_label=False, container=False)
650
+ with gr.Column():
651
+ gr.Markdown("**Confusion matrix:**")
652
+ gr.Image(os.path.join(ASSETS_DIR, "anomaly_confusion_matrix.png"), show_label=False, container=False)
653
+ gr.Markdown("**ROC curve:**")
654
+ gr.Image(os.path.join(ASSETS_DIR, "anomaly_roc_curve.png"), show_label=False, container=False)
655
+
656
+ gr.Markdown("---")
657
+ gr.Markdown(eval_retrieval_section_md())
658
+ gr.Image(os.path.join(ASSETS_DIR, "retrieval_hitrate_bar.png"), show_label=False, container=False)
659
+
660
+ gr.Markdown("---")
661
+ gr.Markdown(eval_latency_section_md())
662
+ gr.Image(os.path.join(ASSETS_DIR, "latency_bar.png"), show_label=False, container=False)
663
+
664
+ gr.Markdown("---")
665
+ gr.Markdown(EVAL_METHODOLOGY_MD)
666
 
667
  with gr.Tab("ℹ️ About"):
668
  gr.Markdown(ABOUT_MD)
669
 
670
+
671
  if __name__ == "__main__":
672
  demo.launch(server_name="0.0.0.0", server_port=int(os.environ.get("PORT", 7860)))
assets/anomaly_metrics_bar.png ADDED
assets/intent_dataset_composition.png ADDED
assets/intent_per_class_bar.png ADDED
assets/latency_bar.png ADDED
assets/retrieval_hitrate_bar.png ADDED
assets/sensor_distributions.png ADDED
build_artifacts.py CHANGED
@@ -98,6 +98,27 @@ def build_intent_classifier():
98
  pipeline_full.fit(df["text"], df["intent"])
99
  save_pipeline(pipeline_full, os.path.join(MODELS_DIR, "intent_pipeline.joblib"))
100
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  metrics = {
102
  "accuracy": acc,
103
  "macro_f1": macro_f1,
@@ -109,6 +130,18 @@ def build_intent_classifier():
109
  }
110
  with open(os.path.join(DATA_DIR, "intent_eval.json"), "w") as f:
111
  json.dump(metrics, f, indent=2)
 
 
 
 
 
 
 
 
 
 
 
 
112
  return metrics
113
 
114
 
@@ -204,6 +237,45 @@ def build_anomaly_detector():
204
  }
205
  with open(os.path.join(DATA_DIR, "anomaly_eval.json"), "w") as f:
206
  json.dump(metrics, f, indent=2)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
207
  return metrics
208
 
209
 
@@ -238,6 +310,21 @@ def build_retrieval_eval():
238
  print(f"hit@1={metrics['hit_rate_at_1']:.2f} hit@2={metrics['hit_rate_at_2']:.2f}")
239
  with open(os.path.join(DATA_DIR, "retrieval_eval.json"), "w") as f:
240
  json.dump(metrics, f, indent=2)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
241
  return metrics
242
 
243
 
@@ -287,6 +374,19 @@ def build_latency_benchmark(intent_metrics, anomaly_metrics):
287
  json.dump(latency, f, indent=2)
288
  print(latency)
289
 
 
 
 
 
 
 
 
 
 
 
 
 
 
290
 
291
  if __name__ == "__main__":
292
  intent_metrics = build_intent_classifier()
 
98
  pipeline_full.fit(df["text"], df["intent"])
99
  save_pipeline(pipeline_full, os.path.join(MODELS_DIR, "intent_pipeline.joblib"))
100
 
101
+ # Per-class precision/recall/F1 bar chart (clearer at a glance than the table alone)
102
+ fig, ax = plt.subplots(figsize=(9, 5))
103
+ x = np.arange(len(labels))
104
+ width = 0.25
105
+ precisions = [report[l]["precision"] for l in labels]
106
+ recalls = [report[l]["recall"] for l in labels]
107
+ f1s = [report[l]["f1-score"] for l in labels]
108
+ ax.bar(x - width, precisions, width, label="Precision", color="#3b82f6")
109
+ ax.bar(x, recalls, width, label="Recall", color="#10b981")
110
+ ax.bar(x + width, f1s, width, label="F1", color="#f59e0b")
111
+ ax.set_xticks(x)
112
+ ax.set_xticklabels(labels, rotation=35, ha="right", fontsize=8)
113
+ ax.set_ylim(0, 1.15)
114
+ ax.set_ylabel("Score")
115
+ ax.set_title("Intent Classifier: Per-Class Precision / Recall / F1")
116
+ ax.legend(loc="lower right", ncol=3)
117
+ ax.grid(axis="y", alpha=0.3)
118
+ fig.tight_layout()
119
+ fig.savefig(os.path.join(ASSETS_DIR, "intent_per_class_bar.png"), dpi=150)
120
+ plt.close(fig)
121
+
122
  metrics = {
123
  "accuracy": acc,
124
  "macro_f1": macro_f1,
 
130
  }
131
  with open(os.path.join(DATA_DIR, "intent_eval.json"), "w") as f:
132
  json.dump(metrics, f, indent=2)
133
+
134
+ # Dataset composition chart (helps a reader understand what the model was trained on)
135
+ counts = df["intent"].value_counts().reindex(labels)
136
+ fig, ax = plt.subplots(figsize=(8, 4.5))
137
+ ax.barh(labels, counts.values, color="#6366f1")
138
+ ax.set_xlabel("Number of examples")
139
+ ax.set_title(f"Intent Dataset Composition (n={len(df)}, synthetic, templated)")
140
+ ax.grid(axis="x", alpha=0.3)
141
+ fig.tight_layout()
142
+ fig.savefig(os.path.join(ASSETS_DIR, "intent_dataset_composition.png"), dpi=150)
143
+ plt.close(fig)
144
+
145
  return metrics
146
 
147
 
 
237
  }
238
  with open(os.path.join(DATA_DIR, "anomaly_eval.json"), "w") as f:
239
  json.dump(metrics, f, indent=2)
240
+
241
+ # Metrics bar chart
242
+ fig, ax = plt.subplots(figsize=(6.5, 4.5))
243
+ metric_names = ["Precision", "Recall", "F1", "ROC-AUC", "Accuracy"]
244
+ metric_vals = [precision, recall, f1, roc_auc, acc]
245
+ bars = ax.bar(metric_names, metric_vals, color=["#3b82f6", "#10b981", "#f59e0b", "#8b5cf6", "#ef4444"])
246
+ ax.set_ylim(0, 1.15)
247
+ ax.set_ylabel("Score")
248
+ ax.set_title("Anomaly Detector: Evaluation Metrics")
249
+ ax.grid(axis="y", alpha=0.3)
250
+ for bar, val in zip(bars, metric_vals):
251
+ ax.text(bar.get_x() + bar.get_width() / 2, val + 0.03, f"{val:.2f}", ha="center", fontsize=9)
252
+ fig.tight_layout()
253
+ fig.savefig(os.path.join(ASSETS_DIR, "anomaly_metrics_bar.png"), dpi=150)
254
+ plt.close(fig)
255
+
256
+ # Sensor feature distributions: normal vs anomaly (helps a reader see *why*
257
+ # the model flags what it flags -- directly supports the Predictive
258
+ # Maintenance tab's sliders)
259
+ fig, axes = plt.subplots(2, 2, figsize=(10, 7))
260
+ titles = {
261
+ "motor_temp_c": "Motor Temperature (°C)",
262
+ "vibration_mm_s": "Vibration (mm/s)",
263
+ "current_amps": "Motor Current (A)",
264
+ "belt_speed_mps": "Belt Speed (m/s)",
265
+ }
266
+ for ax, feat in zip(axes.flat, FEATURES):
267
+ normal_vals = df.loc[df["label"] == 0, feat]
268
+ anomaly_vals = df.loc[df["label"] == 1, feat]
269
+ ax.hist(normal_vals, bins=25, alpha=0.6, label="Normal", color="#10b981")
270
+ ax.hist(anomaly_vals, bins=25, alpha=0.6, label="Anomaly", color="#ef4444")
271
+ ax.set_title(titles[feat], fontsize=10)
272
+ ax.legend(fontsize=8)
273
+ ax.grid(alpha=0.3)
274
+ fig.suptitle("Sensor Feature Distributions: Normal vs. Anomaly (synthetic training data)", fontsize=11)
275
+ fig.tight_layout()
276
+ fig.savefig(os.path.join(ASSETS_DIR, "sensor_distributions.png"), dpi=150)
277
+ plt.close(fig)
278
+
279
  return metrics
280
 
281
 
 
310
  print(f"hit@1={metrics['hit_rate_at_1']:.2f} hit@2={metrics['hit_rate_at_2']:.2f}")
311
  with open(os.path.join(DATA_DIR, "retrieval_eval.json"), "w") as f:
312
  json.dump(metrics, f, indent=2)
313
+
314
+ fig, ax = plt.subplots(figsize=(4.5, 4))
315
+ bars = ax.bar(["Hit Rate @ 1", "Hit Rate @ 2"],
316
+ [metrics["hit_rate_at_1"], metrics["hit_rate_at_2"]],
317
+ color=["#3b82f6", "#10b981"])
318
+ ax.set_ylim(0, 1.15)
319
+ ax.set_ylabel("Hit rate")
320
+ ax.set_title(f"RAG Retriever Hit Rate (n={n} labelled queries)")
321
+ ax.grid(axis="y", alpha=0.3)
322
+ for bar, val in zip(bars, [metrics["hit_rate_at_1"], metrics["hit_rate_at_2"]]):
323
+ ax.text(bar.get_x() + bar.get_width() / 2, val + 0.03, f"{val:.0%}", ha="center", fontsize=10)
324
+ fig.tight_layout()
325
+ fig.savefig(os.path.join(ASSETS_DIR, "retrieval_hitrate_bar.png"), dpi=150)
326
+ plt.close(fig)
327
+
328
  return metrics
329
 
330
 
 
374
  json.dump(latency, f, indent=2)
375
  print(latency)
376
 
377
+ fig, ax = plt.subplots(figsize=(6, 4))
378
+ components = ["Intent\nclassifier", "Anomaly\ndetector", "KB\nretrieval"]
379
+ values = [intent_ms, anomaly_ms, retrieval_ms]
380
+ bars = ax.bar(components, values, color=["#3b82f6", "#f59e0b", "#10b981"])
381
+ ax.set_ylabel("Latency (ms, avg of 50 runs)")
382
+ ax.set_title("Local Component Latency (CPU)")
383
+ ax.grid(axis="y", alpha=0.3)
384
+ for bar, val in zip(bars, values):
385
+ ax.text(bar.get_x() + bar.get_width() / 2, val, f"{val:.2f} ms", ha="center", va="bottom", fontsize=9)
386
+ fig.tight_layout()
387
+ fig.savefig(os.path.join(ASSETS_DIR, "latency_bar.png"), dpi=150)
388
+ plt.close(fig)
389
+
390
 
391
  if __name__ == "__main__":
392
  intent_metrics = build_intent_classifier()
data/intent_dataset.csv CHANGED
@@ -1,5 +1,5 @@
1
  text,intent
2
- Is order #37898 delayed?,order_status
3
  Is the sorter in Zone C running normally?,system_status
4
  What is the uptime for Sorter-02 today?,system_status
5
  Recommend a picking strategy for high-velocity SKUs,picking_optimization
@@ -7,70 +7,70 @@ Is the sorter in the receiving dock running normally?,system_status
7
  The sorter in the mezzanine keeps jamming,equipment_maintenance
8
  Optimize the pick path for Zone D,picking_optimization
9
  Is Crane-03 operational?,system_status
10
- Has order #26915 shipped yet?,order_status
11
  What's the difference between AGV and AMR?,general_faq
12
- What is the current stock level for SKU-7663?,inventory_check
13
  Optimize the pick path for the receiving dock,picking_optimization
14
  What's the difference between AGV and AMR?,general_faq
15
  How can we reduce travel time for pickers in Zone C?,picking_optimization
16
- What is the current stock level for SKU-1214?,inventory_check
17
- What's the status of order #50538?,order_status
18
- How much inventory is left for SKU-4959?,inventory_check
19
  What is a WMS?,general_faq
20
- Is SKU-9180 in stock at Zone A?,inventory_check
21
  Send AGV AMR-21 to Zone B,agv_navigation
22
  Redirect Sorter-02 around the blocked aisle in Zone B,agv_navigation
23
  Explain how an AS/RS works,general_faq
24
- When will order #66314 be delivered?,order_status
25
- What's the fastest picking route for order #52993?,picking_optimization
26
- Why hasn't order #81176 left the dock yet?,order_status
27
  What KPIs matter most in warehouse automation?,general_faq
28
  File an incident report for Zone D,safety_incident
29
  "A worker slipped near AMR-21, please log it",safety_incident
30
  "A worker slipped near Sorter-02, please log it",safety_incident
31
- What is the current stock level for SKU-1705?,inventory_check
32
  Is Crane-03 operational?,system_status
33
- What is the current stock level for SKU-1151?,inventory_check
34
  Are all cranes online in Zone D?,system_status
35
  What is predictive maintenance?,general_faq
36
  What is the uptime for AMR-21 today?,system_status
37
- Track order #76958 for me,order_status
38
  Log a safety incident involving Crane-05,safety_incident
39
  "Belt AGV-12 stopped unexpectedly, please check",equipment_maintenance
40
  What KPIs matter most in warehouse automation?,general_faq
41
- Check inventory count for SKU-1240 in the mezzanine,inventory_check
42
  A forklift near-miss was reported in the receiving dock,safety_incident
43
  Why is AGV-12 stuck near Zone D?,agv_navigation
44
- Has order #36763 shipped yet?,order_status
45
  What is the current location of AGV-07?,agv_navigation
46
- Do we have enough SKU-5968 to fulfill 200 units?,inventory_check
47
  Report unsafe pallet stacking in Zone D,safety_incident
48
  What's the difference between AGV and AMR?,general_faq
49
- Track order #45880 for me,order_status
50
  "Belt AGV-07 stopped unexpectedly, please check",equipment_maintenance
51
- Is order #77822 delayed?,order_status
52
  What is the uptime for Conveyor-14 today?,system_status
53
  There was a near collision between AGV-12 and a pedestrian in Zone B,safety_incident
54
  Is Sorter-02 operational?,system_status
55
  How does goods-to-person picking work?,general_faq
56
  Report unsafe pallet stacking in Zone A,safety_incident
57
  Suggest a wave picking plan for Zone C,picking_optimization
58
- Has order #69175 shipped yet?,order_status
59
- Show the fulfillment status of #72615,order_status
60
  What's the difference between AGV and AMR?,general_faq
61
- Why hasn't order #13114 left the dock yet?,order_status
62
  What's the difference between AGV and AMR?,general_faq
63
- What's the fastest picking route for order #22223?,picking_optimization
64
- Show the fulfillment status of #80304,order_status
65
  Schedule maintenance for AMR-21,equipment_maintenance
66
  Redirect Crane-03 around the blocked aisle in Zone D,agv_navigation
67
  Report unsafe pallet stacking in the receiving dock,safety_incident
68
  Report unsafe pallet stacking in Zone D,safety_incident
69
- What's the status of order #84458?,order_status
70
- What's the status of order #26699?,order_status
71
  What is the current location of Sorter-02?,agv_navigation
72
  "A worker slipped near Crane-03, please log it",safety_incident
73
- Track order #37216 for me,order_status
74
  Route Conveyor-14 to picking station 7,agv_navigation
75
  "Belt AGV-12 stopped unexpectedly, please check",equipment_maintenance
76
  AGV-12 motor temperature seems high,equipment_maintenance
@@ -78,27 +78,27 @@ Crane Crane-05 reported a fault code,equipment_maintenance
78
  Suggest a wave picking plan for Zone A,picking_optimization
79
  Explain how an AS/RS works,general_faq
80
  A forklift near-miss was reported in Zone D,safety_incident
81
- Is order #19388 delayed?,order_status
82
  How do sortation systems decide where to route a parcel?,general_faq
83
- Give me stock levels across all zones for SKU-5790,inventory_check
84
  The sorter in Zone D keeps jamming,equipment_maintenance
85
  Explain how an AS/RS works,general_faq
86
- Check inventory count for SKU-9378 in Zone D,inventory_check
87
  There was a near collision between Crane-05 and a pedestrian in Zone D,safety_incident
88
  A forklift near-miss was reported in the mezzanine,safety_incident
89
- How many units of SKU-1573 are in Zone D?,inventory_check
90
  Report unsafe pallet stacking in the receiving dock,safety_incident
91
  Reassign Sorter-02 to charging station,agv_navigation
92
  What KPIs matter most in warehouse automation?,general_faq
93
  Redirect AGV-12 around the blocked aisle in Zone A,agv_navigation
94
  Route AGV-12 to picking station 3,agv_navigation
95
  Check system health for the receiving dock,system_status
96
- Show me the on-hand quantity of SKU-7096,inventory_check
97
  Check system health for Zone A,system_status
98
  Crane AMR-21 reported a fault code,equipment_maintenance
99
  Redirect AMR-21 around the blocked aisle in the mezzanine,agv_navigation
100
  What KPIs matter most in warehouse automation?,general_faq
101
- Check inventory count for SKU-9515 in Zone C,inventory_check
102
  Is the sorter in Zone A running normally?,system_status
103
  What is the uptime for Conveyor-14 today?,system_status
104
  Crane AGV-12 reported a fault code,equipment_maintenance
@@ -106,94 +106,94 @@ What is predictive maintenance?,general_faq
106
  Redirect AMR-21 around the blocked aisle in Zone B,agv_navigation
107
  Reassign Crane-05 to charging station,agv_navigation
108
  How do sortation systems decide where to route a parcel?,general_faq
109
- Give me stock levels across all zones for SKU-3527,inventory_check
110
  What KPIs matter most in warehouse automation?,general_faq
111
- Do we have enough SKU-7090 to fulfill 200 units?,inventory_check
112
  Schedule maintenance for Conveyor-14,equipment_maintenance
113
  Is AGV-07 operational?,system_status
114
  Crane Conveyor-14 reported a fault code,equipment_maintenance
115
  What is predictive maintenance?,general_faq
116
  What's the difference between AGV and AMR?,general_faq
117
- What is the current stock level for SKU-3744?,inventory_check
118
  Report vibration issue on Sorter-02,equipment_maintenance
119
  How can we reduce travel time for pickers in Zone B?,picking_optimization
120
  Is Crane-05 operational?,system_status
121
- Give me stock levels across all zones for SKU-5721,inventory_check
122
- Show me the on-hand quantity of SKU-5559,inventory_check
123
- Track order #19300 for me,order_status
124
  Is Crane-05 operational?,system_status
125
- Show the fulfillment status of #13571,order_status
126
- Show me the on-hand quantity of SKU-5098,inventory_check
127
- Why hasn't order #10859 left the dock yet?,order_status
128
  Report vibration issue on AMR-21,equipment_maintenance
129
  File an incident report for Zone B,safety_incident
130
  How does goods-to-person picking work?,general_faq
131
  What is predictive maintenance?,general_faq
132
- Show the fulfillment status of #96688,order_status
133
  Report unsafe pallet stacking in the receiving dock,safety_incident
134
  Redirect AMR-21 around the blocked aisle in the mezzanine,agv_navigation
135
- Is SKU-4451 in stock at Zone B?,inventory_check
136
  Why is Conveyor-14 stuck near the receiving dock?,agv_navigation
137
  How can we reduce travel time for pickers in Zone A?,picking_optimization
138
  What is the uptime for Sorter-02 today?,system_status
139
- Do we have enough SKU-8632 to fulfill 200 units?,inventory_check
140
- What's the status of order #39040?,order_status
141
- How much inventory is left for SKU-9838?,inventory_check
142
- Check inventory count for SKU-4526 in Zone C,inventory_check
143
  What KPIs matter most in warehouse automation?,general_faq
144
  Is Crane-05 operational?,system_status
145
- How many units of SKU-7701 are in Zone A?,inventory_check
146
  What KPIs matter most in warehouse automation?,general_faq
147
- Is order #29501 delayed?,order_status
148
- Track order #16617 for me,order_status
149
  Report unsafe pallet stacking in Zone B,safety_incident
150
  How can we reduce travel time for pickers in Zone D?,picking_optimization
151
- Check inventory count for SKU-3493 in the receiving dock,inventory_check
152
  Report unsafe pallet stacking in Zone C,safety_incident
153
  What is the current location of Crane-05?,agv_navigation
154
- Give me stock levels across all zones for SKU-6612,inventory_check
155
- Is SKU-1080 in stock at Zone C?,inventory_check
156
  What is predictive maintenance?,general_faq
157
- Is order #42539 delayed?,order_status
158
- How many units of SKU-2112 are in the mezzanine?,inventory_check
159
  Schedule maintenance for AGV-12,equipment_maintenance
160
  What KPIs matter most in warehouse automation?,general_faq
161
- Is order #71287 delayed?,order_status
162
- Show the fulfillment status of #96666,order_status
163
  Should we batch pick these orders together?,picking_optimization
164
  How do sortation systems decide where to route a parcel?,general_faq
165
  The sorter in the mezzanine keeps jamming,equipment_maintenance
166
  File an incident report for the mezzanine,safety_incident
167
  Give me the current status of the WMS integration,system_status
168
- What's the fastest picking route for order #67193?,picking_optimization
169
  How can we reduce travel time for pickers in Zone D?,picking_optimization
170
  Why is Sorter-02 stuck near the receiving dock?,agv_navigation
171
  What is predictive maintenance?,general_faq
172
  Report vibration issue on Conveyor-14,equipment_maintenance
173
  File an incident report for the receiving dock,safety_incident
174
- Has order #11872 shipped yet?,order_status
175
  Redirect AMR-21 around the blocked aisle in Zone D,agv_navigation
176
  Schedule maintenance for AMR-21,equipment_maintenance
177
  What is the uptime for Sorter-02 today?,system_status
178
  Send AGV AMR-21 to Zone D,agv_navigation
179
  Route AGV-12 to picking station 7,agv_navigation
180
- Has order #23013 shipped yet?,order_status
181
  Reassign Conveyor-14 to charging station,agv_navigation
182
  The sorter in Zone D keeps jamming,equipment_maintenance
183
  Should we batch pick these orders together?,picking_optimization
184
  "Belt AGV-07 stopped unexpectedly, please check",equipment_maintenance
185
  Give me the current status of the WMS integration,system_status
186
  Are all cranes online in Zone C?,system_status
187
- Track order #30107 for me,order_status
188
  Check system health for the mezzanine,system_status
189
  Report vibration issue on AMR-21,equipment_maintenance
190
  "A worker slipped near Crane-03, please log it",safety_incident
191
  Route Conveyor-14 to picking station 7,agv_navigation
192
- When will order #20466 be delivered?,order_status
193
  Suggest a wave picking plan for Zone A,picking_optimization
194
  What is the uptime for Conveyor-14 today?,system_status
195
  Route AGV-12 to picking station 7,agv_navigation
196
- Is order #77099 delayed?,order_status
197
  Suggest a wave picking plan for Zone A,picking_optimization
198
  Check system health for the receiving dock,system_status
199
  How do sortation systems decide where to route a parcel?,general_faq
@@ -203,18 +203,18 @@ A forklift near-miss was reported in Zone A,safety_incident
203
  What is the uptime for Sorter-02 today?,system_status
204
  Is Conveyor-14 operational?,system_status
205
  Are all cranes online in the mezzanine?,system_status
206
- Do we have enough SKU-8857 to fulfill 200 units?,inventory_check
207
  Why is Conveyor-14 stuck near the receiving dock?,agv_navigation
208
  Log a breakdown for Conveyor-14 in Zone A,equipment_maintenance
209
  File an incident report for Zone D,safety_incident
210
  Why is AGV-12 stuck near Zone A?,agv_navigation
211
  Recommend a picking strategy for high-velocity SKUs,picking_optimization
212
  Should we batch pick these orders together?,picking_optimization
213
- Show me the on-hand quantity of SKU-5184,inventory_check
214
- Has order #84530 shipped yet?,order_status
215
  Redirect Conveyor-14 around the blocked aisle in Zone C,agv_navigation
216
  Is AMR-21 operational?,system_status
217
- How many units of SKU-2141 are in Zone B?,inventory_check
218
  "A worker slipped near AGV-07, please log it",safety_incident
219
  A forklift near-miss was reported in Zone D,safety_incident
220
  "Belt Conveyor-14 stopped unexpectedly, please check",equipment_maintenance
@@ -222,12 +222,12 @@ Log a breakdown for AGV-07 in Zone D,equipment_maintenance
222
  Crane AMR-21 reported a fault code,equipment_maintenance
223
  Is Conveyor-14 operational?,system_status
224
  Why is Crane-05 stuck near Zone B?,agv_navigation
225
- What's the fastest picking route for order #52316?,picking_optimization
226
- Show me the on-hand quantity of SKU-8644,inventory_check
227
  Is the sorter in Zone D running normally?,system_status
228
- When will order #59204 be delivered?,order_status
229
- When will order #59602 be delivered?,order_status
230
- How many units of SKU-8300 are in Zone A?,inventory_check
231
  What is the uptime for Crane-03 today?,system_status
232
  The conveyor belt in the mezzanine is making noise,equipment_maintenance
233
  What is predictive maintenance?,general_faq
@@ -237,31 +237,31 @@ Optimize the pick path for Zone B,picking_optimization
237
  A forklift near-miss was reported in Zone C,safety_incident
238
  How does goods-to-person picking work?,general_faq
239
  Reassign AGV-07 to charging station,agv_navigation
240
- Track order #11091 for me,order_status
241
  Crane-03 motor temperature seems high,equipment_maintenance
242
  The sorter in Zone D keeps jamming,equipment_maintenance
243
  Should we batch pick these orders together?,picking_optimization
244
  Crane AGV-12 reported a fault code,equipment_maintenance
245
- What is the current stock level for SKU-8634?,inventory_check
246
- What's the status of order #52708?,order_status
247
  Check system health for the mezzanine,system_status
248
- Show the fulfillment status of #26180,order_status
249
  What's the difference between AGV and AMR?,general_faq
250
  The sorter in the mezzanine keeps jamming,equipment_maintenance
251
  File an incident report for the mezzanine,safety_incident
252
- What's the status of order #77245?,order_status
253
  Log a breakdown for Crane-05 in Zone C,equipment_maintenance
254
  Send AGV Conveyor-14 to Zone D,agv_navigation
255
  Is AMR-21 operational?,system_status
256
  Are all cranes online in Zone A?,system_status
257
  Should we batch pick these orders together?,picking_optimization
258
- When will order #18447 be delivered?,order_status
259
  What is the uptime for Crane-05 today?,system_status
260
  Report vibration issue on Crane-03,equipment_maintenance
261
  Reassign Crane-05 to charging station,agv_navigation
262
  Redirect Crane-05 around the blocked aisle in the mezzanine,agv_navigation
263
  Suggest a wave picking plan for Zone A,picking_optimization
264
- What's the fastest picking route for order #11864?,picking_optimization
265
  How can we reduce travel time for pickers in the receiving dock?,picking_optimization
266
  "A worker slipped near Crane-05, please log it",safety_incident
267
  How can we reduce travel time for pickers in the receiving dock?,picking_optimization
@@ -282,7 +282,7 @@ Log a safety incident involving Crane-03,safety_incident
282
  What KPIs matter most in warehouse automation?,general_faq
283
  A forklift near-miss was reported in Zone C,safety_incident
284
  What KPIs matter most in warehouse automation?,general_faq
285
- Is order #74973 delayed?,order_status
286
  Crane Crane-03 reported a fault code,equipment_maintenance
287
  Suggest a wave picking plan for Zone C,picking_optimization
288
  A forklift near-miss was reported in Zone B,safety_incident
@@ -296,7 +296,7 @@ Log a breakdown for AMR-21 in Zone A,equipment_maintenance
296
  Reassign Conveyor-14 to charging station,agv_navigation
297
  Suggest a wave picking plan for Zone D,picking_optimization
298
  What is the current location of Crane-05?,agv_navigation
299
- What's the status of order #87757?,order_status
300
  The conveyor belt in the receiving dock is making noise,equipment_maintenance
301
  A forklift near-miss was reported in Zone C,safety_incident
302
  Route Sorter-02 to picking station 12,agv_navigation
@@ -305,58 +305,58 @@ A forklift near-miss was reported in Zone A,safety_incident
305
  "Belt Crane-05 stopped unexpectedly, please check",equipment_maintenance
306
  Should we batch pick these orders together?,picking_optimization
307
  Are all cranes online in Zone A?,system_status
308
- Track order #36358 for me,order_status
309
  A forklift near-miss was reported in the receiving dock,safety_incident
310
  Report unsafe pallet stacking in the receiving dock,safety_incident
311
  AGV-12 motor temperature seems high,equipment_maintenance
312
  Is Sorter-02 operational?,system_status
313
- Show me the on-hand quantity of SKU-2270,inventory_check
314
  What KPIs matter most in warehouse automation?,general_faq
315
- Is order #22755 delayed?,order_status
316
  Suggest a wave picking plan for Zone B,picking_optimization
317
- When will order #46139 be delivered?,order_status
318
  Should we batch pick these orders together?,picking_optimization
319
  What is the current location of AMR-21?,agv_navigation
320
  Crane Sorter-02 reported a fault code,equipment_maintenance
321
- Is SKU-8193 in stock at the mezzanine?,inventory_check
322
- Check inventory count for SKU-4760 in the mezzanine,inventory_check
323
- What is the current stock level for SKU-7210?,inventory_check
324
  Report vibration issue on Conveyor-14,equipment_maintenance
325
  Log a breakdown for AMR-21 in Zone B,equipment_maintenance
326
  Is the sorter in Zone A running normally?,system_status
327
  What is a WMS?,general_faq
328
  Send AGV AGV-12 to the receiving dock,agv_navigation
329
- When will order #40339 be delivered?,order_status
330
- How much inventory is left for SKU-5187?,inventory_check
331
  Should we batch pick these orders together?,picking_optimization
332
  Give me the current status of the WMS integration,system_status
333
  What is the uptime for AGV-07 today?,system_status
334
  The conveyor belt in Zone D is making noise,equipment_maintenance
335
- Check inventory count for SKU-9221 in Zone B,inventory_check
336
  Give me the current status of the WMS integration,system_status
337
  Why is Crane-03 stuck near Zone B?,agv_navigation
338
- What's the fastest picking route for order #39330?,picking_optimization
339
  Recommend a picking strategy for high-velocity SKUs,picking_optimization
340
  Check system health for the mezzanine,system_status
341
- How many units of SKU-7921 are in the mezzanine?,inventory_check
342
- What's the fastest picking route for order #36192?,picking_optimization
343
  What KPIs matter most in warehouse automation?,general_faq
344
- Why hasn't order #72092 left the dock yet?,order_status
345
  Redirect AMR-21 around the blocked aisle in Zone C,agv_navigation
346
  Is the sorter in Zone A running normally?,system_status
347
  Route Sorter-02 to picking station 12,agv_navigation
348
  Schedule maintenance for AGV-07,equipment_maintenance
349
- When will order #49814 be delivered?,order_status
350
  Recommend a picking strategy for high-velocity SKUs,picking_optimization
351
  Send AGV Crane-05 to Zone B,agv_navigation
352
- Show the fulfillment status of #77475,order_status
353
- How many units of SKU-9050 are in the mezzanine?,inventory_check
354
- What is the current stock level for SKU-8851?,inventory_check
355
  Recommend a picking strategy for high-velocity SKUs,picking_optimization
356
  "A worker slipped near AMR-21, please log it",safety_incident
357
  Why is AGV-12 stuck near Zone C?,agv_navigation
358
  What KPIs matter most in warehouse automation?,general_faq
359
- Do we have enough SKU-3849 to fulfill 200 units?,inventory_check
360
  Check system health for Zone C,system_status
361
  Redirect Crane-03 around the blocked aisle in Zone B,agv_navigation
362
  Optimize the pick path for the mezzanine,picking_optimization
@@ -364,18 +364,18 @@ Optimize the pick path for Zone B,picking_optimization
364
  Report vibration issue on Crane-05,equipment_maintenance
365
  What is the uptime for AGV-12 today?,system_status
366
  Crane AGV-12 reported a fault code,equipment_maintenance
367
- What's the status of order #14373?,order_status
368
  Log a breakdown for AMR-21 in Zone D,equipment_maintenance
369
  The sorter in Zone C keeps jamming,equipment_maintenance
370
  What is predictive maintenance?,general_faq
371
- Is SKU-3836 in stock at Zone A?,inventory_check
372
  File an incident report for Zone D,safety_incident
373
  What is cycle counting?,general_faq
374
- What's the status of order #34002?,order_status
375
  There was a near collision between Conveyor-14 and a pedestrian in Zone A,safety_incident
376
- What is the current stock level for SKU-5377?,inventory_check
377
  Report vibration issue on AMR-21,equipment_maintenance
378
- What is the current stock level for SKU-7925?,inventory_check
379
  Explain how an AS/RS works,general_faq
380
  Give me the current status of the WMS integration,system_status
381
  Route AGV-07 to picking station 12,agv_navigation
@@ -388,7 +388,7 @@ Redirect AGV-12 around the blocked aisle in the mezzanine,agv_navigation
388
  Send AGV Crane-03 to Zone A,agv_navigation
389
  Recommend a picking strategy for high-velocity SKUs,picking_optimization
390
  What KPIs matter most in warehouse automation?,general_faq
391
- What's the fastest picking route for order #52930?,picking_optimization
392
  What's the difference between AGV and AMR?,general_faq
393
  What's the difference between AGV and AMR?,general_faq
394
  Log a safety incident involving AGV-12,safety_incident
@@ -396,35 +396,35 @@ File an incident report for the receiving dock,safety_incident
396
  Recommend a picking strategy for high-velocity SKUs,picking_optimization
397
  Redirect Crane-03 around the blocked aisle in Zone B,agv_navigation
398
  "Belt AGV-12 stopped unexpectedly, please check",equipment_maintenance
399
- Do we have enough SKU-1497 to fulfill 200 units?,inventory_check
400
  What is the current location of Crane-05?,agv_navigation
401
  What is the current location of Conveyor-14?,agv_navigation
402
  Log a safety incident involving Crane-05,safety_incident
403
  Suggest a wave picking plan for the mezzanine,picking_optimization
404
- Is order #15665 delayed?,order_status
405
- Give me stock levels across all zones for SKU-1705,inventory_check
406
  Give me the current status of the WMS integration,system_status
407
- Do we have enough SKU-6979 to fulfill 200 units?,inventory_check
408
  Explain how an AS/RS works,general_faq
409
  Explain how an AS/RS works,general_faq
410
- Do we have enough SKU-3890 to fulfill 200 units?,inventory_check
411
- When will order #23395 be delivered?,order_status
412
  Route Crane-03 to picking station 5,agv_navigation
413
- Check inventory count for SKU-6599 in Zone D,inventory_check
414
  Should we batch pick these orders together?,picking_optimization
415
  Is the sorter in Zone A running normally?,system_status
416
- When will order #29139 be delivered?,order_status
417
  There was a near collision between Crane-05 and a pedestrian in Zone B,safety_incident
418
  How does goods-to-person picking work?,general_faq
419
- How much inventory is left for SKU-1963?,inventory_check
420
  "A worker slipped near AMR-21, please log it",safety_incident
421
  Optimize the pick path for Zone D,picking_optimization
422
  Recommend a picking strategy for high-velocity SKUs,picking_optimization
423
- How many units of SKU-1944 are in the receiving dock?,inventory_check
424
  "A worker slipped near AGV-07, please log it",safety_incident
425
- Show the fulfillment status of #66984,order_status
426
  Check system health for Zone D,system_status
427
- What's the fastest picking route for order #21706?,picking_optimization
428
  The conveyor belt in Zone A is making noise,equipment_maintenance
429
  File an incident report for the receiving dock,safety_incident
430
  What is predictive maintenance?,general_faq
@@ -433,20 +433,20 @@ There was a near collision between AGV-07 and a pedestrian in Zone D,safety_inci
433
  How do sortation systems decide where to route a parcel?,general_faq
434
  A forklift near-miss was reported in the receiving dock,safety_incident
435
  Recommend a picking strategy for high-velocity SKUs,picking_optimization
436
- Give me stock levels across all zones for SKU-8767,inventory_check
437
  Is AGV-07 operational?,system_status
438
- What is the current stock level for SKU-6146?,inventory_check
439
  AMR-21 motor temperature seems high,equipment_maintenance
440
  Why is Crane-03 stuck near Zone C?,agv_navigation
441
  What's the difference between AGV and AMR?,general_faq
442
  Why is Sorter-02 stuck near Zone A?,agv_navigation
443
  AMR-21 motor temperature seems high,equipment_maintenance
444
- How much inventory is left for SKU-6680?,inventory_check
445
- Do we have enough SKU-5318 to fulfill 200 units?,inventory_check
446
  There was a near collision between AGV-12 and a pedestrian in Zone A,safety_incident
447
  Reassign Conveyor-14 to charging station,agv_navigation
448
  Should we batch pick these orders together?,picking_optimization
449
- Do we have enough SKU-1063 to fulfill 200 units?,inventory_check
450
  File an incident report for Zone A,safety_incident
451
  Log a breakdown for AGV-07 in Zone B,equipment_maintenance
452
  Recommend a picking strategy for high-velocity SKUs,picking_optimization
@@ -462,20 +462,20 @@ Crane Sorter-02 reported a fault code,equipment_maintenance
462
  Sorter-02 motor temperature seems high,equipment_maintenance
463
  "Belt Crane-05 stopped unexpectedly, please check",equipment_maintenance
464
  There was a near collision between Sorter-02 and a pedestrian in Zone D,safety_incident
465
- Has order #78709 shipped yet?,order_status
466
  Is Conveyor-14 operational?,system_status
467
- Has order #14046 shipped yet?,order_status
468
  What is a WMS?,general_faq
469
  Report unsafe pallet stacking in Zone C,safety_incident
470
  Route AMR-21 to picking station 3,agv_navigation
471
  How do sortation systems decide where to route a parcel?,general_faq
472
  Sorter-02 motor temperature seems high,equipment_maintenance
473
  What is a WMS?,general_faq
474
- Do we have enough SKU-3593 to fulfill 200 units?,inventory_check
475
  Send AGV AGV-12 to Zone D,agv_navigation
476
- What's the status of order #38333?,order_status
477
- Why hasn't order #55768 left the dock yet?,order_status
478
  Suggest a wave picking plan for the receiving dock,picking_optimization
479
  "A worker slipped near Conveyor-14, please log it",safety_incident
480
  What's the difference between AGV and AMR?,general_faq
481
- Track order #93785 for me,order_status
 
1
  text,intent
2
+ Is order #69013 delayed?,order_status
3
  Is the sorter in Zone C running normally?,system_status
4
  What is the uptime for Sorter-02 today?,system_status
5
  Recommend a picking strategy for high-velocity SKUs,picking_optimization
 
7
  The sorter in the mezzanine keeps jamming,equipment_maintenance
8
  Optimize the pick path for Zone D,picking_optimization
9
  Is Crane-03 operational?,system_status
10
+ Has order #22208 shipped yet?,order_status
11
  What's the difference between AGV and AMR?,general_faq
12
+ What is the current stock level for SKU-1481?,inventory_check
13
  Optimize the pick path for the receiving dock,picking_optimization
14
  What's the difference between AGV and AMR?,general_faq
15
  How can we reduce travel time for pickers in Zone C?,picking_optimization
16
+ What is the current stock level for SKU-6098?,inventory_check
17
+ What's the status of order #34714?,order_status
18
+ How much inventory is left for SKU-8044?,inventory_check
19
  What is a WMS?,general_faq
20
+ Is SKU-4724 in stock at Zone A?,inventory_check
21
  Send AGV AMR-21 to Zone B,agv_navigation
22
  Redirect Sorter-02 around the blocked aisle in Zone B,agv_navigation
23
  Explain how an AS/RS works,general_faq
24
+ When will order #38043 be delivered?,order_status
25
+ What's the fastest picking route for order #11428?,picking_optimization
26
+ Why hasn't order #82342 left the dock yet?,order_status
27
  What KPIs matter most in warehouse automation?,general_faq
28
  File an incident report for Zone D,safety_incident
29
  "A worker slipped near AMR-21, please log it",safety_incident
30
  "A worker slipped near Sorter-02, please log it",safety_incident
31
+ What is the current stock level for SKU-5101?,inventory_check
32
  Is Crane-03 operational?,system_status
33
+ What is the current stock level for SKU-7785?,inventory_check
34
  Are all cranes online in Zone D?,system_status
35
  What is predictive maintenance?,general_faq
36
  What is the uptime for AMR-21 today?,system_status
37
+ Track order #93776 for me,order_status
38
  Log a safety incident involving Crane-05,safety_incident
39
  "Belt AGV-12 stopped unexpectedly, please check",equipment_maintenance
40
  What KPIs matter most in warehouse automation?,general_faq
41
+ Check inventory count for SKU-2025 in the mezzanine,inventory_check
42
  A forklift near-miss was reported in the receiving dock,safety_incident
43
  Why is AGV-12 stuck near Zone D?,agv_navigation
44
+ Has order #58337 shipped yet?,order_status
45
  What is the current location of AGV-07?,agv_navigation
46
+ Do we have enough SKU-5631 to fulfill 200 units?,inventory_check
47
  Report unsafe pallet stacking in Zone D,safety_incident
48
  What's the difference between AGV and AMR?,general_faq
49
+ Track order #24961 for me,order_status
50
  "Belt AGV-07 stopped unexpectedly, please check",equipment_maintenance
51
+ Is order #13815 delayed?,order_status
52
  What is the uptime for Conveyor-14 today?,system_status
53
  There was a near collision between AGV-12 and a pedestrian in Zone B,safety_incident
54
  Is Sorter-02 operational?,system_status
55
  How does goods-to-person picking work?,general_faq
56
  Report unsafe pallet stacking in Zone A,safety_incident
57
  Suggest a wave picking plan for Zone C,picking_optimization
58
+ Has order #86007 shipped yet?,order_status
59
+ Show the fulfillment status of #15798,order_status
60
  What's the difference between AGV and AMR?,general_faq
61
+ Why hasn't order #21644 left the dock yet?,order_status
62
  What's the difference between AGV and AMR?,general_faq
63
+ What's the fastest picking route for order #47398?,picking_optimization
64
+ Show the fulfillment status of #65245,order_status
65
  Schedule maintenance for AMR-21,equipment_maintenance
66
  Redirect Crane-03 around the blocked aisle in Zone D,agv_navigation
67
  Report unsafe pallet stacking in the receiving dock,safety_incident
68
  Report unsafe pallet stacking in Zone D,safety_incident
69
+ What's the status of order #26643?,order_status
70
+ What's the status of order #31576?,order_status
71
  What is the current location of Sorter-02?,agv_navigation
72
  "A worker slipped near Crane-03, please log it",safety_incident
73
+ Track order #79604 for me,order_status
74
  Route Conveyor-14 to picking station 7,agv_navigation
75
  "Belt AGV-12 stopped unexpectedly, please check",equipment_maintenance
76
  AGV-12 motor temperature seems high,equipment_maintenance
 
78
  Suggest a wave picking plan for Zone A,picking_optimization
79
  Explain how an AS/RS works,general_faq
80
  A forklift near-miss was reported in Zone D,safety_incident
81
+ Is order #69266 delayed?,order_status
82
  How do sortation systems decide where to route a parcel?,general_faq
83
+ Give me stock levels across all zones for SKU-3600,inventory_check
84
  The sorter in Zone D keeps jamming,equipment_maintenance
85
  Explain how an AS/RS works,general_faq
86
+ Check inventory count for SKU-6428 in Zone D,inventory_check
87
  There was a near collision between Crane-05 and a pedestrian in Zone D,safety_incident
88
  A forklift near-miss was reported in the mezzanine,safety_incident
89
+ How many units of SKU-1430 are in Zone D?,inventory_check
90
  Report unsafe pallet stacking in the receiving dock,safety_incident
91
  Reassign Sorter-02 to charging station,agv_navigation
92
  What KPIs matter most in warehouse automation?,general_faq
93
  Redirect AGV-12 around the blocked aisle in Zone A,agv_navigation
94
  Route AGV-12 to picking station 3,agv_navigation
95
  Check system health for the receiving dock,system_status
96
+ Show me the on-hand quantity of SKU-2713,inventory_check
97
  Check system health for Zone A,system_status
98
  Crane AMR-21 reported a fault code,equipment_maintenance
99
  Redirect AMR-21 around the blocked aisle in the mezzanine,agv_navigation
100
  What KPIs matter most in warehouse automation?,general_faq
101
+ Check inventory count for SKU-5725 in Zone C,inventory_check
102
  Is the sorter in Zone A running normally?,system_status
103
  What is the uptime for Conveyor-14 today?,system_status
104
  Crane AGV-12 reported a fault code,equipment_maintenance
 
106
  Redirect AMR-21 around the blocked aisle in Zone B,agv_navigation
107
  Reassign Crane-05 to charging station,agv_navigation
108
  How do sortation systems decide where to route a parcel?,general_faq
109
+ Give me stock levels across all zones for SKU-5593,inventory_check
110
  What KPIs matter most in warehouse automation?,general_faq
111
+ Do we have enough SKU-6494 to fulfill 200 units?,inventory_check
112
  Schedule maintenance for Conveyor-14,equipment_maintenance
113
  Is AGV-07 operational?,system_status
114
  Crane Conveyor-14 reported a fault code,equipment_maintenance
115
  What is predictive maintenance?,general_faq
116
  What's the difference between AGV and AMR?,general_faq
117
+ What is the current stock level for SKU-6132?,inventory_check
118
  Report vibration issue on Sorter-02,equipment_maintenance
119
  How can we reduce travel time for pickers in Zone B?,picking_optimization
120
  Is Crane-05 operational?,system_status
121
+ Give me stock levels across all zones for SKU-5332,inventory_check
122
+ Show me the on-hand quantity of SKU-5115,inventory_check
123
+ Track order #39306 for me,order_status
124
  Is Crane-05 operational?,system_status
125
+ Show the fulfillment status of #70351,order_status
126
+ Show me the on-hand quantity of SKU-6361,inventory_check
127
+ Why hasn't order #80826 left the dock yet?,order_status
128
  Report vibration issue on AMR-21,equipment_maintenance
129
  File an incident report for Zone B,safety_incident
130
  How does goods-to-person picking work?,general_faq
131
  What is predictive maintenance?,general_faq
132
+ Show the fulfillment status of #10862,order_status
133
  Report unsafe pallet stacking in the receiving dock,safety_incident
134
  Redirect AMR-21 around the blocked aisle in the mezzanine,agv_navigation
135
+ Is SKU-1013 in stock at Zone B?,inventory_check
136
  Why is Conveyor-14 stuck near the receiving dock?,agv_navigation
137
  How can we reduce travel time for pickers in Zone A?,picking_optimization
138
  What is the uptime for Sorter-02 today?,system_status
139
+ Do we have enough SKU-1897 to fulfill 200 units?,inventory_check
140
+ What's the status of order #56805?,order_status
141
+ How much inventory is left for SKU-1659?,inventory_check
142
+ Check inventory count for SKU-5362 in Zone C,inventory_check
143
  What KPIs matter most in warehouse automation?,general_faq
144
  Is Crane-05 operational?,system_status
145
+ How many units of SKU-5627 are in Zone A?,inventory_check
146
  What KPIs matter most in warehouse automation?,general_faq
147
+ Is order #59173 delayed?,order_status
148
+ Track order #15605 for me,order_status
149
  Report unsafe pallet stacking in Zone B,safety_incident
150
  How can we reduce travel time for pickers in Zone D?,picking_optimization
151
+ Check inventory count for SKU-6500 in the receiving dock,inventory_check
152
  Report unsafe pallet stacking in Zone C,safety_incident
153
  What is the current location of Crane-05?,agv_navigation
154
+ Give me stock levels across all zones for SKU-8781,inventory_check
155
+ Is SKU-7378 in stock at Zone C?,inventory_check
156
  What is predictive maintenance?,general_faq
157
+ Is order #15022 delayed?,order_status
158
+ How many units of SKU-7134 are in the mezzanine?,inventory_check
159
  Schedule maintenance for AGV-12,equipment_maintenance
160
  What KPIs matter most in warehouse automation?,general_faq
161
+ Is order #49861 delayed?,order_status
162
+ Show the fulfillment status of #76528,order_status
163
  Should we batch pick these orders together?,picking_optimization
164
  How do sortation systems decide where to route a parcel?,general_faq
165
  The sorter in the mezzanine keeps jamming,equipment_maintenance
166
  File an incident report for the mezzanine,safety_incident
167
  Give me the current status of the WMS integration,system_status
168
+ What's the fastest picking route for order #40826?,picking_optimization
169
  How can we reduce travel time for pickers in Zone D?,picking_optimization
170
  Why is Sorter-02 stuck near the receiving dock?,agv_navigation
171
  What is predictive maintenance?,general_faq
172
  Report vibration issue on Conveyor-14,equipment_maintenance
173
  File an incident report for the receiving dock,safety_incident
174
+ Has order #60505 shipped yet?,order_status
175
  Redirect AMR-21 around the blocked aisle in Zone D,agv_navigation
176
  Schedule maintenance for AMR-21,equipment_maintenance
177
  What is the uptime for Sorter-02 today?,system_status
178
  Send AGV AMR-21 to Zone D,agv_navigation
179
  Route AGV-12 to picking station 7,agv_navigation
180
+ Has order #78446 shipped yet?,order_status
181
  Reassign Conveyor-14 to charging station,agv_navigation
182
  The sorter in Zone D keeps jamming,equipment_maintenance
183
  Should we batch pick these orders together?,picking_optimization
184
  "Belt AGV-07 stopped unexpectedly, please check",equipment_maintenance
185
  Give me the current status of the WMS integration,system_status
186
  Are all cranes online in Zone C?,system_status
187
+ Track order #31954 for me,order_status
188
  Check system health for the mezzanine,system_status
189
  Report vibration issue on AMR-21,equipment_maintenance
190
  "A worker slipped near Crane-03, please log it",safety_incident
191
  Route Conveyor-14 to picking station 7,agv_navigation
192
+ When will order #73619 be delivered?,order_status
193
  Suggest a wave picking plan for Zone A,picking_optimization
194
  What is the uptime for Conveyor-14 today?,system_status
195
  Route AGV-12 to picking station 7,agv_navigation
196
+ Is order #50452 delayed?,order_status
197
  Suggest a wave picking plan for Zone A,picking_optimization
198
  Check system health for the receiving dock,system_status
199
  How do sortation systems decide where to route a parcel?,general_faq
 
203
  What is the uptime for Sorter-02 today?,system_status
204
  Is Conveyor-14 operational?,system_status
205
  Are all cranes online in the mezzanine?,system_status
206
+ Do we have enough SKU-4848 to fulfill 200 units?,inventory_check
207
  Why is Conveyor-14 stuck near the receiving dock?,agv_navigation
208
  Log a breakdown for Conveyor-14 in Zone A,equipment_maintenance
209
  File an incident report for Zone D,safety_incident
210
  Why is AGV-12 stuck near Zone A?,agv_navigation
211
  Recommend a picking strategy for high-velocity SKUs,picking_optimization
212
  Should we batch pick these orders together?,picking_optimization
213
+ Show me the on-hand quantity of SKU-7831,inventory_check
214
+ Has order #37050 shipped yet?,order_status
215
  Redirect Conveyor-14 around the blocked aisle in Zone C,agv_navigation
216
  Is AMR-21 operational?,system_status
217
+ How many units of SKU-1033 are in Zone B?,inventory_check
218
  "A worker slipped near AGV-07, please log it",safety_incident
219
  A forklift near-miss was reported in Zone D,safety_incident
220
  "Belt Conveyor-14 stopped unexpectedly, please check",equipment_maintenance
 
222
  Crane AMR-21 reported a fault code,equipment_maintenance
223
  Is Conveyor-14 operational?,system_status
224
  Why is Crane-05 stuck near Zone B?,agv_navigation
225
+ What's the fastest picking route for order #12884?,picking_optimization
226
+ Show me the on-hand quantity of SKU-2617,inventory_check
227
  Is the sorter in Zone D running normally?,system_status
228
+ When will order #79189 be delivered?,order_status
229
+ When will order #68111 be delivered?,order_status
230
+ How many units of SKU-8165 are in Zone A?,inventory_check
231
  What is the uptime for Crane-03 today?,system_status
232
  The conveyor belt in the mezzanine is making noise,equipment_maintenance
233
  What is predictive maintenance?,general_faq
 
237
  A forklift near-miss was reported in Zone C,safety_incident
238
  How does goods-to-person picking work?,general_faq
239
  Reassign AGV-07 to charging station,agv_navigation
240
+ Track order #79020 for me,order_status
241
  Crane-03 motor temperature seems high,equipment_maintenance
242
  The sorter in Zone D keeps jamming,equipment_maintenance
243
  Should we batch pick these orders together?,picking_optimization
244
  Crane AGV-12 reported a fault code,equipment_maintenance
245
+ What is the current stock level for SKU-2932?,inventory_check
246
+ What's the status of order #50176?,order_status
247
  Check system health for the mezzanine,system_status
248
+ Show the fulfillment status of #92835,order_status
249
  What's the difference between AGV and AMR?,general_faq
250
  The sorter in the mezzanine keeps jamming,equipment_maintenance
251
  File an incident report for the mezzanine,safety_incident
252
+ What's the status of order #97649?,order_status
253
  Log a breakdown for Crane-05 in Zone C,equipment_maintenance
254
  Send AGV Conveyor-14 to Zone D,agv_navigation
255
  Is AMR-21 operational?,system_status
256
  Are all cranes online in Zone A?,system_status
257
  Should we batch pick these orders together?,picking_optimization
258
+ When will order #18048 be delivered?,order_status
259
  What is the uptime for Crane-05 today?,system_status
260
  Report vibration issue on Crane-03,equipment_maintenance
261
  Reassign Crane-05 to charging station,agv_navigation
262
  Redirect Crane-05 around the blocked aisle in the mezzanine,agv_navigation
263
  Suggest a wave picking plan for Zone A,picking_optimization
264
+ What's the fastest picking route for order #67988?,picking_optimization
265
  How can we reduce travel time for pickers in the receiving dock?,picking_optimization
266
  "A worker slipped near Crane-05, please log it",safety_incident
267
  How can we reduce travel time for pickers in the receiving dock?,picking_optimization
 
282
  What KPIs matter most in warehouse automation?,general_faq
283
  A forklift near-miss was reported in Zone C,safety_incident
284
  What KPIs matter most in warehouse automation?,general_faq
285
+ Is order #86830 delayed?,order_status
286
  Crane Crane-03 reported a fault code,equipment_maintenance
287
  Suggest a wave picking plan for Zone C,picking_optimization
288
  A forklift near-miss was reported in Zone B,safety_incident
 
296
  Reassign Conveyor-14 to charging station,agv_navigation
297
  Suggest a wave picking plan for Zone D,picking_optimization
298
  What is the current location of Crane-05?,agv_navigation
299
+ What's the status of order #48499?,order_status
300
  The conveyor belt in the receiving dock is making noise,equipment_maintenance
301
  A forklift near-miss was reported in Zone C,safety_incident
302
  Route Sorter-02 to picking station 12,agv_navigation
 
305
  "Belt Crane-05 stopped unexpectedly, please check",equipment_maintenance
306
  Should we batch pick these orders together?,picking_optimization
307
  Are all cranes online in Zone A?,system_status
308
+ Track order #25112 for me,order_status
309
  A forklift near-miss was reported in the receiving dock,safety_incident
310
  Report unsafe pallet stacking in the receiving dock,safety_incident
311
  AGV-12 motor temperature seems high,equipment_maintenance
312
  Is Sorter-02 operational?,system_status
313
+ Show me the on-hand quantity of SKU-9509,inventory_check
314
  What KPIs matter most in warehouse automation?,general_faq
315
+ Is order #81134 delayed?,order_status
316
  Suggest a wave picking plan for Zone B,picking_optimization
317
+ When will order #14162 be delivered?,order_status
318
  Should we batch pick these orders together?,picking_optimization
319
  What is the current location of AMR-21?,agv_navigation
320
  Crane Sorter-02 reported a fault code,equipment_maintenance
321
+ Is SKU-3755 in stock at the mezzanine?,inventory_check
322
+ Check inventory count for SKU-1945 in the mezzanine,inventory_check
323
+ What is the current stock level for SKU-4071?,inventory_check
324
  Report vibration issue on Conveyor-14,equipment_maintenance
325
  Log a breakdown for AMR-21 in Zone B,equipment_maintenance
326
  Is the sorter in Zone A running normally?,system_status
327
  What is a WMS?,general_faq
328
  Send AGV AGV-12 to the receiving dock,agv_navigation
329
+ When will order #90290 be delivered?,order_status
330
+ How much inventory is left for SKU-5795?,inventory_check
331
  Should we batch pick these orders together?,picking_optimization
332
  Give me the current status of the WMS integration,system_status
333
  What is the uptime for AGV-07 today?,system_status
334
  The conveyor belt in Zone D is making noise,equipment_maintenance
335
+ Check inventory count for SKU-9882 in Zone B,inventory_check
336
  Give me the current status of the WMS integration,system_status
337
  Why is Crane-03 stuck near Zone B?,agv_navigation
338
+ What's the fastest picking route for order #10016?,picking_optimization
339
  Recommend a picking strategy for high-velocity SKUs,picking_optimization
340
  Check system health for the mezzanine,system_status
341
+ How many units of SKU-4779 are in the mezzanine?,inventory_check
342
+ What's the fastest picking route for order #28928?,picking_optimization
343
  What KPIs matter most in warehouse automation?,general_faq
344
+ Why hasn't order #99186 left the dock yet?,order_status
345
  Redirect AMR-21 around the blocked aisle in Zone C,agv_navigation
346
  Is the sorter in Zone A running normally?,system_status
347
  Route Sorter-02 to picking station 12,agv_navigation
348
  Schedule maintenance for AGV-07,equipment_maintenance
349
+ When will order #75046 be delivered?,order_status
350
  Recommend a picking strategy for high-velocity SKUs,picking_optimization
351
  Send AGV Crane-05 to Zone B,agv_navigation
352
+ Show the fulfillment status of #32378,order_status
353
+ How many units of SKU-7206 are in the mezzanine?,inventory_check
354
+ What is the current stock level for SKU-9688?,inventory_check
355
  Recommend a picking strategy for high-velocity SKUs,picking_optimization
356
  "A worker slipped near AMR-21, please log it",safety_incident
357
  Why is AGV-12 stuck near Zone C?,agv_navigation
358
  What KPIs matter most in warehouse automation?,general_faq
359
+ Do we have enough SKU-4869 to fulfill 200 units?,inventory_check
360
  Check system health for Zone C,system_status
361
  Redirect Crane-03 around the blocked aisle in Zone B,agv_navigation
362
  Optimize the pick path for the mezzanine,picking_optimization
 
364
  Report vibration issue on Crane-05,equipment_maintenance
365
  What is the uptime for AGV-12 today?,system_status
366
  Crane AGV-12 reported a fault code,equipment_maintenance
367
+ What's the status of order #42485?,order_status
368
  Log a breakdown for AMR-21 in Zone D,equipment_maintenance
369
  The sorter in Zone C keeps jamming,equipment_maintenance
370
  What is predictive maintenance?,general_faq
371
+ Is SKU-9153 in stock at Zone A?,inventory_check
372
  File an incident report for Zone D,safety_incident
373
  What is cycle counting?,general_faq
374
+ What's the status of order #25908?,order_status
375
  There was a near collision between Conveyor-14 and a pedestrian in Zone A,safety_incident
376
+ What is the current stock level for SKU-7712?,inventory_check
377
  Report vibration issue on AMR-21,equipment_maintenance
378
+ What is the current stock level for SKU-3014?,inventory_check
379
  Explain how an AS/RS works,general_faq
380
  Give me the current status of the WMS integration,system_status
381
  Route AGV-07 to picking station 12,agv_navigation
 
388
  Send AGV Crane-03 to Zone A,agv_navigation
389
  Recommend a picking strategy for high-velocity SKUs,picking_optimization
390
  What KPIs matter most in warehouse automation?,general_faq
391
+ What's the fastest picking route for order #60573?,picking_optimization
392
  What's the difference between AGV and AMR?,general_faq
393
  What's the difference between AGV and AMR?,general_faq
394
  Log a safety incident involving AGV-12,safety_incident
 
396
  Recommend a picking strategy for high-velocity SKUs,picking_optimization
397
  Redirect Crane-03 around the blocked aisle in Zone B,agv_navigation
398
  "Belt AGV-12 stopped unexpectedly, please check",equipment_maintenance
399
+ Do we have enough SKU-9423 to fulfill 200 units?,inventory_check
400
  What is the current location of Crane-05?,agv_navigation
401
  What is the current location of Conveyor-14?,agv_navigation
402
  Log a safety incident involving Crane-05,safety_incident
403
  Suggest a wave picking plan for the mezzanine,picking_optimization
404
+ Is order #74036 delayed?,order_status
405
+ Give me stock levels across all zones for SKU-6317,inventory_check
406
  Give me the current status of the WMS integration,system_status
407
+ Do we have enough SKU-4614 to fulfill 200 units?,inventory_check
408
  Explain how an AS/RS works,general_faq
409
  Explain how an AS/RS works,general_faq
410
+ Do we have enough SKU-9494 to fulfill 200 units?,inventory_check
411
+ When will order #63042 be delivered?,order_status
412
  Route Crane-03 to picking station 5,agv_navigation
413
+ Check inventory count for SKU-1270 in Zone D,inventory_check
414
  Should we batch pick these orders together?,picking_optimization
415
  Is the sorter in Zone A running normally?,system_status
416
+ When will order #86590 be delivered?,order_status
417
  There was a near collision between Crane-05 and a pedestrian in Zone B,safety_incident
418
  How does goods-to-person picking work?,general_faq
419
+ How much inventory is left for SKU-9371?,inventory_check
420
  "A worker slipped near AMR-21, please log it",safety_incident
421
  Optimize the pick path for Zone D,picking_optimization
422
  Recommend a picking strategy for high-velocity SKUs,picking_optimization
423
+ How many units of SKU-5484 are in the receiving dock?,inventory_check
424
  "A worker slipped near AGV-07, please log it",safety_incident
425
+ Show the fulfillment status of #22905,order_status
426
  Check system health for Zone D,system_status
427
+ What's the fastest picking route for order #36117?,picking_optimization
428
  The conveyor belt in Zone A is making noise,equipment_maintenance
429
  File an incident report for the receiving dock,safety_incident
430
  What is predictive maintenance?,general_faq
 
433
  How do sortation systems decide where to route a parcel?,general_faq
434
  A forklift near-miss was reported in the receiving dock,safety_incident
435
  Recommend a picking strategy for high-velocity SKUs,picking_optimization
436
+ Give me stock levels across all zones for SKU-9571,inventory_check
437
  Is AGV-07 operational?,system_status
438
+ What is the current stock level for SKU-2340?,inventory_check
439
  AMR-21 motor temperature seems high,equipment_maintenance
440
  Why is Crane-03 stuck near Zone C?,agv_navigation
441
  What's the difference between AGV and AMR?,general_faq
442
  Why is Sorter-02 stuck near Zone A?,agv_navigation
443
  AMR-21 motor temperature seems high,equipment_maintenance
444
+ How much inventory is left for SKU-5577?,inventory_check
445
+ Do we have enough SKU-6653 to fulfill 200 units?,inventory_check
446
  There was a near collision between AGV-12 and a pedestrian in Zone A,safety_incident
447
  Reassign Conveyor-14 to charging station,agv_navigation
448
  Should we batch pick these orders together?,picking_optimization
449
+ Do we have enough SKU-7862 to fulfill 200 units?,inventory_check
450
  File an incident report for Zone A,safety_incident
451
  Log a breakdown for AGV-07 in Zone B,equipment_maintenance
452
  Recommend a picking strategy for high-velocity SKUs,picking_optimization
 
462
  Sorter-02 motor temperature seems high,equipment_maintenance
463
  "Belt Crane-05 stopped unexpectedly, please check",equipment_maintenance
464
  There was a near collision between Sorter-02 and a pedestrian in Zone D,safety_incident
465
+ Has order #55893 shipped yet?,order_status
466
  Is Conveyor-14 operational?,system_status
467
+ Has order #45816 shipped yet?,order_status
468
  What is a WMS?,general_faq
469
  Report unsafe pallet stacking in Zone C,safety_incident
470
  Route AMR-21 to picking station 3,agv_navigation
471
  How do sortation systems decide where to route a parcel?,general_faq
472
  Sorter-02 motor temperature seems high,equipment_maintenance
473
  What is a WMS?,general_faq
474
+ Do we have enough SKU-5882 to fulfill 200 units?,inventory_check
475
  Send AGV AGV-12 to Zone D,agv_navigation
476
+ What's the status of order #25189?,order_status
477
+ Why hasn't order #47151 left the dock yet?,order_status
478
  Suggest a wave picking plan for the receiving dock,picking_optimization
479
  "A worker slipped near Conveyor-14, please log it",safety_incident
480
  What's the difference between AGV and AMR?,general_faq
481
+ Track order #55871 for me,order_status
data/latency_eval.json CHANGED
@@ -1,6 +1,6 @@
1
  {
2
- "intent_classifier_ms": 0.309,
3
- "anomaly_detector_ms": 17.703,
4
- "kb_retrieval_ms": 0.446,
5
  "note": "LLM generation latency depends on the external Inference API call and is measured live in the app, not benchmarked here."
6
  }
 
1
  {
2
+ "intent_classifier_ms": 0.408,
3
+ "anomaly_detector_ms": 21.223,
4
+ "kb_retrieval_ms": 0.617,
5
  "note": "LLM generation latency depends on the external Inference API call and is measured live in the app, not benchmarked here."
6
  }
models/intent_pipeline.joblib CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:9bbdf1c95a8a9dac3baa157e22462025c8e40dae5ea10b483a8d0e1506c106c1
3
- size 65196
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b8e49f35a4e88b2a61908f861e49beb4a912a34fa85484c1936878e6ce1a6620
3
+ size 65356
src/llm_client.py CHANGED
@@ -12,18 +12,38 @@ Design notes
12
  secrets). The public demo also works without a token: it falls back to a
13
  deterministic, still-useful extractive answer built from the retrieved
14
  knowledge-base passages, so the Space never shows a broken demo.
15
- * The model name is configurable via `LLM_MODEL_ID` (defaults to a small,
16
- fast, freely-hostable instruct model).
 
 
 
 
 
 
17
  """
18
 
19
  import os
20
  import time
21
- from dataclasses import dataclass
22
- from typing import List
23
 
24
  from src.retriever import KBRetriever, RetrievedDoc
25
 
26
- DEFAULT_MODEL_ID = os.environ.get("LLM_MODEL_ID", "Qwen/Qwen2.5-7B-Instruct")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
  SYSTEM_PROMPT = (
29
  "You are the Smart Warehouse AI Assistant, a helpful operations copilot "
@@ -42,6 +62,7 @@ class AssistantResponse:
42
  sources: List[RetrievedDoc]
43
  latency_s: float
44
  model_id: str
 
45
 
46
 
47
  def _extractive_fallback(query: str, sources: List[RetrievedDoc]) -> str:
@@ -57,8 +78,8 @@ def _extractive_fallback(query: str, sources: List[RetrievedDoc]) -> str:
57
  lead = sources[0]
58
  bullets = "\n".join(f"- **{s.title}**: {s.text}" for s in sources)
59
  return (
60
- f"(Offline / no LLM API key configured -- showing retrieved "
61
- f"knowledge instead of a generated answer.)\n\n"
62
  f"Based on **{lead.title}**, here's the relevant information:\n\n{bullets}"
63
  )
64
 
@@ -67,7 +88,6 @@ def answer_query(
67
  query: str,
68
  retriever: KBRetriever,
69
  k: int = 2,
70
- model_id: str = DEFAULT_MODEL_ID,
71
  max_tokens: int = 350,
72
  ) -> AssistantResponse:
73
  start = time.time()
@@ -84,35 +104,57 @@ def answer_query(
84
  sources=sources,
85
  latency_s=time.time() - start,
86
  model_id="extractive-fallback",
 
87
  )
88
 
89
  try:
90
  from huggingface_hub import InferenceClient
91
-
92
- client = InferenceClient(model=model_id, token=hf_token)
93
- messages = [
94
- {"role": "system", "content": SYSTEM_PROMPT},
95
- {
96
- "role": "user",
97
- "content": f"CONTEXT:\n{context_block}\n\nQUESTION: {query}",
98
- },
99
- ]
100
- completion = client.chat_completion(messages=messages, max_tokens=max_tokens, temperature=0.3)
101
- text = completion.choices[0].message.content
102
- return AssistantResponse(
103
- answer=text,
104
- used_llm=True,
105
- sources=sources,
106
- latency_s=time.time() - start,
107
- model_id=model_id,
108
- )
109
- except Exception as e: # noqa: BLE001 -- deliberately broad: any API/network issue -> fallback
110
  answer = _extractive_fallback(query, sources)
111
- answer += f"\n\n_(LLM call failed: {type(e).__name__}. Showing retrieval-only answer.)_"
112
  return AssistantResponse(
113
- answer=answer,
114
- used_llm=False,
115
- sources=sources,
116
- latency_s=time.time() - start,
117
- model_id="extractive-fallback",
118
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  secrets). The public demo also works without a token: it falls back to a
13
  deterministic, still-useful extractive answer built from the retrieved
14
  knowledge-base passages, so the Space never shows a broken demo.
15
+ * Serverless model availability on the free HF Inference API changes over
16
+ time (models get gated, deprecated, or moved between providers), so
17
+ rather than hard-depending on a single model id, we try a short list of
18
+ candidates in order and use the first one that responds successfully.
19
+ `LLM_MODEL_ID` (env var) is tried first if set, ahead of the built-in list.
20
+ * On failure, the *actual* exception message (not just its type) is
21
+ surfaced back to the UI, so a broken deployment is debuggable from the
22
+ Space itself instead of requiring log access.
23
  """
24
 
25
  import os
26
  import time
27
+ from dataclasses import dataclass, field
28
+ from typing import List, Optional
29
 
30
  from src.retriever import KBRetriever, RetrievedDoc
31
 
32
+ # Small, widely-available instruct models known to work well on HF's free
33
+ # serverless Inference API. Tried in order; first success wins. If
34
+ # LLM_MODEL_ID is set as an env var, it is tried first, ahead of this list.
35
+ MODEL_CANDIDATES = [
36
+ "Qwen/Qwen2.5-7B-Instruct",
37
+ "meta-llama/Llama-3.2-3B-Instruct",
38
+ "mistralai/Mistral-7B-Instruct-v0.3",
39
+ "HuggingFaceH4/zephyr-7b-beta",
40
+ ]
41
+
42
+ _env_model = os.environ.get("LLM_MODEL_ID")
43
+ if _env_model:
44
+ MODEL_CANDIDATES = [_env_model] + [m for m in MODEL_CANDIDATES if m != _env_model]
45
+
46
+ DEFAULT_MODEL_ID = MODEL_CANDIDATES[0]
47
 
48
  SYSTEM_PROMPT = (
49
  "You are the Smart Warehouse AI Assistant, a helpful operations copilot "
 
62
  sources: List[RetrievedDoc]
63
  latency_s: float
64
  model_id: str
65
+ debug_errors: List[str] = field(default_factory=list) # non-empty only when used_llm is False due to failures
66
 
67
 
68
  def _extractive_fallback(query: str, sources: List[RetrievedDoc]) -> str:
 
78
  lead = sources[0]
79
  bullets = "\n".join(f"- **{s.title}**: {s.text}" for s in sources)
80
  return (
81
+ f"(Showing retrieved knowledge instead of an LLM-generated answer -- "
82
+ f"see the diagnostics below.)\n\n"
83
  f"Based on **{lead.title}**, here's the relevant information:\n\n{bullets}"
84
  )
85
 
 
88
  query: str,
89
  retriever: KBRetriever,
90
  k: int = 2,
 
91
  max_tokens: int = 350,
92
  ) -> AssistantResponse:
93
  start = time.time()
 
104
  sources=sources,
105
  latency_s=time.time() - start,
106
  model_id="extractive-fallback",
107
+ debug_errors=["No HF_TOKEN secret is set on this Space."],
108
  )
109
 
110
  try:
111
  from huggingface_hub import InferenceClient
112
+ except ImportError as e:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  answer = _extractive_fallback(query, sources)
 
114
  return AssistantResponse(
115
+ answer=answer, used_llm=False, sources=sources,
116
+ latency_s=time.time() - start, model_id="extractive-fallback",
117
+ debug_errors=[f"huggingface_hub not importable: {e}"],
 
 
118
  )
119
+
120
+ messages = [
121
+ {"role": "system", "content": SYSTEM_PROMPT},
122
+ {"role": "user", "content": f"CONTEXT:\n{context_block}\n\nQUESTION: {query}"},
123
+ ]
124
+
125
+ errors = []
126
+ for candidate in MODEL_CANDIDATES:
127
+ try:
128
+ client = InferenceClient(model=candidate, token=hf_token)
129
+ completion = client.chat_completion(messages=messages, max_tokens=max_tokens, temperature=0.3)
130
+ text = completion.choices[0].message.content
131
+ if text and text.strip():
132
+ return AssistantResponse(
133
+ answer=text,
134
+ used_llm=True,
135
+ sources=sources,
136
+ latency_s=time.time() - start,
137
+ model_id=candidate,
138
+ )
139
+ errors.append(f"{candidate}: empty response")
140
+ except Exception as e: # noqa: BLE001 -- try the next candidate model
141
+ errors.append(f"{candidate}: {type(e).__name__}: {e}")
142
+
143
+ # All candidates failed -- fall back, but surface the real errors so the
144
+ # deployment is debuggable directly from the UI.
145
+ answer = _extractive_fallback(query, sources)
146
+ return AssistantResponse(
147
+ answer=answer,
148
+ used_llm=False,
149
+ sources=sources,
150
+ latency_s=time.time() - start,
151
+ model_id="extractive-fallback",
152
+ debug_errors=errors,
153
+ )
154
+
155
+
156
+ def test_connection(retriever: Optional[KBRetriever] = None) -> AssistantResponse:
157
+ """Runs a single canned query through the full pipeline -- used by the
158
+ 'Test LLM connection' diagnostics button in the app."""
159
+ retriever = retriever or KBRetriever()
160
+ return answer_query("What is a WMS?", retriever, k=1, max_tokens=60)