cat-stack 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cat_stack/__about__.py +10 -0
- cat_stack/__init__.py +128 -0
- cat_stack/_batch.py +1388 -0
- cat_stack/_category_analysis.py +348 -0
- cat_stack/_chunked.py +424 -0
- cat_stack/_embeddings.py +189 -0
- cat_stack/_formatter.py +169 -0
- cat_stack/_providers.py +1048 -0
- cat_stack/_tiebreaker.py +277 -0
- cat_stack/_utils.py +512 -0
- cat_stack/_web_fetch.py +194 -0
- cat_stack/calls/CoVe.py +287 -0
- cat_stack/calls/__init__.py +25 -0
- cat_stack/calls/all_calls.py +622 -0
- cat_stack/calls/image_CoVe.py +386 -0
- cat_stack/calls/image_stepback.py +210 -0
- cat_stack/calls/pdf_CoVe.py +386 -0
- cat_stack/calls/pdf_stepback.py +210 -0
- cat_stack/calls/stepback.py +180 -0
- cat_stack/calls/top_n.py +217 -0
- cat_stack/classify.py +682 -0
- cat_stack/explore.py +111 -0
- cat_stack/extract.py +218 -0
- cat_stack/image_functions.py +2078 -0
- cat_stack/images/circle.png +0 -0
- cat_stack/images/cube.png +0 -0
- cat_stack/images/diamond.png +0 -0
- cat_stack/images/overlapping_pentagons.png +0 -0
- cat_stack/images/rectangles.png +0 -0
- cat_stack/model_reference_list.py +94 -0
- cat_stack/pdf_functions.py +2087 -0
- cat_stack/summarize.py +290 -0
- cat_stack/text_functions.py +1358 -0
- cat_stack/text_functions_ensemble.py +3644 -0
- cat_stack-0.1.0.dist-info/METADATA +150 -0
- cat_stack-0.1.0.dist-info/RECORD +38 -0
- cat_stack-0.1.0.dist-info/WHEEL +4 -0
- cat_stack-0.1.0.dist-info/licenses/LICENSE +672 -0
cat_stack/calls/CoVe.py
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
# openai chain of verification calls
|
|
2
|
+
|
|
3
|
+
def chain_of_verification_openai(
|
|
4
|
+
initial_reply,
|
|
5
|
+
step2_prompt,
|
|
6
|
+
step3_prompt,
|
|
7
|
+
step4_prompt,
|
|
8
|
+
client,
|
|
9
|
+
user_model,
|
|
10
|
+
creativity,
|
|
11
|
+
remove_numbering
|
|
12
|
+
):
|
|
13
|
+
"""
|
|
14
|
+
Execute Chain of Verification (CoVe) process.
|
|
15
|
+
Returns the verified reply or initial reply if error occurs.
|
|
16
|
+
"""
|
|
17
|
+
try:
|
|
18
|
+
# STEP 2: Generate verification questions
|
|
19
|
+
step2_filled = step2_prompt.replace('<<INITIAL_REPLY>>', initial_reply)
|
|
20
|
+
|
|
21
|
+
verification_response = client.chat.completions.create(
|
|
22
|
+
model=user_model,
|
|
23
|
+
messages=[{'role': 'user', 'content': step2_filled}],
|
|
24
|
+
**({"temperature": creativity} if creativity is not None else {})
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
verification_questions = verification_response.choices[0].message.content
|
|
28
|
+
|
|
29
|
+
# STEP 3: Answer verification questions
|
|
30
|
+
questions_list = [
|
|
31
|
+
remove_numbering(q)
|
|
32
|
+
for q in verification_questions.split('\n')
|
|
33
|
+
if q.strip()
|
|
34
|
+
]
|
|
35
|
+
verification_qa = []
|
|
36
|
+
|
|
37
|
+
# Prompting each question individually
|
|
38
|
+
for question in questions_list:
|
|
39
|
+
step3_filled = step3_prompt.replace('<<QUESTION>>', question)
|
|
40
|
+
|
|
41
|
+
answer_response = client.chat.completions.create(
|
|
42
|
+
model=user_model,
|
|
43
|
+
messages=[{'role': 'user', 'content': step3_filled}],
|
|
44
|
+
**({"temperature": creativity} if creativity is not None else {})
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
answer = answer_response.choices[0].message.content
|
|
48
|
+
verification_qa.append(f"Q: {question}\nA: {answer}")
|
|
49
|
+
|
|
50
|
+
# STEP 4: Final corrected categorization
|
|
51
|
+
verification_qa_text = "\n\n".join(verification_qa)
|
|
52
|
+
|
|
53
|
+
step4_filled = (step4_prompt
|
|
54
|
+
.replace('<<INITIAL_REPLY>>', initial_reply)
|
|
55
|
+
.replace('<<VERIFICATION_QA>>', verification_qa_text))
|
|
56
|
+
|
|
57
|
+
final_response = client.chat.completions.create(
|
|
58
|
+
model=user_model,
|
|
59
|
+
messages=[{'role': 'user', 'content': step4_filled}],
|
|
60
|
+
**({"temperature": creativity} if creativity is not None else {})
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
verified_reply = final_response.choices[0].message.content
|
|
64
|
+
|
|
65
|
+
return verified_reply
|
|
66
|
+
|
|
67
|
+
except Exception as e:
|
|
68
|
+
return initial_reply
|
|
69
|
+
|
|
70
|
+
# anthropic chain of verification calls
|
|
71
|
+
|
|
72
|
+
def chain_of_verification_anthropic(
|
|
73
|
+
initial_reply,
|
|
74
|
+
step2_prompt,
|
|
75
|
+
step3_prompt,
|
|
76
|
+
step4_prompt,
|
|
77
|
+
client,
|
|
78
|
+
user_model,
|
|
79
|
+
creativity,
|
|
80
|
+
remove_numbering
|
|
81
|
+
):
|
|
82
|
+
"""
|
|
83
|
+
Execute Chain of Verification (CoVe) process for Anthropic Claude.
|
|
84
|
+
Returns the verified reply or initial reply if error occurs.
|
|
85
|
+
"""
|
|
86
|
+
try:
|
|
87
|
+
# STEP 2: Generate verification questions
|
|
88
|
+
step2_filled = step2_prompt.replace('<<INITIAL_REPLY>>', initial_reply)
|
|
89
|
+
|
|
90
|
+
verification_response = client.messages.create(
|
|
91
|
+
model=user_model,
|
|
92
|
+
messages=[{'role': 'user', 'content': step2_filled}],
|
|
93
|
+
max_tokens=4096,
|
|
94
|
+
**({"temperature": creativity} if creativity is not None else {})
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
verification_questions = verification_response.content[0].text
|
|
98
|
+
|
|
99
|
+
# STEP 3: Answer verification questions
|
|
100
|
+
questions_list = [
|
|
101
|
+
remove_numbering(q)
|
|
102
|
+
for q in verification_questions.split('\n')
|
|
103
|
+
if q.strip()
|
|
104
|
+
]
|
|
105
|
+
verification_qa = []
|
|
106
|
+
|
|
107
|
+
# Prompting each question individually
|
|
108
|
+
for question in questions_list:
|
|
109
|
+
step3_filled = step3_prompt.replace('<<QUESTION>>', question)
|
|
110
|
+
|
|
111
|
+
answer_response = client.messages.create(
|
|
112
|
+
model=user_model,
|
|
113
|
+
messages=[{'role': 'user', 'content': step3_filled}],
|
|
114
|
+
max_tokens=4096,
|
|
115
|
+
**({"temperature": creativity} if creativity is not None else {})
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
answer = answer_response.content[0].text
|
|
119
|
+
verification_qa.append(f"Q: {question}\nA: {answer}")
|
|
120
|
+
|
|
121
|
+
# STEP 4: Final corrected categorization
|
|
122
|
+
verification_qa_text = "\n\n".join(verification_qa)
|
|
123
|
+
|
|
124
|
+
step4_filled = (step4_prompt
|
|
125
|
+
.replace('<<INITIAL_REPLY>>', initial_reply)
|
|
126
|
+
.replace('<<VERIFICATION_QA>>', verification_qa_text))
|
|
127
|
+
|
|
128
|
+
final_response = client.messages.create(
|
|
129
|
+
model=user_model,
|
|
130
|
+
messages=[{'role': 'user', 'content': step4_filled}],
|
|
131
|
+
max_tokens=4096,
|
|
132
|
+
**({"temperature": creativity} if creativity is not None else {})
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
verified_reply = final_response.content[0].text
|
|
136
|
+
|
|
137
|
+
return verified_reply
|
|
138
|
+
|
|
139
|
+
except Exception as e:
|
|
140
|
+
return initial_reply
|
|
141
|
+
|
|
142
|
+
# google chain of verification calls
|
|
143
|
+
def chain_of_verification_google(
|
|
144
|
+
initial_reply,
|
|
145
|
+
prompt,
|
|
146
|
+
step2_prompt,
|
|
147
|
+
step3_prompt,
|
|
148
|
+
step4_prompt,
|
|
149
|
+
url,
|
|
150
|
+
headers,
|
|
151
|
+
creativity,
|
|
152
|
+
remove_numbering,
|
|
153
|
+
make_google_request
|
|
154
|
+
):
|
|
155
|
+
import time
|
|
156
|
+
"""
|
|
157
|
+
Execute Chain of Verification (CoVe) process for Google Gemini.
|
|
158
|
+
Returns the verified reply or initial reply if error occurs.
|
|
159
|
+
"""
|
|
160
|
+
try:
|
|
161
|
+
# STEP 2: Generate verification questions
|
|
162
|
+
step2_filled = step2_prompt.replace('<<INITIAL_REPLY>>', initial_reply)
|
|
163
|
+
|
|
164
|
+
payload_step2 = {
|
|
165
|
+
"contents": [{
|
|
166
|
+
"parts": [{"text": step2_filled}]
|
|
167
|
+
}],
|
|
168
|
+
**({"generationConfig": {"temperature": creativity}} if creativity is not None else {})
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
result_step2 = make_google_request(url, headers, payload_step2)
|
|
172
|
+
verification_questions = result_step2["candidates"][0]["content"]["parts"][0]["text"]
|
|
173
|
+
|
|
174
|
+
# STEP 3: Answer verification questions
|
|
175
|
+
questions_list = [
|
|
176
|
+
remove_numbering(q)
|
|
177
|
+
for q in verification_questions.split('\n')
|
|
178
|
+
if q.strip()
|
|
179
|
+
]
|
|
180
|
+
verification_qa = []
|
|
181
|
+
|
|
182
|
+
for question in questions_list:
|
|
183
|
+
time.sleep(2) # temporary rate limit handling
|
|
184
|
+
step3_filled = step3_prompt.replace('<<QUESTION>>', question)
|
|
185
|
+
|
|
186
|
+
payload_step3 = {
|
|
187
|
+
"contents": [{
|
|
188
|
+
"parts": [{"text": step3_filled}]
|
|
189
|
+
}],
|
|
190
|
+
**({"generationConfig": {"temperature": creativity}} if creativity is not None else {})
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
result_step3 = make_google_request(url, headers, payload_step3)
|
|
194
|
+
answer = result_step3["candidates"][0]["content"]["parts"][0]["text"]
|
|
195
|
+
verification_qa.append(f"Q: {question}\nA: {answer}")
|
|
196
|
+
|
|
197
|
+
# STEP 4: Final corrected categorization
|
|
198
|
+
verification_qa_text = "\n\n".join(verification_qa)
|
|
199
|
+
|
|
200
|
+
step4_filled = (step4_prompt
|
|
201
|
+
.replace('<<PROMPT>>', prompt)
|
|
202
|
+
.replace('<<INITIAL_REPLY>>', initial_reply)
|
|
203
|
+
.replace('<<VERIFICATION_QA>>', verification_qa_text))
|
|
204
|
+
|
|
205
|
+
payload_step4 = {
|
|
206
|
+
"contents": [{
|
|
207
|
+
"parts": [{"text": step4_filled}]
|
|
208
|
+
}],
|
|
209
|
+
**({"generationConfig": {"temperature": creativity}} if creativity is not None else {})
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
result_step4 = make_google_request(url, headers, payload_step4)
|
|
213
|
+
verified_reply = result_step4["candidates"][0]["content"]["parts"][0]["text"]
|
|
214
|
+
|
|
215
|
+
return verified_reply
|
|
216
|
+
|
|
217
|
+
except Exception as e:
|
|
218
|
+
return initial_reply
|
|
219
|
+
|
|
220
|
+
# mistral chain of verification calls
|
|
221
|
+
|
|
222
|
+
def chain_of_verification_mistral(
|
|
223
|
+
initial_reply,
|
|
224
|
+
step2_prompt,
|
|
225
|
+
step3_prompt,
|
|
226
|
+
step4_prompt,
|
|
227
|
+
client,
|
|
228
|
+
user_model,
|
|
229
|
+
creativity,
|
|
230
|
+
remove_numbering
|
|
231
|
+
):
|
|
232
|
+
"""
|
|
233
|
+
Execute Chain of Verification (CoVe) process for Mistral AI.
|
|
234
|
+
Returns the verified reply or initial reply if error occurs.
|
|
235
|
+
"""
|
|
236
|
+
try:
|
|
237
|
+
# STEP 2: Generate verification questions
|
|
238
|
+
step2_filled = step2_prompt.replace('<<INITIAL_REPLY>>', initial_reply)
|
|
239
|
+
|
|
240
|
+
verification_response = client.chat.complete(
|
|
241
|
+
model=user_model,
|
|
242
|
+
messages=[{'role': 'user', 'content': step2_filled}],
|
|
243
|
+
**({"temperature": creativity} if creativity is not None else {})
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
verification_questions = verification_response.choices[0].message.content
|
|
247
|
+
|
|
248
|
+
# STEP 3: Answer verification questions
|
|
249
|
+
questions_list = [
|
|
250
|
+
remove_numbering(q)
|
|
251
|
+
for q in verification_questions.split('\n')
|
|
252
|
+
if q.strip()
|
|
253
|
+
]
|
|
254
|
+
verification_qa = []
|
|
255
|
+
|
|
256
|
+
# Prompting each question individually
|
|
257
|
+
for question in questions_list:
|
|
258
|
+
step3_filled = step3_prompt.replace('<<QUESTION>>', question)
|
|
259
|
+
|
|
260
|
+
answer_response = client.chat.complete(
|
|
261
|
+
model=user_model,
|
|
262
|
+
messages=[{'role': 'user', 'content': step3_filled}],
|
|
263
|
+
**({"temperature": creativity} if creativity is not None else {})
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
answer = answer_response.choices[0].message.content
|
|
267
|
+
verification_qa.append(f"Q: {question}\nA: {answer}")
|
|
268
|
+
|
|
269
|
+
# STEP 4: Final corrected categorization
|
|
270
|
+
verification_qa_text = "\n\n".join(verification_qa)
|
|
271
|
+
|
|
272
|
+
step4_filled = (step4_prompt
|
|
273
|
+
.replace('<<INITIAL_REPLY>>', initial_reply)
|
|
274
|
+
.replace('<<VERIFICATION_QA>>', verification_qa_text))
|
|
275
|
+
|
|
276
|
+
final_response = client.chat.complete(
|
|
277
|
+
model=user_model,
|
|
278
|
+
messages=[{'role': 'user', 'content': step4_filled}],
|
|
279
|
+
**({"temperature": creativity} if creativity is not None else {})
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
verified_reply = final_response.choices[0].message.content
|
|
283
|
+
|
|
284
|
+
return verified_reply
|
|
285
|
+
|
|
286
|
+
except Exception as e:
|
|
287
|
+
return initial_reply
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2025-present Christopher Soria <chrissoria@berkeley.edu>
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
4
|
+
|
|
5
|
+
from .all_calls import (
|
|
6
|
+
get_stepback_insight_openai,
|
|
7
|
+
get_stepback_insight_anthropic,
|
|
8
|
+
get_stepback_insight_google,
|
|
9
|
+
get_stepback_insight_mistral,
|
|
10
|
+
chain_of_verification_openai,
|
|
11
|
+
chain_of_verification_google,
|
|
12
|
+
chain_of_verification_anthropic,
|
|
13
|
+
chain_of_verification_mistral
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
'get_stepback_insight_openai',
|
|
18
|
+
'get_stepback_insight_anthropic',
|
|
19
|
+
'get_stepback_insight_google',
|
|
20
|
+
'get_stepback_insight_mistral',
|
|
21
|
+
'chain_of_verification_openai',
|
|
22
|
+
'chain_of_verification_anthropic',
|
|
23
|
+
'chain_of_verification_google',
|
|
24
|
+
'chain_of_verification_mistral',
|
|
25
|
+
]
|