Nipun Claude Opus 4.6 (1M context) commited on
Commit
b50be46
·
1 Parent(s): cc852ec

Match nipunbatra.github.io design system; fix Mermaid parser errors

Browse files

Look & feel:
- Work Sans body + Playfair Display headings (both from Google Fonts).
- Warm-red #c44536 accent, #1a1a2e ink, cream #faf7f2 surface — same
palette as nipunbatra.github.io / sustainability-lab.github.io.
- Cream title card with warm-red left border replaces the purple/pink
gradient block.
- Underlined-accent tab bar, rounded-corner primary button, subtle
shadows and 4px corners throughout.
- Pill example buttons now white with cream hover in the warm-red.
- Gradio theme switched from Soft to Default(red) so our CSS variables
control the look.

Mermaid:
- Fully quote every node label; switch edge labels from `-- x -->` to
`-->|x|`; drop <br/> from inside diamond labels. Mermaid 11.14 is
strict about unquoted specials and that was the source of
"Syntax error in text".
- Use mermaid.run({nodes}) async with a :not([data-processed]) selector
so re-renders after tab swaps don't double-parse.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Files changed (1) hide show
  1. app.py +185 -50
app.py CHANGED
@@ -655,6 +655,8 @@ TOOLS_DETAIL = f"""
655
 
656
 
657
  # Mermaid flowchart — rendered inside a raw HTML block with CDN Mermaid.
 
 
658
  FLOWCHART_HTML = """
659
  <div style="padding: 1rem 0;">
660
  <h2 style="text-align:left;">Without tools vs. with tools</h2>
@@ -662,28 +664,31 @@ FLOWCHART_HTML = """
662
 
663
  <pre class="mermaid" style="background:transparent;">
664
  flowchart LR
665
- subgraph plain["Without tools (plain LLM)"]
666
- direction TB
667
- PU[User question] --> PL[LLM]
668
- PL --> PA["Answer<br/>(may hallucinate)"]
669
  end
670
- subgraph agent["With tools (agent loop)"]
671
- direction TB
672
- AU[User question] --> AL["LLM + tool menu"]
673
- AL --> AD{Tool call<br/>needed?}
674
- AD -- no --> AF["Final answer<br/>(grounded in data)"]
675
- AD -- yes --> AT[Run tool in your code]
676
- AT --> AR[Append result to messages]
677
  AR --> AL
678
  end
679
  </pre>
680
 
681
  <script type="module">
682
  import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs";
683
- mermaid.initialize({ startOnLoad: true, theme: "default", securityLevel: "loose", flowchart: { htmlLabels: true } });
684
- const rerun = () => { try { mermaid.run({ nodes: document.querySelectorAll('.mermaid:not([data-processed])') }); } catch(e) {} };
685
- rerun();
686
- const obs = new MutationObserver(rerun);
 
 
 
 
 
687
  obs.observe(document.body, { childList: true, subtree: true });
688
  </script>
689
  </div>
@@ -691,69 +696,191 @@ flowchart LR
691
 
692
 
693
  CUSTOM_CSS = """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
694
  #title-card {
695
- background: linear-gradient(135deg, #4f46e5 0%, #ec4899 100%);
696
- color: white;
697
- padding: 1.25rem 1.5rem;
698
- border-radius: 16px;
699
- margin-bottom: 1rem;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
700
  }
701
- #title-card h1 { color: white; margin: 0 0 .25rem 0; font-size: 1.8rem; }
702
- #title-card p { color: rgba(255,255,255,.92); margin: 0; font-size: .95rem; }
703
 
 
704
  #question-box textarea {
 
705
  font-size: 1.05rem !important;
706
- border-radius: 12px !important;
707
  padding: .75rem 1rem !important;
708
- border: 2px solid #e5e7eb !important;
 
709
  transition: border-color .15s;
710
  }
711
  #question-box textarea:focus {
712
- border-color: #4f46e5 !important;
713
  outline: none !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
714
  }
715
 
716
- #pill-row { gap: .45rem !important; flex-wrap: wrap !important; }
 
717
  #pill-row .gr-button, #pill-row button {
718
  border-radius: 999px !important;
