File size: 4,034 Bytes
2a4f8c1
 
 
abb982c
2a4f8c1
 
 
 
 
 
 
 
 
c587702
2a4f8c1
 
 
 
 
abb982c
 
6cf0e48
abb982c
2a4f8c1
 
c587702
 
2a4f8c1
 
 
abb982c
2a4f8c1
abb982c
2a4f8c1
c587702
2a4f8c1
 
 
 
 
 
 
abb982c
2a4f8c1
abb982c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a84de7c
 
 
 
 
 
 
2a4f8c1
abb982c
2a4f8c1
46bcb50
 
5fac9f7
46bcb50
a25d416
 
 
6cf0e48
a25d416
2a4f8c1
 
6cf0e48
 
2a4f8c1
6cf0e48
3929f15
7eb507d
6cf0e48
 
abb982c
6cf0e48
2a4f8c1
6cf0e48
2a4f8c1
2d465c8
 
6cf0e48
 
 
 
 
 
 
2a4f8c1
abb982c
 
 
2a4f8c1
5e3e841
2a4f8c1
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import gradio as gr
import requests
import os
import random

# Load instructions from local files
def load_instruction(persona):
    try:
        with open(f"instructions/{persona.lower()}.txt", "r") as file:
            return file.read()
    except FileNotFoundError:
        return ""

# Call Cohere R+ model via API
def call_cohere_api(system_instruction, user_prompt):
    headers = {
        "Authorization": f"Bearer {os.getenv('COHERE_API_KEY')}",
        "Content-Type": "application/json"
    }
    
    # Append the word limit instruction
    user_prompt += "\n\nAnswer in 200 words or fewer."
    
    payload = {
        "model": "command-r-plus",
        "message": user_prompt,
        "preamble": system_instruction,
        "max_tokens": 300
    }
    response = requests.post("https://api.cohere.ai/v1/chat", headers=headers, json=payload)
    
    if response.status_code == 200:
        return response.json().get("text", "No response").strip()
    else:
        return f"Error: {response.status_code} - {response.text}"

# Wrapper for dual assistant responses
def ask_forest_oracle(persona1, persona2, prompt):
    instruction1 = load_instruction(persona1)
    instruction2 = load_instruction(persona2)
    response1 = call_cohere_api(instruction1, prompt)
    response2 = call_cohere_api(instruction2, prompt)
    return response1, response2

# Load questions from a text file
def load_questions():
    try:
        with open("questions.txt", "r") as file:
            questions = [line.strip() for line in file if line.strip()]
            return questions
    except FileNotFoundError:
        return []

questions_list = load_questions()

# Function to get a random question
def get_random_question():
    if questions_list:
        return random.choice(questions_list)
    else:
        return "No questions found. Please add questions to questions.txt."

# Dynamically load persona names from instructions folder
personas = [
    os.path.splitext(f)[0].capitalize()
    for f in os.listdir("instructions")
    if f.endswith(".txt")
]

# Gradio Interface
with gr.Blocks() as demo:
    with gr.Row():
        with gr.Column(scale=0.15):
            gr.Image(value="data/MoreThanHumanVoices.png", label="More Than Human Voices", show_label=False)
        with gr.Column():
            gr.Markdown("""# More Than Human Voices 🌳🪶
*Conversations with the more-than-human world.*
This interactive experience allows you to ask questions to non-human personas—trees, crows, fungi, rivers—each responding from their own unique ecological viewpoint.
Rooted in poetic imagination but grounded in truth, these voices offer insight into the living Earth and our entanglement with it.
""")

    with gr.Row():
        persona1 = gr.Dropdown(personas, label="Choose First Persona", value="Western human")
        persona2 = gr.Dropdown(personas, label="Choose Second Persona", value="Fungal network")

    # Question box with random question generator
    with gr.Row():
        user_input = gr.Textbox(label="Your Question to them", placeholder="e.g., What do you think of humans?", lines=2)
        random_button = gr.Button("🎲 Generate Random Question")

    with gr.Row():
        ask_button = gr.Button("🌱 Submit Question")

    # Textboxes that dynamically display the persona names
    with gr.Row():
        output1 = gr.Textbox(label="Persona 1 Responds")
        output2 = gr.Textbox(label="Persona 2 Responds")

    # Update the labels when personas are selected
    def update_labels(p1, p2):
        return f"{p1} Responds", f"{p2} Responds"

    persona1.change(fn=update_labels, inputs=[persona1, persona2], outputs=[output1, output2])
    persona2.change(fn=update_labels, inputs=[persona1, persona2], outputs=[output1, output2])

    # Button events
    random_button.click(fn=get_random_question, inputs=[], outputs=[user_input])
    ask_button.click(fn=ask_forest_oracle, inputs=[persona1, persona2, user_input], outputs=[output1, output2])


if __name__ == "__main__":
    demo.launch()