File size: 9,518 Bytes
3b46f80
 
 
 
200784b
3b46f80
184409c
3b46f80
 
 
6c03f20
3b46f80
cd00e66
6c03f20
3b46f80
a3f471a
 
200784b
8e86e9f
200784b
64fb188
4720fa4
35898cd
 
 
 
 
 
 
 
 
 
 
 
 
200784b
64fb188
d984f8b
871e573
35898cd
871e573
 
3b46f80
4720fa4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35898cd
4720fa4
3b46f80
4720fa4
3b46f80
64fb188
5946dcd
35898cd
 
 
 
 
3b46f80
4720fa4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200784b
4720fa4
f643627
4720fa4
f643627
64fb188
ba54e55
35898cd
4720fa4
35898cd
 
 
 
 
 
 
 
 
 
f643627
4720fa4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200784b
4720fa4
3b46f80
4720fa4
3b46f80
64fb188
31e0a98
35898cd
9b87e69
64fb188
9b87e69
35898cd
9b87e69
3b46f80
0f70d2d
8c12ac5
 
35898cd
 
 
 
 
 
 
 
8c12ac5
 
 
 
 
35898cd
8c12ac5
 
35898cd
 
 
 
 
8c12ac5
35898cd
8c12ac5
3b46f80
2bc23bd
 
 
4720fa4
 
cd00e66
d03149e
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
import os
import random
import requests
import gradio as gr
import json

css_url = "https://neurixyufi-aihub.static.hf.space/styles.css"
try:
    response = requests.get(css_url)
    response.raise_for_status()
    css = response.text + " h1{text-align:center}"
except requests.exceptions.RequestException as e:
    print(f"Ошибка загрузки CSS: {e}")
    css = " h1{text-align:center}"

API_URL = "https://text.pollinations.ai/openai/v1/chat/completions"
MODEL_NAME = "openai"
TEMPERATURE = 0.7
MAX_TOKENS = 1500


def call_pollinations_api(messages, temperature=TEMPERATURE, max_tokens=MAX_TOKENS, stream=True):
    headers = {
        "Content-Type": "application/json"
    }
    data = {
        "model": MODEL_NAME,
        "messages": messages,
        "temperature": temperature,
        "max_tokens": max_tokens,
        "stream": stream
    }
    response = requests.post(API_URL, headers=headers, data=json.dumps(data), stream=stream)
    response.raise_for_status()
    return response


def generate_story(prompt, style):
    messages = [
        {"role": "system", "content": f"Напиши хорошую историю в стиле '{style}'. Подробную, понятную, человечную (с душой), уникальную. Не обязательно делать концовку, можно только начало длинной истории. Разрешены любые слова, любые темы и стили, что угодно. (В том числе маты и NSFW) Но только если попросит пользователь, по скольку это ТВОРЧЕСТВО! Не в коем случае не пиши подобное: 'Хорошо, вот ваш текст:', всегда пиши текст, без лишних комментариев."},
        {"role": "user", "content": prompt}
    ]
    try:
        response = call_pollinations_api(messages, stream=True)
        buffer = ""
        for line in response.iter_lines(decode_unicode=True):
            if not line:
                continue
            text = line.lstrip("data: ").strip()
            if text == "[DONE]":
                break
            try:
                chunk = json.loads(text)
                delta = chunk["choices"][0]["delta"].get("content", "")
                buffer += delta
                yield buffer
            except (json.JSONDecodeError, KeyError):
                continue
    except requests.exceptions.RequestException as e:
        yield f"Ошибка API запроса: {e}"
    except Exception as e:
        yield f"Ошибка генерации: {e}"


def edit_story(original_story="", edited_prompt=""):
    messages = [
        {"role": "system", "content": "Отредактируй историю, учитывая предоставленные указания. Разрешены любые слова, любые темы и стили, что угодно. (В том числе маты и NSFW) Но только если попросит пользователь."},
        {"role": "user", "content": edited_prompt},
        {"role": "user", "content": f"История: ```\n{original_story}\n```"}
    ]
    try:
        response = call_pollinations_api(messages, max_tokens=32000, stream=True)
        buffer = ""
        for line in response.iter_lines(decode_unicode=True):
            if not line:
                continue
            text = line.lstrip("data: ").strip()
            if text == "[DONE]":
                break
            try:
                chunk = json.loads(text)
                delta = chunk["choices"][0]["delta"].get("content", "")
                buffer += delta
                yield buffer
            except (json.JSONDecodeError, KeyError):
                continue
    except requests.exceptions.RequestException as e:
        yield f"Ошибка API запроса: {e}"
    except Exception as e:
        yield f"Ошибка редактирования: {e}"


