Spaces:
Sleeping
Sleeping
Create app.py
Browse files
app.py
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
YSenseAI Wisdom Canvas Demo v4.5-Beta
|
| 3 |
+
A demonstration of the Story-First UX for ethical AI training data collection.
|
| 4 |
+
"""
|
| 5 |
+
|
| 6 |
+
import gradio as gr
|
| 7 |
+
import hashlib
|
| 8 |
+
import uuid
|
| 9 |
+
import json
|
| 10 |
+
from datetime import datetime
|
| 11 |
+
|
| 12 |
+
def generate_attribution(story, author_name):
|
| 13 |
+
timestamp = datetime.utcnow().isoformat() + "Z"
|
| 14 |
+
content_hash = hashlib.sha256(story.encode('utf-8')).hexdigest()
|
| 15 |
+
did = f"did:ysense:{uuid.uuid4().hex[:16]}"
|
| 16 |
+
return {
|
| 17 |
+
"did": did,
|
| 18 |
+
"content_hash": content_hash,
|
| 19 |
+
"author": author_name or "Anonymous",
|
| 20 |
+
"timestamp": timestamp,
|
| 21 |
+
"version": "v4.5-beta",
|
| 22 |
+
"protocol": "Z-Protocol v2.0"
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
def analyze_perception_layers(story):
|
| 26 |
+
word_count = len(story.split())
|
| 27 |
+
sentences = story.split('.')
|
| 28 |
+
return {
|
| 29 |
+
"narrative": f"A personal story with {len(sentences)} key moments, exploring meaningful experiences.",
|
| 30 |
+
"somatic": "Physical presence and embodied experience are woven throughout the narrative.",
|
| 31 |
+
"attention": "The author's focus reveals what matters most in this moment of reflection.",
|
| 32 |
+
"synesthetic": "Sensory details paint a vivid picture of the experience.",
|
| 33 |
+
"temporal": f"The story unfolds across time, with {word_count} words capturing the journey."
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
def distill_essence(story, layers):
|
| 37 |
+
words = story.lower().split()
|
| 38 |
+
common = {'about', 'there', 'would', 'could', 'should', 'their', 'these', 'those', 'which', 'where', 'being'}
|
| 39 |
+
meaningful = [w.strip('.,!?') for w in words if len(w) > 5 and w not in common][:3]
|
| 40 |
+
if len(meaningful) < 3:
|
| 41 |
+
meaningful = ["wisdom", "growth", "journey"]
|
| 42 |
+
return {
|
| 43 |
+
"essence": " ".join(meaningful[:3]).title(),
|
| 44 |
+
"meaning": "These words capture the core themes of your story.",
|
| 45 |
+
"wisdom_type": "personal growth"
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
def calculate_quality_metrics(story, layers, essence):
|
| 49 |
+
word_count = len(story.split())
|
| 50 |
+
sentence_count = len([s for s in story.split('.') if s.strip()])
|
| 51 |
+
metrics = {
|
| 52 |
+
"authenticity": min(100, 50 + (word_count // 10)),
|
| 53 |
+
"emotional_depth": min(100, 60 + len(layers.get("somatic", "")) // 2),
|
| 54 |
+
"narrative_clarity": min(100, 70 if sentence_count > 3 else 50),
|
| 55 |
+
"cultural_richness": min(100, 55 + (word_count // 20)),
|
| 56 |
+
"wisdom_density": min(100, 65 if essence.get("wisdom_type") else 45),
|
| 57 |
+
"training_value": 0
|
| 58 |
+
}
|
| 59 |
+
metrics["training_value"] = sum(list(metrics.values())[:-1]) // 5
|
| 60 |
+
return metrics
|
| 61 |
+
|
| 62 |
+
def process_story(story, author_name, consent_research, consent_commercial, consent_derivative, consent_attribution):
|
| 63 |
+
if not story or len(story.strip()) < 50:
|
| 64 |
+
return "Please write at least 50 characters to analyze.", "", "", "", "", ""
|
| 65 |
+
|
| 66 |
+
attribution = generate_attribution(story, author_name)
|
| 67 |
+
attribution_display = f"""### Attribution Record
|
| 68 |
+
| Field | Value |
|
| 69 |
+
|-------|-------|
|
| 70 |
+
| **DID** | `{attribution['did']}` |
|
| 71 |
+
| **Content Hash** | `{attribution['content_hash'][:32]}...` |
|
| 72 |
+
| **Author** | {attribution['author']} |
|
| 73 |
+
| **Timestamp** | {attribution['timestamp']} |
|
| 74 |
+
| **Protocol** | {attribution['protocol']} |"""
|
| 75 |
+
|
| 76 |
+
layers = analyze_perception_layers(story)
|
| 77 |
+
layers_display = f"""### 5-Layer Perception Analysis
|
| 78 |
+
**Narrative Layer**: {layers.get('narrative', 'N/A')}
|
| 79 |
+
|
| 80 |
+
**Somatic Layer**: {layers.get('somatic', 'N/A')}
|
| 81 |
+
|
| 82 |
+
**Attention Layer**: {layers.get('attention', 'N/A')}
|
| 83 |
+
|
| 84 |
+
**Synesthetic Layer**: {layers.get('synesthetic', 'N/A')}
|
| 85 |
+
|
| 86 |
+
**Temporal Layer**: {layers.get('temporal', 'N/A')}"""
|
| 87 |
+
|
| 88 |
+
essence = distill_essence(story, layers)
|
| 89 |
+
essence_display = f"""### 3-Word Essence
|
| 90 |
+
# {essence.get('essence', 'Wisdom Awaits You')}
|
| 91 |
+
**Meaning:** {essence.get('meaning', 'Your story holds unique wisdom.')}
|
| 92 |
+
**Wisdom Type:** {essence.get('wisdom_type', 'personal growth').title()}"""
|
| 93 |
+
|
| 94 |
+
metrics = calculate_quality_metrics(story, layers, essence)
|
| 95 |
+
metrics_display = f"""### Quality Metrics
|
| 96 |
+
| Metric | Score |
|
| 97 |
+
|--------|-------|
|
| 98 |
+
| Authenticity | {metrics['authenticity']}% |
|
| 99 |
+
| Emotional Depth | {metrics['emotional_depth']}% |
|
| 100 |
+
| Narrative Clarity | {metrics['narrative_clarity']}% |
|
| 101 |
+
| Cultural Richness | {metrics['cultural_richness']}% |
|
| 102 |
+
| Wisdom Density | {metrics['wisdom_density']}% |
|
| 103 |
+
| **Training Value** | **{metrics['training_value']}%** |"""
|
| 104 |
+
|
| 105 |
+
consent_types = []
|
| 106 |
+
if consent_research: consent_types.append("Research Use")
|
| 107 |
+
if consent_commercial: consent_types.append("Commercial Training")
|
| 108 |
+
if consent_derivative: consent_types.append("Derivative Works")
|
| 109 |
+
if consent_attribution: consent_types.append("Public Attribution")
|
| 110 |
+
if not consent_types: consent_types.append("No consent granted")
|
| 111 |
+
|
| 112 |
+
consent_display = f"""### Z-Protocol v2.0 Consent
|
| 113 |
+
{chr(10).join(['- ' + c for c in consent_types])}
|
| 114 |
+
**Consent Hash:** `{hashlib.sha256(str(consent_types).encode()).hexdigest()[:16]}`
|
| 115 |
+
**Revocable:** Yes"""
|
| 116 |
+
|
| 117 |
+
export_data = {
|
| 118 |
+
"attribution": attribution,
|
| 119 |
+
"layers": layers,
|
| 120 |
+
"essence": essence,
|
| 121 |
+
"metrics": metrics,
|
| 122 |
+
"consent": {"research": consent_research, "commercial": consent_commercial, "derivative": consent_derivative, "attribution": consent_attribution}
|
| 123 |
+
}
|
| 124 |
+
export_display = f"""### Export Preview
|
| 125 |
+
```json
|
| 126 |
+
{json.dumps(export_data, indent=2)}
|
| 127 |
+
```"""
|
| 128 |
+
|
| 129 |
+
return attribution_display, layers_display, essence_display, metrics_display, consent_display, export_display
|
| 130 |
+
|
| 131 |
+
example_stories = [
|
| 132 |
+
["My grandmother taught me to make dumplings when I was seven. Her hands, weathered from decades of work, moved with a grace I couldn't understand then. She never measured anything - a pinch of this, a handful of that. Years later, standing in my own kitchen, I finally understood: she wasn't teaching me to cook. She was passing down a language of love that words could never capture.", "Anonymous"],
|
| 133 |
+
["The day I failed my first exam, my father didn't say a word. He just took me fishing. We sat by the lake for hours in silence. When the sun set, he finally spoke: 'The fish don't care about your grades. Neither do I. I care about who you become.' That silence taught me more than any lecture ever could.", "Anonymous"]
|
| 134 |
+
]
|
| 135 |
+
|
| 136 |
+
with gr.Blocks(title="YSenseAI Wisdom Canvas") as demo:
|
| 137 |
+
gr.HTML("""<div style="text-align:center;padding:20px;background:linear-gradient(135deg,#0f172a,#1e293b);border-radius:12px;margin-bottom:20px;">
|
| 138 |
+
<h1 style="color:#f59e0b;font-size:2.5em;margin-bottom:10px;">YSenseAI Wisdom Canvas</h1>
|
| 139 |
+
<p style="color:#94a3b8;font-size:1.1em;">v4.5-Beta | Share your stories. Preserve your wisdom. Shape ethical AI.</p>
|
| 140 |
+
<p style="margin-top:10px;"><a href="https://ysenseai.org" target="_blank" style="color:#22d3ee;margin-right:15px;">Website</a>
|
| 141 |
+
<a href="https://github.com/creator35lwb-web/YSense-AI-Attribution-Infrastructure" target="_blank" style="color:#22d3ee;margin-right:15px;">GitHub</a>
|
| 142 |
+
<a href="https://doi.org/10.5281/zenodo.17737995" target="_blank" style="color:#22d3ee;">White Paper</a></p></div>""")
|
| 143 |
+
|
| 144 |
+
with gr.Row():
|
| 145 |
+
with gr.Column(scale=1):
|
| 146 |
+
gr.Markdown("## Story Canvas")
|
| 147 |
+
story_input = gr.Textbox(label="Your Story", placeholder="Share a meaningful moment...", lines=8)
|
| 148 |
+
author_input = gr.Textbox(label="Author Name (optional)", placeholder="Anonymous", lines=1)
|
| 149 |
+
gr.Markdown("### Z-Protocol Consent")
|
| 150 |
+
with gr.Row():
|
| 151 |
+
consent_research = gr.Checkbox(label="Research Use", value=True)
|
| 152 |
+
consent_commercial = gr.Checkbox(label="Commercial Training", value=False)
|
| 153 |
+
with gr.Row():
|
| 154 |
+
consent_derivative = gr.Checkbox(label="Derivative Works", value=True)
|
| 155 |
+
consent_attribution = gr.Checkbox(label="Public Attribution", value=False)
|
| 156 |
+
analyze_btn = gr.Button("Analyze & Distill", variant="primary")
|
| 157 |
+
gr.Examples(examples=example_stories, inputs=[story_input, author_input])
|
| 158 |
+
|
| 159 |
+
with gr.Column(scale=1):
|
| 160 |
+
gr.Markdown("## Analysis Results")
|
| 161 |
+
with gr.Accordion("Attribution", open=True):
|
| 162 |
+
attribution_output = gr.Markdown()
|
| 163 |
+
with gr.Accordion("5-Layer Analysis", open=True):
|
| 164 |
+
layers_output = gr.Markdown()
|
| 165 |
+
with gr.Accordion("3-Word Essence", open=True):
|
| 166 |
+
essence_output = gr.Markdown()
|
| 167 |
+
with gr.Accordion("Quality Metrics", open=False):
|
| 168 |
+
metrics_output = gr.Markdown()
|
| 169 |
+
with gr.Accordion("Consent Record", open=False):
|
| 170 |
+
consent_output = gr.Markdown()
|
| 171 |
+
with gr.Accordion("Export Preview", open=False):
|
| 172 |
+
export_output = gr.Markdown()
|
| 173 |
+
|
| 174 |
+
analyze_btn.click(fn=process_story, inputs=[story_input, author_input, consent_research, consent_commercial, consent_derivative, consent_attribution], outputs=[attribution_output, layers_output, essence_output, metrics_output, consent_output, export_output])
|
| 175 |
+
gr.HTML("""<footer style="text-align:center;padding:20px;color:#64748b;"><p>2025 YSenseAI | MIT License | <a href="https://doi.org/10.5281/zenodo.17737995" target="_blank">DOI: 10.5281/zenodo.17737995</a></p></footer>""")
|
| 176 |
+
|
| 177 |
+
if __name__ == "__main__":
|
| 178 |
+
demo.launch()
|