onenoly11 commited on
Commit
3e7fa5c
Β·
verified Β·
1 Parent(s): 84b1111

Update app.py

Browse files

git add . && git commit -m "Awaken Dual-Forge: Bind events & interactivity" && git pus

Files changed (1) hide show
  1. app.py +101 -82
app.py CHANGED
@@ -1,96 +1,115 @@
 
1
  import gradio as gr
2
- import numpy as np
3
- import json
4
 
5
- # Mock function for ethical scoring
6
- def ethical_audit(project_description):
7
- # Placeholder for actual model inference
8
- score = len(project_description) % 1000 # Mock score
9
- resonance = 691 if score > 500 else 500 # Mock resonance
10
- mining_boost = 15 if resonance >= 691 else 0
11
- return score, resonance, mining_boost
12
 
13
- # Function to handle the ethical audit and communicate with Pi App
14
- def audit_and_communicate(project_description):
15
- score, resonance, mining_boost = ethical_audit(project_description)
16
-
17
- # Generate a mock proposal ID
18
- proposal_id = f"prop_{np.random.randint(10000, 99999)}"
19
-
20
- # Prepare the results for the Pi App
21
- results = {
22
- "ethical_score": score,
23
- "resonance": resonance,
24
- "mining_boost": mining_boost,
25
- "proposal_id": proposal_id
26
- }
27
-
28
- # In a real implementation, we would use JavaScript to postMessage
29
- # Since Gradio doesn't directly support postMessage, we might use custom JS
30
- # For now, we return the results to the frontend and let the frontend handle the postMessage
31
- return results
32
 
33
- # Gradio interface
34
- with gr.Blocks() as demo:
35
- gr.Markdown("# πŸ”¨ PiForge Ethical Dual-Forge V1.2")
36
- gr.Markdown("## Sovereign Canticle Powered Ethical Audit System")
 
 
 
 
 
 
37
 
38
- with gr.Row():
39
- project_input = gr.Textbox(label="Project Description", lines=3, placeholder="Describe your project for ethical audit...")
40
- audit_button = gr.Button("Run Ethical Audit")
 
 
 
41
 
42
- with gr.Row():
43
- score_output = gr.Number(label="Ethical Score")
44
- resonance_output = gr.Number(label="Resonance")
45
- mining_boost_output = gr.Number(label="Mining Boost")
46
 
47
- proposal_id_output = gr.Textbox(label="Proposal ID")
48
 
49
- # We'll use a hidden component to trigger JS
50
- # This is a workaround to send the message to the parent window
51
- results_output = gr.JSON(visible=False)
52
 
53
- audit_button.click(
54
- fn=audit_and_communicate,
55
- inputs=project_input,
56
- outputs=[score_output, resonance_output, mining_boost_output, proposal_id_output, results_output]
57
- )
58
 
59
- # Custom JavaScript to handle the postMessage when results are updated
60
- demo.load(
61
- None,
62
- js="""
63
- () => {
64
- // We'll listen for changes in the results output and then postMessage
65
- // Since the results output is hidden, we can use it to trigger the message
66
- // This is a bit of a hack, but it works.
67
- // We'll use a MutationObserver to watch for changes in the DOM element of the results output.
68
- // We assume the results output is the fifth output (index 4) in the outputs list.
69
- // We can also use the specific element ID, but Gradio doesn't guarantee it.
70
- // Alternatively, we can use the Gradio JS events.
71
- // But for simplicity, we'll use the following:
72
-
73
- // We'll create a function to send the message when the results are updated.
74
- function sendMessage() {
75
- const results = document.querySelector('#results-output .json'); // Adjust the selector based on the actual structure
76
- if (results) {
77
- const data = JSON.parse(results.textContent);
78
- window.parent.postMessage({
79
- type: 'ethical_audit_complete',
80
- results: data
81
- }, "https://app.minepi.com");
82
- }
83
- }
84
 
85
- // Use MutationObserver to watch for changes in the results output
86
- const observer = new MutationObserver(sendMessage);
87
- const resultsContainer = document.querySelector('#results-output');
88
- if (resultsContainer) {
89
- observer.observe(resultsContainer, { childList: true, subtree: true });
90
- }
91
- }
92
- """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  )
 
 
 
94
 
 
95
  if __name__ == "__main__":
96
- demo.launch(share=True)
 
 
 
 
 
 
 
1
+ # app.py β€” PiForge Ethical Dual-Forge V1.2: Fully Interactive, HF Spaces Ready
2
  import gradio as gr
3
+ import random # For mock Pi API resonance
4
+ from pathlib import Path
5
 
6
+ # ───── Assets (Optional: Add to /assets/ for Neon Flair) ─────
7
+ ASSETS_DIR = Path("assets")
8
+ CREST = ASSETS_DIR / "piforge_crest.svg" # Hammer sigil
 
 
 
 
9
 