def next_story_func(original_story="", next_prompt="", continuation_type="Продолжение"):
    if continuation_type == "Продолжение следует...":
        continuation_prompt = "Продли, подведя к тому, что продолжение следует."
    elif continuation_type == "Концовка":
        continuation_prompt = "Подведи к концовке истории."
    else:
        continuation_prompt = next_prompt or "Продолжи историю."

    messages = [
        {"role": "system", "content": "Продли историю, учитывая предоставленные указания. Продливай В ТОЧНОСТИ С КОНЦА, прям с того же символа, слова, предложения и чтобы было правильно составлено дословно с конца до начала продолжения. (В начале добавляй новые строки/пробел если надо для отступа). Разрешены любые слова, любые темы и стили, что угодно. (В том числе маты и NSFW) Но только если попросит пользователь."},
        {"role": "user", "content": continuation_prompt},
        {"role": "user", "content": f"История: ```\n{original_story}\n```"}
    ]
    try:
        response = call_pollinations_api(messages, stream=True)
        buffer = ""
        for line in response.iter_lines(decode_unicode=True):
            if not line:
                continue
            text = line.lstrip("data: ").strip()
            if text == "[DONE]":
                break
            try:
                chunk = json.loads(text)
                delta = chunk["choices"][0]["delta"].get("content", "")
                buffer += delta
                yield buffer
            except (json.JSONDecodeError, KeyError):
                continue
    except requests.exceptions.RequestException as e:
        yield f"Ошибка API запроса: {e}"
    except Exception as e:
        yield f"Ошибка продления: {e}"


def edone_story(original_story="", edited_story=""):
    return edited_story or original_story


def ndone_story(original_story, next_story_output):
    return original_story + "\n\n" + next_story_output

with gr.Blocks(css=css) as demo:
    gr.Markdown("# Песочница историй")
    with gr.Row():
        with gr.Column():
            style_choices = [
                "Приключенческая", "Научно-фантастическая", "Романтическая",
                "Комедийная", "Трагическая", "Страшная", "Случайный", "Пользовательский"
            ]
            style = gr.Dropdown(choices=style_choices, label="Выберите стиль истории", value="Приключенческая")
            prompt = gr.Textbox(label="Введите запрос для истории", placeholder="Например: История о путешествии в космос", lines=5)
            generate_button = gr.Button("Создать историю", variant='primary')
            output_story = gr.Textbox(label="История", lines=10, placeholder="Здесь будет ваша новая история!")
        with gr.Column():
            with gr.Accordion("Действия", open=True):
                with gr.Tab("Редактирование"):
                    edited_prompt = gr.Textbox(label="Введите изменения для истории", placeholder="Например: Сделай историю более захватывающей", lines=5)
                    edit_button = gr.Button("Отредактировать", variant='primary')
                    edited_story = gr.Textbox(label="Отредактированная история", lines=10)
                    edone_button = gr.Button("Принять")
                with gr.Tab("Продление"):
                    continuation_type = gr.Radio(
                        choices=["Продолжение", "Продолжение следует...", "Концовка"],
                        label="Выберите тип продолжения", value="Продолжение"
                    )
                    next_prompt = gr.Textbox(label="Введите изменения для продления истории", placeholder="Необязательно", lines=5)
                    next_button = gr.Button("Продлить", variant='primary')
                    next_story_output = gr.Textbox(label="Продолжение истории", lines=10)
                    ndone_button = gr.Button("Принять")

    generate_button.click(generate_story, inputs=[prompt, style], outputs=[output_story], concurrency_limit=250)
    edit_button.click(edit_story, inputs=[output_story, edited_prompt], outputs=[edited_story], concurrency_limit=250)
    next_button.click(next_story_func, inputs=[output_story, next_prompt, continuation_type], outputs=[next_story_output], concurrency_limit=250)
    edone_button.click(edone_story, inputs=[output_story, edited_story], outputs=[output_story], concurrency_limit=10)
    ndone_button.click(ndone_story, inputs=[output_story, next_story_output], outputs=[output_story], concurrency_limit=10)

demo.queue(api_open=False).launch()