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.
@@ -0,0 +1,180 @@
1
+ # Stepback prompting functions for various LLM providers
2
+
3
+ import requests
4
+
5
+
6
+ def get_stepback_insight_openai(
7
+ stepback,
8
+ api_key,
9
+ user_model,
10
+ model_source="openai",
11
+ creativity=None
12
+ ):
13
+ """
14
+ Get stepback insight from OpenAI-compatible APIs.
15
+ Supports OpenAI, Perplexity, Huggingface, and xAI.
16
+
17
+ Uses direct HTTP requests instead of OpenAI SDK for lighter dependencies.
18
+ """
19
+ # Determine the base URL based on model source
20
+ if model_source == "huggingface":
21
+ from cat_stack._providers import _detect_huggingface_endpoint
22
+ base_url = _detect_huggingface_endpoint(api_key, user_model)
23
+ elif model_source == "huggingface-together":
24
+ base_url = "https://router.huggingface.co/together/v1"
25
+ elif model_source == "perplexity":
26
+ base_url = "https://api.perplexity.ai"
27
+ elif model_source == "xai":
28
+ base_url = "https://api.x.ai/v1"
29
+ else:
30
+ base_url = "https://api.openai.com/v1"
31
+
32
+ endpoint = f"{base_url}/chat/completions"
33
+
34
+ headers = {
35
+ "Content-Type": "application/json",
36
+ "Authorization": f"Bearer {api_key}"
37
+ }
38
+
39
+ payload = {
40
+ "model": user_model,
41
+ "messages": [{"role": "user", "content": stepback}],
42
+ }
43
+
44
+ if creativity is not None:
45
+ payload["temperature"] = creativity
46
+
47
+ try:
48
+ response = requests.post(endpoint, headers=headers, json=payload, timeout=120)
49
+ response.raise_for_status()
50
+ result = response.json()
51
+ stepback_insight = result["choices"][0]["message"]["content"]
52
+
53
+ return stepback_insight, True
54
+
55
+ except Exception as e:
56
+ return None, False
57
+
58
+
59
+ def get_stepback_insight_anthropic(
60
+ stepback,
61
+ api_key,
62
+ user_model,
63
+ model_source="anthropic",
64
+ creativity=None
65
+ ):
66
+ """
67
+ Get stepback insight from Anthropic Claude.
68
+
69
+ Uses direct HTTP requests instead of Anthropic SDK for lighter dependencies.
70
+ """
71
+ import requests
72
+
73
+ endpoint = "https://api.anthropic.com/v1/messages"
74
+
75
+ headers = {
76
+ "Content-Type": "application/json",
77
+ "x-api-key": api_key,
78
+ "anthropic-version": "2023-06-01"
79
+ }
80
+
81
+ payload = {
82
+ "model": user_model,
83
+ "max_tokens": 4096,
84
+ "messages": [{"role": "user", "content": stepback}],
85
+ }
86
+
87
+ if creativity is not None:
88
+ payload["temperature"] = creativity
89
+
90
+ try:
91
+ response = requests.post(endpoint, headers=headers, json=payload, timeout=120)
92
+ response.raise_for_status()
93
+ result = response.json()
94
+
95
+ # Parse response - Anthropic returns content as a list
96
+ content = result.get("content", [])
97
+ if content and content[0].get("type") == "text":
98
+ stepback_insight = content[0].get("text", "")
99
+ return stepback_insight, True
100
+
101
+ return None, False
102
+
103
+ except Exception as e:
104
+ return None, False
105
+
106
+
107
+ def get_stepback_insight_google(
108
+ stepback,
109
+ api_key,
110
+ user_model,
111
+ model_source="google",
112
+ creativity=None
113
+ ):
114
+ """
115
+ Get stepback insight from Google Gemini.
116
+ """
117
+ import requests
118
+
119
+ url = f"https://generativelanguage.googleapis.com/v1beta/models/{user_model}:generateContent?key={api_key}"
120
+
121
+ headers = {
122
+ "Content-Type": "application/json"
123
+ }
124
+
125
+ payload = {
126
+ "contents": [{
127
+ "parts": [{"text": stepback}],
128
+
129
+ **({"generationConfig": {"temperature": creativity}} if creativity is not None else {})
130
+ }]
131
+ }
132
+
133
+ try:
134
+ response = requests.post(url, headers=headers, json=payload)
135
+ response.raise_for_status() # Raise error for bad status codes
136
+
137
+ result = response.json()
138
+ stepback_insight = result['candidates'][0]['content']['parts'][0]['text']
139
+
140
+ return stepback_insight, True
141
+
142
+ except Exception as e:
143
+ return None, False
144
+
145
+
146
+ def get_stepback_insight_mistral(
147
+ stepback,
148
+ api_key,
149
+ user_model,
150
+ model_source="mistral",
151
+ creativity=None
152
+ ):
153
+ """
154
+ Get stepback insight from Mistral AI.
155
+ """
156
+ import requests
157
+
158
+ endpoint = "https://api.mistral.ai/v1/chat/completions"
159
+ headers = {
160
+ "Content-Type": "application/json",
161
+ "Authorization": f"Bearer {api_key}"
162
+ }
163
+
164
+ payload = {
165
+ "model": user_model,
166
+ "messages": [{'role': 'user', 'content': stepback}],
167
+ }
168
+ if creativity is not None:
169
+ payload["temperature"] = creativity
170
+
171
+ try:
172
+ response = requests.post(endpoint, headers=headers, json=payload, timeout=120)
173
+ response.raise_for_status()
174
+ result = response.json()
175
+ stepback_insight = result["choices"][0]["message"]["content"]
176
+
177
+ return stepback_insight, True
178
+
179
+ except Exception as e:
180
+ return None, False
@@ -0,0 +1,217 @@
1
+ # Top N category extraction functions for various LLM providers
2
+
3
+ import requests
4
+
5
+
6
+ def get_openai_top_n(
7
+ prompt,
8
+ user_model,
9
+ specificity,
10
+ model_source,
11
+ api_key,
12
+ research_question,
13
+ creativity
14
+ ):
15
+ """
16
+ Get response from OpenAI API with system message.
17
+ Supports OpenAI, Perplexity, Huggingface, and xAI.
18
+
19
+ Uses direct HTTP requests instead of OpenAI SDK for lighter dependencies.
20
+ """
21
+ # Determine the base URL based on model source
22
+ if model_source == "huggingface":
23
+ from cat_stack._providers import _detect_huggingface_endpoint
24
+ base_url = _detect_huggingface_endpoint(api_key, user_model)
25
+ elif model_source == "huggingface-together":
26
+ base_url = "https://router.huggingface.co/together/v1"
27
+ elif model_source == "perplexity":
28
+ base_url = "https://api.perplexity.ai"
29
+ elif model_source == "xai":
30
+ base_url = "https://api.x.ai/v1"
31
+ else:
32
+ base_url = "https://api.openai.com/v1"
33
+
34
+ endpoint = f"{base_url}/chat/completions"
35
+
36
+ headers = {
37
+ "Content-Type": "application/json",
38
+ "Authorization": f"Bearer {api_key}"
39
+ }
40
+
41
+ # Build system message
42
+ if research_question:
43
+ system_content = (
44
+ f"You are a helpful assistant that extracts categories from text responses. "
45
+ f"The specific task is to identify {specificity} categories of responses to a text prompt. "
46
+ f"The research question is: {research_question}"
47
+ )
48
+ else:
49
+ system_content = "You are a helpful assistant."
50
+
51
+ payload = {
52
+ "model": user_model,
53
+ "messages": [
54
+ {"role": "system", "content": system_content},
55
+ {"role": "user", "content": prompt}
56
+ ],
57
+ }
58
+
59
+ if creativity is not None:
60
+ payload["temperature"] = creativity
61
+
62
+ response = requests.post(endpoint, headers=headers, json=payload, timeout=120)
63
+ response.raise_for_status()
64
+ result = response.json()
65
+
66
+ return result["choices"][0]["message"]["content"]
67
+
68
+
69
+ def get_anthropic_top_n(
70
+ prompt,
71
+ user_model,
72
+ model_source,
73
+ specificity,
74
+ api_key,
75
+ research_question,
76
+ creativity
77
+ ):
78
+ """
79
+ Get response from Anthropic API with system prompt.
80
+
81
+ Uses direct HTTP requests instead of Anthropic SDK for lighter dependencies.
82
+ """
83
+ import requests
84
+
85
+ endpoint = "https://api.anthropic.com/v1/messages"
86
+
87
+ headers = {
88
+ "Content-Type": "application/json",
89
+ "x-api-key": api_key,
90
+ "anthropic-version": "2023-06-01"
91
+ }
92
+
93
+ # Build system prompt
94
+ if research_question:
95
+ system_content = (f"You are a helpful assistant that extracts categories from text responses. "
96
+ f"The specific task is to identify {specificity} categories of responses to a text prompt. "
97
+ f"The research question is: {research_question}")
98
+ else:
99
+ system_content = "You are a helpful assistant."
100
+
101
+ payload = {
102
+ "model": user_model,
103
+ "max_tokens": 4096,
104
+ "system": system_content,
105
+ "messages": [{"role": "user", "content": prompt}],
106
+ }
107
+
108
+ if creativity is not None:
109
+ payload["temperature"] = creativity
110
+
111
+ response = requests.post(endpoint, headers=headers, json=payload, timeout=120)
112
+ response.raise_for_status()
113
+ result = response.json()
114
+
115
+ # Parse response - Anthropic returns content as a list
116
+ content = result.get("content", [])
117
+ if content and content[0].get("type") == "text":
118
+ return content[0].get("text", "")
119
+
120
+ return ""
121
+
122
+
123
+ def get_google_top_n(
124
+ prompt,
125
+ user_model,
126
+ specificity,
127
+ model_source,
128
+ api_key,
129
+ research_question,
130
+ creativity
131
+ ):
132
+ """
133
+ Get response from Google Gemini API.
134
+ """
135
+ import requests
136
+
137
+ url = f"https://generativelanguage.googleapis.com/v1beta/models/{user_model}:generateContent"
138
+
139
+ headers = {
140
+ "x-goog-api-key": api_key,
141
+ "Content-Type": "application/json"
142
+ }
143
+
144
+ # Build system-like content in the prompt
145
+ if research_question:
146
+ system_context = (f"You are a helpful assistant that extracts categories from text responses. "
147
+ f"The specific task is to identify {specificity} categories of responses to a text prompt. "
148
+ f"The research question is: {research_question}\n\n")
149
+ else:
150
+ system_context = "You are a helpful assistant.\n\n"
151
+
152
+ full_prompt = system_context + prompt
153
+
154
+ payload = {
155
+ "contents": [{
156
+ "parts": [{"text": full_prompt}]
157
+ }],
158
+ "generationConfig": {
159
+ **({"temperature": creativity} if creativity is not None else {})
160
+ }
161
+ }
162
+
163
+ response = requests.post(url, headers=headers, json=payload)
164
+ response.raise_for_status()
165
+
166
+ result = response.json()
167
+
168
+ if "candidates" in result and result["candidates"]:
169
+ return result["candidates"][0]["content"]["parts"][0]["text"]
170
+ else:
171
+ return "No response generated"
172
+
173
+
174
+ def get_mistral_top_n(
175
+ prompt,
176
+ user_model,
177
+ specificity,
178
+ model_source,
179
+ api_key,
180
+ research_question,
181
+ creativity
182
+ ):
183
+ """
184
+ Get response from Mistral AI API.
185
+ """
186
+ import requests
187
+
188
+ endpoint = "https://api.mistral.ai/v1/chat/completions"
189
+ headers = {
190
+ "Content-Type": "application/json",
191
+ "Authorization": f"Bearer {api_key}"
192
+ }
193
+
194
+ # Build system prompt
195
+ if research_question:
196
+ system_content = (f"You are a helpful assistant that extracts categories from text responses. "
197
+ f"The specific task is to identify {specificity} categories of responses to a text prompt. "
198
+ f"The research question is: {research_question}")
199
+ else:
200
+ system_content = "You are a helpful assistant."
201
+
202
+ payload = {
203
+ "model": user_model,
204
+ "messages": [
205
+ {'role': 'system', 'content': system_content},
206
+ {'role': 'user', 'content': prompt}
207
+ ],
208
+ }
209
+ if creativity is not None:
210
+ payload["temperature"] = creativity
211
+
212
+ response = requests.post(endpoint, headers=headers, json=payload, timeout=120)
213
+ response.raise_for_status()
214
+ result = response.json()
215
+
216
+ return result["choices"][0]["message"]["content"]
217
+