719
- padding: .35rem .9rem !important;
720
- font-size: .85rem !important;
721
- font-weight: 500 !important;
722
- background: #f3f4f6 !important;
723
- color: #1f2937 !important;
724
- border: 1px solid #e5e7eb !important;
 
725
  min-width: 0 !important;
726
  width: auto !important;
727
  text-align: left !important;
728
  white-space: normal !important;
729
- line-height: 1.25 !important;
730
  flex: 0 0 auto !important;
 
731
  }
732
  #pill-row .gr-button:hover, #pill-row button:hover {
733
- background: #e0e7ff !important;
734
- border-color: #4f46e5 !important;
 
735
  }
736
 
 
737
  .panel {
738
- border-radius: 14px;
739
- padding: 1rem 1.1rem;
740
  min-height: 220px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
741
  }
742
- .panel-plain { background: #fdecea; border: 1px solid #f5b7b1; }
743
- .panel-agent { background: #e8f5e9; border: 1px solid #a9dfbf; }
744
- .panel h3 { margin-top: 0 !important; text-align: left; }
745
 
746
  .final-box {
747
- background: white;
748
- border-left: 4px solid #1e8449;
749
  padding: .75rem 1rem;
750
- border-radius: 8px;
751
  margin-bottom: .75rem;
752
  }
753
 
754
- /* Left-align everything in the demo by default */
755
- .gradio-container h1, .gradio-container h2, .gradio-container h3,
756
- .gradio-container p, .gradio-container label { text-align: left !important; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
757
  """
758
 
759
 
@@ -787,14 +914,22 @@ EXAMPLES = [
787
 
788
  TITLE_CARD = """
789
  <div id="title-card">
790
- <h1>🤖 Agent 101 — LLM vs. LLM-with-tools</h1>
791
- <p>Same model both sides. Left: plain LLM. Right: the same model with a toolkit and an agent loop. Watch what happens on questions the LLM can't answer from memory.</p>
792
- <p style="margin-top:.4rem;font-size:.85rem;">Built for CS 203 at IIT Gandhinagar · <a href="https://github.com/nipunbatra/stt-ai-teaching/blob/master/lecture-demos/week12/colab-notebooks/01-agents-from-scratch.ipynb" style="color:white;text-decoration:underline;">companion Colab</a></p>
793
  </div>
794
  """
795
 
796
 
797
- with gr.Blocks(title="Agent 101", theme=gr.themes.Soft(), css=CUSTOM_CSS) as demo:
 
 
 
 
 
 
 
 
798
  gr.HTML(TITLE_CARD)
799
 
800
  with gr.Tabs():
 
655
 
656
 
657
  # Mermaid flowchart — rendered inside a raw HTML block with CDN Mermaid.
658
+ # Mermaid 11 is strict: every label with special chars / parens must be
659
+ # quoted, and <br/> tags must live inside quoted labels only.
660
  FLOWCHART_HTML = """
661
  <div style="padding: 1rem 0;">
662
  <h2 style="text-align:left;">Without tools vs. with tools</h2>
 
664
 
665
  <pre class="mermaid" style="background:transparent;">
666
  flowchart LR
667
+ subgraph plain["Without tools"]
668
+ PU["User question"] --> PL["LLM"]
669
+ PL --> PA["Answer (may hallucinate)"]
 
670
  end
671
+ subgraph agent["With tools - agent loop"]
672
+ AU["User question"] --> AL["LLM + tool menu"]
673
+ AL --> AD{"Tool call?"}
674
+ AD -->|no| AF["Final answer"]
675
+ AD -->|yes| AT["Run tool in your code"]
676
+ AT --> AR["Append result"]
 
677
  AR --> AL
678
  end
679
  </pre>
680
 
681
  <script type="module">
682
  import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs";
683
+ mermaid.initialize({ startOnLoad: false, theme: "default", securityLevel: "loose" });
684
+ async function renderAll() {
685
+ const blocks = document.querySelectorAll('.mermaid:not([data-processed])');
686
+ if (!blocks.length) return;
687
+ try { await mermaid.run({ nodes: blocks }); }
688
+ catch (e) { console.error('Mermaid render error:', e); }
689
+ }
690
+ renderAll();
691
+ const obs = new MutationObserver(renderAll);
692
  obs.observe(document.body, { childList: true, subtree: true });
693
  </script>
694
  </div>
 
696
 
697
 
698
  CUSTOM_CSS = """
699
+ @import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@500;600;700&family=Work+Sans:wght@300;400;500;600&display=swap');
700
+
701
+ :root {
702
+ --ink: #1a1a2e;
703
+ --muted: #5a6070;
704
+ --paper: #ffffff;
705
+ --cream: #faf7f2;
706
+ --accent: #c44536;
707
+ --accent-hover: #a63c30;
708
+ --line: rgba(26, 26, 46, 0.1);
709
+ --shadow-sm: 0 2px 8px rgba(26, 26, 46, 0.06);
710
+ --shadow-md: 0 8px 30px rgba(26, 26, 46, 0.12);
711
+ }
712
+
713
+ .gradio-container, .gradio-container * {
714
+ font-family: "Work Sans", system-ui, sans-serif !important;
715
+ color: var(--ink);
716
+ }
717
+
718
+ .gradio-container { background: var(--paper) !important; }
719
+
720
+ .gradio-container h1, .gradio-container h2 {
721
+ font-family: "Playfair Display", serif !important;
722
+ font-weight: 600 !important;
723
+ letter-spacing: -0.01em;
724
+ }
725
+
726
+ .gradio-container h1, .gradio-container h2, .gradio-container h3,
727
+ .gradio-container p, .gradio-container label {
728
+ text-align: left !important;
729
+ }
730
+
731
+ /* Header card — replaces the purple/pink gradient */
732
  #title-card {
733
+ background: var(--cream);
734
+ border: 1px solid var(--line);
735
+ border-left: 4px solid var(--accent);
736
+ padding: 1.5rem 1.75rem;
737
+ border-radius: 4px;
738
+ margin-bottom: 1.25rem;
739
+ box-shadow: var(--shadow-sm);
740
+ }
741
+ #title-card h1 {
742
+ font-family: "Playfair Display", serif;
743
+ color: var(--ink);
744
+ margin: 0 0 .35rem 0;
745
+ font-size: 2rem;
746
+ font-weight: 600;
747
+ }
748
+ #title-card p {
749
+ color: var(--muted);
750
+ margin: 0;
751
+ font-size: 1rem;
752
+ line-height: 1.6;
753
+ }
754
+ #title-card a { color: var(--accent); text-decoration: none; }
755
+ #title-card a:hover { color: var(--accent-hover); text-decoration: underline; }
756
+
757
+ /* Tabs */
758
+ .gradio-container .tab-nav button {
759
+ font-family: "Work Sans", sans-serif !important;
760
+ font-weight: 500 !important;
761
+ color: var(--muted) !important;
762
+ background: transparent !important;
763
+ border: none !important;
764
+ border-bottom: 2px solid transparent !important;
765
+ border-radius: 0 !important;
766
+ padding: .6rem 1.1rem !important;
767
+ }
768
+ .gradio-container .tab-nav button.selected {
769
+ color: var(--accent) !important;
770
+ border-bottom-color: var(--accent) !important;
771
  }
 
 
772
 
773
+ /* Question textbox */
774
  #question-box textarea {
775
+ font-family: "Work Sans", sans-serif !important;
776
  font-size: 1.05rem !important;
777
+ border-radius: 4px !important;
778
  padding: .75rem 1rem !important;
779
+ border: 1px solid var(--line) !important;
780
+ background: var(--paper) !important;
781
  transition: border-color .15s;
782
  }
783
  #question-box textarea:focus {
784
+ border-color: var(--accent) !important;
785
  outline: none !important;
786
+ box-shadow: 0 0 0 3px rgba(196, 69, 54, .1) !important;
787
+ }
788
+
789
+ /* Primary button (Run both) */
790
+ .gradio-container button.primary {
791
+ background: var(--accent) !important;
792
+ border: none !important;
793
+ border-radius: 4px !important;
794
+ font-weight: 500 !important;
795
+ letter-spacing: .02em !important;
796
+ transition: background .15s;
797
+ }
798
+ .gradio-container button.primary:hover {
799
+ background: var(--accent-hover) !important;
800
  }
801
 
802
+ /* Pill-style example buttons */
803
+ #pill-row { gap: .5rem !important; flex-wrap: wrap !important; }
804
  #pill-row .gr-button, #pill-row button {
805
  border-radius: 999px !important;
806
+ padding: .4rem 1rem !important;
807
+ font-family: "Work Sans", sans-serif !important;
808
+ font-size: .88rem !important;
809
+ font-weight: 400 !important;
810
+ background: var(--paper) !important;
811
+ color: var(--ink) !important;
812
+ border: 1px solid var(--line) !important;
813
  min-width: 0 !important;
814
  width: auto !important;
815
  text-align: left !important;
816
  white-space: normal !important;
817
+ line-height: 1.3 !important;
818
  flex: 0 0 auto !important;
819
+ transition: all .15s ease;
820
  }
821
  #pill-row .gr-button:hover, #pill-row button:hover {
822
+ background: var(--cream) !important;
823
+ border-color: var(--accent) !important;
824
+ color: var(--accent) !important;
825
  }
826
 
827
+ /* Result panels */
828
  .panel {
829
+ border-radius: 4px;
830
+ padding: 1.1rem 1.25rem;
831
  min-height: 220px;
832
+ background: var(--paper);
833
+ box-shadow: var(--shadow-sm);
834
+ }
835
+ .panel-plain {
836
+ background: var(--cream);
837
+ border: 1px solid var(--line);
838
+ border-top: 3px solid #9a6b6b;
839
+ }
840
+ .panel-agent {
841
+ background: var(--paper);
842
+ border: 1px solid var(--line);
843
+ border-top: 3px solid var(--accent);
844
+ }
845
+ .panel h3 {
846
+ font-family: "Playfair Display", serif !important;
847
+ margin-top: 0 !important;
848
+ margin-bottom: .25rem !important;
849
+ color: var(--ink) !important;
850
  }
 
 
 
851
 
852
  .final-box {
853
+ background: var(--cream);
854
+ border-left: 3px solid var(--accent);
855
  padding: .75rem 1rem;
856
+ border-radius: 2px;
857
  margin-bottom: .75rem;
858
  }
859
 
860
+ /* Dropdown */
861
+ .gradio-container .gr-dropdown,
862
+ .gradio-container .gr-dropdown input {
863
+ border-radius: 4px !important;
864
+ border-color: var(--line) !important;
865
+ font-family: "Work Sans", sans-serif !important;
866
+ }
867
+
868
+ /* Code blocks keep mono font */
869
+ .gradio-container code, .gradio-container pre,
870
+ .gradio-container pre code {
871
+ font-family: "JetBrains Mono", "SF Mono", Menlo, monospace !important;
872
+ font-size: .88rem !important;
873
+ }
874
+
875
+ /* Links */
876
+ .gradio-container a {
877
+ color: var(--accent);
878
+ text-decoration: none;
879
+ }
880
+ .gradio-container a:hover {
881
+ color: var(--accent-hover);
882
+ text-decoration: underline;
883
+ }
884
  """
885
 
886
 
 
914
 
915
  TITLE_CARD = """
916
  <div id="title-card">
917
+ <h1>Agent 101</h1>
918
+ <p>LLM vs. LLM-with-tools same model on both sides, the only difference is the agent loop on the right. Watch what happens on questions the LLM can't answer from memory.</p>
919
+ <p style="margin-top:.5rem;font-size:.88rem;color:var(--muted);">Built for CS 203 at IIT Gandhinagar · <a href="https://github.com/nipunbatra/stt-ai-teaching/blob/master/lecture-demos/week12/colab-notebooks/01-agents-from-scratch.ipynb">companion Colab</a></p>
920
  </div>
921
  """
922
 
923
 
924
+ with gr.Blocks(
925
+ title="Agent 101",
926
+ theme=gr.themes.Default(
927
+ primary_hue=gr.themes.colors.red,
928
+ font=[gr.themes.GoogleFont("Work Sans"), "system-ui", "sans-serif"],
929
+ font_mono=[gr.themes.GoogleFont("JetBrains Mono"), "monospace"],
930
+ ),
931
+ css=CUSTOM_CSS,
932
+ ) as demo:
933
  gr.HTML(TITLE_CARD)
934
 
935
  with gr.Tabs():