File size: 6,120 Bytes
9c24cef
 
c4528c6
9c24cef
c4528c6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9c24cef
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c4528c6
9c24cef
 
 
 
 
 
 
 
 
c4528c6
9c24cef
 
 
 
 
 
 
 
 
 
 
 
c4528c6
9c24cef
c4528c6
9c24cef
c4528c6
9c24cef
 
 
 
c4528c6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9c24cef
 
 
 
 
 
 
 
 
c4528c6
9c24cef
 
 
c4528c6
 
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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
import openai
from openai import OpenAI
import difflib

prompt_fix_text_gpt = "Исправь ошибки в данном тексте:\n{}"

prompt_compare_get_comment = """
Ты должен писать комментарии об ошибках в тексте.
Тебе дан кусок текст, в котором есть одна или несколько ошибок и этот же кусок текста с исправленными ошибками. 
Твоя задача - кратко описать суть каждой ошибки и, если необходимо, исправить её. Отвечай на русском языке.


### Пример 1:
original text:
"кросивую"

corrected text: 
"красивую"

Твой ответ: 
Орфографическая ошибка: "кросивую" -> "красивую".


### Пример 2:
original:
"я решил  пойти в"

corrected text: 
"я решил пойти в"

Твой ответ: 
Опечатка: повтор пробла.


Теперь твоя очередь:
original:
"{}"

corrected text: 
"{}"
"""

prompt = """
Ты должен писать комментарии об ошибках в тексте.
Тебе дан кусок текст, в котором есть ошибка, контекст, в котором стоит это слово и сообщение об ошибке. Твоя задача - кратко описать суть ошибки и, если необходимо, исправить её. 
Исправляй только ту ошибку, на которую указывает сообщение. Отвечай на русском языке.

### Пример 1:
Кусок текста:
"кросивую"

Сообщение об ошибке: 
"Возможно найдена орфографическая ошибка."

Текст: 
"...т! Сегодня я был в парке и встретил там кросивую собаку. Она повиляла хвостом и побежа..."

Твой ответ: 
Орфографическая ошибка в слове "кросивую" - правильно "красивую".

### Пример 2:
Кусок текста:
"  "

Сообщение об ошибке: 
"Повтор пробела."

Текст: 
"...ретил там кросивую собаку.  Она повиляла  хвостом и побежала к речке. Я решил что ..."

Твой ответ: 
Обнаружен повтор пробела между словами.

Теперь твоя очередь:
Кусок текста:
"{}"

Сообщение об ошибке: 
"{}"

Текст: 
"{}"
"""


def get_gpt_response_openai(inp):
    response = openai.ChatCompletion.create(
        model="gpt-4o-mini",
        messages=[
            {"role": "user", "content": inp}
        ]
    )
    return response.choices[0].message['content']


def get_gpt_response_vsegpt(inp):
    client = OpenAI(
        api_key='sk-or-vv-44ca318747a45e810149bf769e9dfbe5f42046695875efd7c9121cca590d6906',
        base_url='https://api.vsegpt.ru/v1'
    )
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": inp}]
    ).choices[0].message.content

    return response


def get_gpt_response(inp, client_name):
    if client_name == "openai":
        return get_gpt_response_openai(inp)
    elif client_name == "vsegpt":
        return get_gpt_response_vsegpt(inp)
    else:
        raise ValueError(f"Unsupported client: {client_name}")
    

def find_corrected_positions(original, corrected):
    matcher = difflib.SequenceMatcher(None, original, corrected)
    changes = []
    
    for opcode in matcher.get_opcodes():
        tag, i1, i2, j1, j2 = opcode
        if tag != 'equal':
            changes.append({
                'original': (i1, i2),
                'corrected': (j1, j2),
                'operation': tag
            })
    
    return changes


def get_piece_of_text_bounds(s, start, end):
    if start != 0: start -= 1
    while start != 0 and s[start] not in [' ', "\n", '\t']:
        start -= 1
    start += 1

    if end < len(s) - 1: end += 1
    while end < len(s) - 1 and s[end] not in [' ', "\n", '\t']:
        end += 1
    return start, end


def add_comments_to_text(text, errors):
    errors = sorted(errors, key=lambda x: x['end'])

    shift = 0
    for i, error in enumerate(errors, 1):
        error['start'] += shift
        error['end'] += shift
        inp = f"({i})"
        text = text[:error['end']] + inp + text[error['end']:]
        shift += len(inp)

    return text.replace("\n", " ")


def check_text_chat_gpt(text, *args, **kwargs):
    fixed_text = get_gpt_response(prompt_fix_text_gpt.format(text), "vsegpt")
    changes = find_corrected_positions(text, fixed_text)
    errors = []
    for change in changes:
        start_orig, end_orid = get_piece_of_text_bounds(text, change['original'][0], change['original'][1])
        start_corr, end_corr = get_piece_of_text_bounds(fixed_text, change['corrected'][0], change['corrected'][1])
        inp = prompt_compare_get_comment.format(text[start_orig:end_orid], fixed_text[start_corr:end_corr])
        errors.append({
            'start': start_orig,
            'end': end_orid,
            'message': get_gpt_response(inp, client_name="vsegpt"),
        })

    text_with_comments = add_comments_to_text(text, errors)
    return text_with_comments, errors

def check_text(text, tool):
    matches = tool.check(text)
    errors = []
    for match in matches:
        inp = prompt.format(text[match.offset:match.offset + match.errorLength], 
                            match.message, match.context)
        error_info = {
            'start': match.offset,
            'end': match.offset + match.errorLength,
            'message': get_gpt_response(inp, client_name="vsegpt"),
        }
        errors.append(error_info)
    
    text_with_comments = add_comments_to_text(text, errors)
    return text_with_comments, errors