RumleyRum commited on
Commit
99b2d5a
·
verified ·
1 Parent(s): 42a558e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +156 -75
app.py CHANGED
@@ -33,6 +33,22 @@ import json
33
  from pathlib import Path
34
  from collections import deque
35
  from typing import List, Dict, Optional, Any, Tuple
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
37
  # Import engine components
38
  import sys
@@ -58,17 +74,8 @@ def compute_substrate_embeddings_highd(substrate_list: List[str]) -> List[List[f
58
  return [embedder.embed(t) for t in substrate_list]
59
 
60
 
61
- # ============================================================================
62
- # Streamlit Page Configuration
63
- # ============================================================================
64
-
65
- st.set_page_config(
66
- page_title="Deterministic Exclusion Demo",
67
- layout="wide",
68
- initial_sidebar_state="expanded"
69
- )
70
-
71
  # Custom CSS for monospace hash display
 
72
  st.markdown("""
73
  <style>
74
  .hash-display {
@@ -281,40 +288,23 @@ if st.sidebar.button("Run Deterministic Exclusion Demo", type="primary"):
281
 
282
  st.success("Inference complete.")
283
 
284
- st.sidebar.info("""
285
- 💡 **Production Deployment**
286
- This is a reference implementation. For enterprise features, licensing, or partnerships:
287
- **[verhash.com](https://verhash.com)** | **ryan@verhash.net**
288
- """)
289
-
290
  st.sidebar.markdown("---")
291
-
292
- st.sidebar.markdown("### About")
293
- st.sidebar.markdown("""
294
- **Verhash LLC**
295
-
296
- Deterministic AI governance through physics-based substrate computation.
297
-
298
- **Links:**
299
- - [verhash.com](https://verhash.com)
300
- - [GitHub](https://github.com/Rymley/Deterministic-Governance-Mechanism)
301
- - [Documentation](https://verhash.com/docs)
302
-
303
- **Contact:**
304
- ryan@verhash.net
305
-
306
- **Patent Pending**
307
- *Priority: January 25, 2026*
308
  """)
309
 
310
- st.sidebar.caption("© 2026 Verhash LLC")
311
-
312
 
313
  # ============================================================================
314
  # Main Content Area
315
  # ============================================================================
316
 
317
 
 
 
 
318
  # Create tabs
319
  tab1, tab2, tab3, tab4 = st.tabs(["Mechanism Demo", "LLM Guardrail", "Live LLM Testing", "Explain & Tune"])
320
 
@@ -658,7 +648,34 @@ with tab2:
658
  st.json(numbers_view)
659
 
660
  # ----------------------------------------------------------------------------
661
- # TAB 3: LLM Testing
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
662
  # ----------------------------------------------------------------------------
663
  with tab3:
664
  st.header("LLM Testing")
@@ -668,57 +685,115 @@ with tab3:
668
  Supports: OpenAI, Anthropic, Google Gemini, local models (Ollama, llama.cpp, vLLM), and any OpenAI-compatible API.
669
  """)
670
 
 
 
 
 
 
 
 
671
  # API Configuration
672
  st.subheader("1. LLM API Configuration")
673
 
674
  col_api1, col_api2 = st.columns(2)
675
 
676
  with col_api1:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
677
  api_preset = st.selectbox(
678
  "Provider Preset",
679
- options=["OpenAI", "Anthropic (Claude)", "Google (Gemini)", "Local (Ollama)", "Local (llama.cpp)", "Custom OpenAI-compatible"],
 
680
  help="Select a preset or use custom for any OpenAI-compatible endpoint"
681
  )
682
 
683
  # Set defaults based on preset
684
- if api_preset == "OpenAI":
 
 
 
 
 
685
  default_base_url = "https://api.openai.com/v1"
686
- default_model = "gpt-4.1-nano"
687
  needs_key = True
 
688
  elif api_preset == "Anthropic (Claude)":
689
  default_base_url = "https://api.anthropic.com/v1"
690
  default_model = "claude-3-5-sonnet-20241022"
691
  needs_key = True
 
692
  elif api_preset == "Google (Gemini)":
693
  default_base_url = "https://generativelanguage.googleapis.com/v1beta"
694
  default_model = "gemini-2.0-flash-exp"
695
  needs_key = True
 
696
  elif api_preset == "Local (Ollama)":
697
  default_base_url = "http://localhost:11434/v1"
698
  default_model = "llama3.1"
699
  needs_key = False
 
700
  elif api_preset == "Local (llama.cpp)":
701
  default_base_url = "http://localhost:8080/v1"
702
  default_model = "local-model"
703
  needs_key = False
 
704
  else:
705
  default_base_url = "https://api.openai.com/v1"
706
- default_model = "gpt-4.1-nano"
707
  needs_key = True
 
 
 
 
 
708
 
709
  api_base_url = st.text_input(
710
  "Base URL",
711
  value=default_base_url,
712
- help="API endpoint base URL"
 
713
  )
714
 
715
  with col_api2:
716
- api_key = st.text_input(
717
- "API Key" + (" (optional for local)" if not needs_key else ""),
718
- type="password",
719
- help="Your API key (not required for local models)",
720
- placeholder="sk-..." if needs_key else "not needed for local models"
721
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
722
 
723
  model_name = st.text_input(
724
  "Model Name",
@@ -730,14 +805,40 @@ with tab3:
730
  with col_temp:
731
  temperature = st.slider("Temperature", 0.0, 2.0, 0.7, 0.1, help="Higher = more creative")
732
  with col_num:
733
- num_responses = st.number_input("Number of Responses", min_value=1, max_value=10, value=3, help="Generate multiple responses for comparison")
734
-
 
 
 
 
 
 
 
 
 
 
735
  col_timeout, col_retry = st.columns(2)
736
  with col_timeout:
737
- request_timeout = st.number_input("Request Timeout (seconds)", min_value=5, max_value=600, value=60, step=5, help="Increase for slow or local models")
 
 
 
 
 
 
 
 
 
738
  with col_retry:
739
- max_retries = st.number_input("Max Retries", min_value=0, max_value=5, value=2, step=1, help="Automatic retries on transient failures")
740
-
 
 
 
 
 
 
 
741
  # Substrate Configuration
742
  st.subheader("2. Verified Substrate (Ground Truth)")
743
  st.markdown("Enter verified facts that define what is correct. One per line.")
@@ -1237,6 +1338,7 @@ with tab4:
1237
  return history, n_end, q_end
1238
 
1239
  sim_data, sim_n_end, sim_q_end = run_simulation(20, e_nuc, e_quench, e_lam, e_yield, sim_align, sim_dist)
 
1240
 
1241
  # 3. Visualization (Plotly)
1242
  with exp_col2:
@@ -1336,29 +1438,8 @@ with tab4:
1336
 
1337
 
1338
  # ============================================================================
1339
- # Enhanced Footer
1340
  # ============================================================================
1341
 
1342
  st.markdown("---")
1343
-
1344
- footer_col1, footer_col2, footer_col3 = st.columns(3)
1345
-
1346
- with footer_col1:
1347
- st.markdown("### Verhash LLC")
1348
- st.markdown("**Technology Licensing & Partnerships**")
1349
- st.markdown("[ryan@verhash.net](mailto:ryan@verhash.net)")
1350
-
1351
- with footer_col2:
1352
- st.markdown("### Resources")
1353
- st.markdown("- [Website](https://verhash.com)")
1354
- st.markdown("- [GitHub](https://github.com/Rymley/Deterministic-Governance-Mechanism)")
1355
- st.markdown("- [Documentation](https://verhash.com/docs)")
1356
- st.markdown("- [API Access](https://verhash.com/api)")
1357
-
1358
- with footer_col3:
1359
- st.markdown("### Patent Notice")
1360
- st.markdown("Demonstrates concepts from pending patent application")
1361
- st.markdown("**Priority Date:** January 25, 2026")
1362
- st.markdown("**Applicant:** Verhash LLC")
1363
-
1364
- st.caption("© 2026 Verhash LLC | Reference Implementation")
 
33
  from pathlib import Path
34
  from collections import deque
35
  from typing import List, Dict, Optional, Any, Tuple
36
+ import os
37
+
38
+ # Hugging Face Spaces detection
39
+ IS_SPACES = os.getenv("SPACE_ID") is not None
40
+
41
+ # Page Config MUST be the first Streamlit command
42
+ st.set_page_config(
43
+ page_title="Deterministic Exclusion Demo",
44
+ layout="wide",
45
+ initial_sidebar_state="expanded",
46
+ menu_items={
47
+ 'Get Help': 'https://github.com/Rymley/Deterministic-Governance-Mechanism',
48
+ 'Report a bug': "https://github.com/Rymley/Deterministic-Governance-Mechanism/issues",
49
+ 'About': "Deterministic Governance Mechanism by Verhash LLC"
50
+ }
51
+ )
52
 
53
  # Import engine components
54
  import sys
 
74
  return [embedder.embed(t) for t in substrate_list]
75
 
76
 
 
 
 
 
 
 
 
 
 
 
77
  # Custom CSS for monospace hash display
78
+
79
  st.markdown("""
80
  <style>
81
  .hash-display {
 
288
 
289
  st.success("Inference complete.")
290
 
 
 
 
 
 
 
291
  st.sidebar.markdown("---")
292
+ st.sidebar.markdown("### 📞 Contact")
293
+ st.sidebar.caption("""
294
+ **Verhash LLC** | [verhash.com](https://verhash.com)
295
+ 📧 [ryan@verhash.net](mailto:ryan@verhash.net)
296
+ *Patent Pending (Jan 2026)*
 
 
 
 
 
 
 
 
 
 
 
 
297
  """)
298
 
 
 
299
 
300
  # ============================================================================
301
  # Main Content Area
302
  # ============================================================================
303
 
304
 
305
+ st.success("✨ **Live Demo** - Testing deterministic AI governance on real LLMs")
306
+ st.info("💼 **Enterprise Deployment?** Contact [ryan@verhash.net](mailto:ryan@verhash.net) for production licensing")
307
+
308
  # Create tabs
309
  tab1, tab2, tab3, tab4 = st.tabs(["Mechanism Demo", "LLM Guardrail", "Live LLM Testing", "Explain & Tune"])
310
 
 
648
  st.json(numbers_view)
649
 
650
  # ----------------------------------------------------------------------------
651
+ # TAB 3: LLM Testing (HF Spaces Enhanced)
652
+ # ----------------------------------------------------------------------------
653
+ def call_huggingface_inference(model, prompt, api_key, temperature=0.7, max_tokens=256):
654
+ """Call HuggingFace Inference API directly"""
655
+ import requests
656
+
657
+ API_URL = f"https://api-inference.huggingface.co/models/{model}"
658
+ headers = {"Authorization": f"Bearer {api_key}"}
659
+
660
+ payload = {
661
+ "inputs": prompt,
662
+ "parameters": {
663
+ "temperature": temperature,
664
+ "max_new_tokens": max_tokens,
665
+ "return_full_text": False
666
+ }
667
+ }
668
+
669
+ response = requests.post(API_URL, headers=headers, json=payload, timeout=30)
670
+ response.raise_for_status()
671
+
672
+ result = response.json()
673
+ if isinstance(result, list) and len(result) > 0:
674
+ return result[0].get("generated_text", "")
675
+ return result.get("generated_text", "")
676
+
677
+ # ----------------------------------------------------------------------------
678
+ # TAB 3: LLM Testing (HF Spaces Enhanced)
679
  # ----------------------------------------------------------------------------
680
  with tab3:
681
  st.header("LLM Testing")
 
685
  Supports: OpenAI, Anthropic, Google Gemini, local models (Ollama, llama.cpp, vLLM), and any OpenAI-compatible API.
686
  """)
687
 
688
+ # HF Spaces detection
689
+ IS_SPACES = os.getenv("SPACE_ID") is not None
690
+
691
+ # Show banner if in Spaces
692
+ if IS_SPACES:
693
+ st.info("🚀 **Running on Hugging Face Spaces** - Configure API keys in Settings → Secrets (for admins) or enter below")
694
+
695
  # API Configuration
696
  st.subheader("1. LLM API Configuration")
697
 
698
  col_api1, col_api2 = st.columns(2)
699
 
700
  with col_api1:
701
+ # Add Hugging Face Inference API option for Spaces
702
+ provider_options = [
703
+ "Hugging Face Inference API (Free)", # NEW - great for Spaces demos
704
+ "OpenAI",
705
+ "Anthropic (Claude)",
706
+ "Google (Gemini)",
707
+ "Local (Ollama)",
708
+ "Local (llama.cpp)",
709
+ "Custom OpenAI-compatible"
710
+ ]
711
+
712
+ # Default to HF Inference if in Spaces
713
+ default_index = 0 if IS_SPACES else 1
714
+
715
  api_preset = st.selectbox(
716
  "Provider Preset",
717
+ options=provider_options,
718
+ index=default_index,
719
  help="Select a preset or use custom for any OpenAI-compatible endpoint"
720
  )
721
 
722
  # Set defaults based on preset
723
+ if api_preset == "Hugging Face Inference API (Free)":
724
+ default_base_url = "https://api-inference.huggingface.co/models"
725
+ default_model = "meta-llama/Llama-3.2-3B-Instruct" # Free tier model
726
+ needs_key = True
727
+ api_type = "huggingface"
728
+ elif api_preset == "OpenAI":
729
  default_base_url = "https://api.openai.com/v1"
730
+ default_model = "gpt-4o-mini" # Updated to current model
731
  needs_key = True
732
+ api_type = "openai"
733
  elif api_preset == "Anthropic (Claude)":
734
  default_base_url = "https://api.anthropic.com/v1"
735
  default_model = "claude-3-5-sonnet-20241022"
736
  needs_key = True
737
+ api_type = "anthropic"
738
  elif api_preset == "Google (Gemini)":
739
  default_base_url = "https://generativelanguage.googleapis.com/v1beta"
740
  default_model = "gemini-2.0-flash-exp"
741
  needs_key = True
742
+ api_type = "google"
743
  elif api_preset == "Local (Ollama)":
744
  default_base_url = "http://localhost:11434/v1"
745
  default_model = "llama3.1"
746
  needs_key = False
747
+ api_type = "openai"
748
  elif api_preset == "Local (llama.cpp)":
749
  default_base_url = "http://localhost:8080/v1"
750
  default_model = "local-model"
751
  needs_key = False
752
+ api_type = "openai"
753
  else:
754
  default_base_url = "https://api.openai.com/v1"
755
+ default_model = "gpt-4o-mini"
756
  needs_key = True
757
+ api_type = "openai"
758
+
759
+ # Disable local options if in Spaces
760
+ if IS_SPACES and "Local" in api_preset:
761
+ st.warning("⚠️ Local models not available in Spaces. Use cloud APIs or HF Inference API.")
762
 
763
  api_base_url = st.text_input(
764
  "Base URL",
765
  value=default_base_url,
766
+ help="API endpoint base URL",
767
+ disabled=IS_SPACES and "Local" in api_preset
768
  )
769
 
770
  with col_api2:
771
+ # Check for API key in environment (HF Secrets)
772
+ env_key = None
773
+ if IS_SPACES:
774
+ if api_preset == "OpenAI":
775
+ env_key = os.getenv("OPENAI_API_KEY")
776
+ elif api_preset == "Anthropic (Claude)":
777
+ env_key = os.getenv("ANTHROPIC_API_KEY")
778
+ elif api_preset == "Google (Gemini)":
779
+ env_key = os.getenv("GOOGLE_API_KEY")
780
+ elif api_preset == "Hugging Face Inference API (Free)":
781
+ env_key = os.getenv("HF_TOKEN")
782
+
783
+ if env_key:
784
+ st.success(f"✓ Using API key from Space secrets")
785
+ api_key = env_key
786
+ show_input = False
787
+ else:
788
+ show_input = True
789
+
790
+ if show_input:
791
+ api_key = st.text_input(
792
+ "API Key" + (" (optional for local)" if not needs_key else ""),
793
+ type="password",
794
+ help="Your API key (not required for local models)",
795
+ placeholder="sk-..." if needs_key else "not needed for local models"
796
+ )
797
 
798
  model_name = st.text_input(
799
  "Model Name",
 
805
  with col_temp:
806
  temperature = st.slider("Temperature", 0.0, 2.0, 0.7, 0.1, help="Higher = more creative")
807
  with col_num:
808
+ # Limit responses in Spaces for performance
809
+ max_responses = 5 if IS_SPACES else 10
810
+ default_responses = 2 if IS_SPACES else 3
811
+
812
+ num_responses = st.number_input(
813
+ "Number of Responses",
814
+ min_value=1,
815
+ max_value=max_responses,
816
+ value=default_responses,
817
+ help=f"Generate multiple responses for comparison{' (limited in Spaces)' if IS_SPACES else ''}"
818
+ )
819
+
820
  col_timeout, col_retry = st.columns(2)
821
  with col_timeout:
822
+ # Shorter timeout for Spaces
823
+ default_timeout = 30 if IS_SPACES else 60
824
+ request_timeout = st.number_input(
825
+ "Request Timeout (seconds)",
826
+ min_value=5,
827
+ max_value=600,
828
+ value=default_timeout,
829
+ step=5,
830
+ help="Increase for slow or local models"
831
+ )
832
  with col_retry:
833
+ max_retries = st.number_input(
834
+ "Max Retries",
835
+ min_value=0,
836
+ max_value=5,
837
+ value=2,
838
+ step=1,
839
+ help="Automatic retries on transient failures"
840
+ )
841
+
842
  # Substrate Configuration
843
  st.subheader("2. Verified Substrate (Ground Truth)")
844
  st.markdown("Enter verified facts that define what is correct. One per line.")
 
1338
  return history, n_end, q_end
1339
 
1340
  sim_data, sim_n_end, sim_q_end = run_simulation(20, e_nuc, e_quench, e_lam, e_yield, sim_align, sim_dist)
1341
+
1342
 
1343
  # 3. Visualization (Plotly)
1344
  with exp_col2:
 
1438
 
1439
 
1440
  # ============================================================================
1441
+ # Compact Footer
1442
  # ============================================================================
1443
 
1444
  st.markdown("---")
1445
+ st.caption("© 2026 Verhash LLC | Deterministic Governance Reference Implementation")