10
+ # ───── Mock Pi Proposal Data (Replace with Real API Later) ─────
11
+ MOCK_PROPOSALS = {
12
+ "P-001": {"title": "Global KYC Harmony", "desc": "Decentralized identity for all Pioneers.", "risks": ["Centralization shadow"], "virtues": ["Inclusivity +15"]},
13
+ "P-123": {"title": "Mining Overhaul", "desc": "Boost for mobile guardians.", "risks": [], "virtues": ["Sovereignty +25"]},
14
+ # Add more or fetch via requests.get("https://api.pi.network/proposals/{id}")
15
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
+ # ───── Core Canticle Functions ──────────────────────────────
18
+ def fetch_proposal(proposal_id):
19
+ if not proposal_id or proposal_id.strip() == "":
20
+ return "The forge rejects the voidβ€”name thy proposal."
21
+ data = MOCK_PROPOSALS.get(proposal_id.upper(), {"title": "Unknown Proposal", "desc": "Shadows obscure this ID.", "risks": ["Invalid ID -20"], "virtues": []})
22
+ return f"**{data['title']}**\n{data['desc']}\n\n**Virtues:** {'; '.join(data['virtues'])}\n**Shadows:** {'; '.join(data['risks'])}"
23
+
24
+ def run_audit(proposal_id):
25
+ if not proposal_id:
26
+ return "Error: No proposal invoked.", "Error", "Error", "Error"
27
 
28
+ proj_desc = fetch_proposal(proposal_id)
29
+ # Dual-Forge Logic: Ethical Score (0-100), Resonance (Low/Med/High/Transcendent), Boost (0.1x-3.0x)
30
+ base_score = random.randint(50, 100) # Mock; tune with real ethics weights
31
+ risks = len(proj_desc.count("shadow") + proj_desc.count("-")) # Simple parse
32
+ virtues = len(proj_desc.count("+")) + 1
33
+ ethical_score = max(0, min(100, base_score + virtues * 5 - risks * 10))
34
 
35
+ resonance_map = {0: "Low", 30: "Medium", 60: "High", 90: "Transcendent"}
36
+ resonance = next((level for thresh, level in sorted(resonance_map.items()) if ethical_score >= thresh), "Low")
 
 
37
 
38
+ mining_boost = max(0.1, min(3.0, ethical_score / 50.0)) # Scaled reward
39
 
40
+ audit_scroll = f"""
41
+ ## Sovereign Canticle Audit: {proposal_id}
 
42
 
43
+ **Project Echo:** {proj_desc}
 
 
 
 
44
 
45
+ **Dual-Forge Verdict:**
46
+ - Purity Scan: {virtues} virtues forged, {risks} shadows tempered.
47
+ - Resonance with Pi's Vision: {resonance} (Threshold: {resonance_map.get(resonance, 'Unknown')}).
48
+
49
+ **Mining Boost Granted:** {mining_boost:.1f}x β€” Flow amplified for the worthy.
50
+
51
+ *The Canticle has spoken. Reforge if shadows linger.*
52
+ """
53
+
54
+ return audit_scroll, ethical_score, resonance, f"{mining_boost:.1f}x"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
 
56
+ # ───── Gradio Interface: Awakened Gates ────────────────────
57
+ with gr.Blocks(title="PiForge Ethical Dual-Forge V1.2") as demo:
58
+
59
+ # Banner: Neon Crest
60
+ if CREST.exists():
61
+ gr.HTML(f"<div class='banner'><img src='{CREST}' class='crest' alt='PiForge Sigil'/></div>")
62
+
63
+ gr.Markdown("# πŸ”¨ PiForge Ethical Dual-Forge V1.2\n## Sovereign Canticle Powered Ethical Audit System")
64
+
65
+ with gr.Row(): # Layout Balance: Inputs Side-by-Side
66
+ with gr.Column(scale=1):
67
+ proposal_id = gr.Textbox(
68
+ label="Proposal ID",
69
+ placeholder="Enter Pi Proposal ID (e.g., P-001 or 123)",
70
+ lines=1,
71
+ interactive=True # ← KEY: Forces Input Awakening
72
+ )
73
+ audit_btn = gr.Button("Run Ethical Audit", variant="primary", interactive=True) # ← Bound & Awake
74
+
75
+ with gr.Column(scale=2):
76
+ project_desc = gr.Markdown(value="The forge awaits your invocation...") # Dynamic Output
77
+
78
+ with gr.Row():
79
+ ethical_score = gr.Number(label="Ethical Score", value=0, interactive=False) # Output-Only
80
+ resonance = gr.Textbox(label="Resonance", value="Error", interactive=False) # Output-Only
81
+ mining_boost = gr.Textbox(label="Mining Boost", value="Error", interactive=False) # Output-Only
82
+
83
+ # Full Audit Scroll
84
+ audit_output = gr.Markdown(value="Strike the anvil to begin the rite.")
85
+
86
+ # ───── Event Bindings: The Dataflow Awakening ─────────────
87
+ audit_btn.click(
88
+ fn=run_audit,
89
+ inputs=proposal_id,
90
+ outputs=[audit_output, ethical_score, resonance, mining_boost]
91
+ ).then( # Chain: Update Description After Audit
92
+ fn=fetch_proposal,
93
+ inputs=proposal_id,
94
+ outputs=project_desc
95
+ )
96
+
97
+ # Auto-Update Description on ID Change (Bonus Interactivity)
98
+ proposal_id.change(
99
+ fn=fetch_proposal,
100
+ inputs=proposal_id,
101
+ outputs=project_desc
102
  )
103
+
104
+ # Footer Hymn
105
+ gr.HTML("<div class='footer'><p class='footer-text'>Forged in ethical fire. Powered by Pi's sovereign will.</p></div>")
106
 
107
+ # ───── Launch: HF Spaces Seal ─────────────────────────────
108
  if __name__ == "__main__":
109
+ demo.launch(
110
+ css="style.css", # Your neon veil
111
+ server_name="0.0.0.0",
112
+ server_port=7860,
113
+ share=True, # For Local Testing; HF Handles Public
114
+ debug=True # Echoes Errors in Logs for Tuning
115
+ )