stratifyai 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.
- cli/__init__.py +5 -0
- cli/stratifyai_cli.py +1753 -0
- stratifyai/__init__.py +113 -0
- stratifyai/api_key_helper.py +372 -0
- stratifyai/caching.py +279 -0
- stratifyai/chat/__init__.py +54 -0
- stratifyai/chat/builder.py +366 -0
- stratifyai/chat/stratifyai_anthropic.py +194 -0
- stratifyai/chat/stratifyai_bedrock.py +200 -0
- stratifyai/chat/stratifyai_deepseek.py +194 -0
- stratifyai/chat/stratifyai_google.py +194 -0
- stratifyai/chat/stratifyai_grok.py +194 -0
- stratifyai/chat/stratifyai_groq.py +195 -0
- stratifyai/chat/stratifyai_ollama.py +201 -0
- stratifyai/chat/stratifyai_openai.py +209 -0
- stratifyai/chat/stratifyai_openrouter.py +201 -0
- stratifyai/chunking.py +158 -0
- stratifyai/client.py +292 -0
- stratifyai/config.py +1273 -0
- stratifyai/cost_tracker.py +257 -0
- stratifyai/embeddings.py +245 -0
- stratifyai/exceptions.py +91 -0
- stratifyai/models.py +59 -0
- stratifyai/providers/__init__.py +5 -0
- stratifyai/providers/anthropic.py +330 -0
- stratifyai/providers/base.py +183 -0
- stratifyai/providers/bedrock.py +634 -0
- stratifyai/providers/deepseek.py +39 -0
- stratifyai/providers/google.py +39 -0
- stratifyai/providers/grok.py +39 -0
- stratifyai/providers/groq.py +39 -0
- stratifyai/providers/ollama.py +43 -0
- stratifyai/providers/openai.py +344 -0
- stratifyai/providers/openai_compatible.py +372 -0
- stratifyai/providers/openrouter.py +39 -0
- stratifyai/py.typed +2 -0
- stratifyai/rag.py +381 -0
- stratifyai/retry.py +185 -0
- stratifyai/router.py +643 -0
- stratifyai/summarization.py +179 -0
- stratifyai/utils/__init__.py +11 -0
- stratifyai/utils/bedrock_validator.py +136 -0
- stratifyai/utils/code_extractor.py +327 -0
- stratifyai/utils/csv_extractor.py +197 -0
- stratifyai/utils/file_analyzer.py +192 -0
- stratifyai/utils/json_extractor.py +219 -0
- stratifyai/utils/log_extractor.py +267 -0
- stratifyai/utils/model_selector.py +324 -0
- stratifyai/utils/provider_validator.py +442 -0
- stratifyai/utils/token_counter.py +186 -0
- stratifyai/vectordb.py +344 -0
- stratifyai-0.1.0.dist-info/METADATA +263 -0
- stratifyai-0.1.0.dist-info/RECORD +57 -0
- stratifyai-0.1.0.dist-info/WHEEL +5 -0
- stratifyai-0.1.0.dist-info/entry_points.txt +2 -0
- stratifyai-0.1.0.dist-info/licenses/LICENSE +21 -0
- stratifyai-0.1.0.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"""Anthropic chat interface for StratifyAI.
|
|
2
|
+
|
|
3
|
+
Provides convenient functions for Anthropic Claude chat completions.
|
|
4
|
+
Model must be specified for each request.
|
|
5
|
+
|
|
6
|
+
Environment Variable: ANTHROPIC_API_KEY
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
# Model is always required
|
|
10
|
+
from stratifyai.chat import anthropic
|
|
11
|
+
response = await anthropic.chat("Hello!", model="claude-sonnet-4-5")
|
|
12
|
+
|
|
13
|
+
# Builder pattern (model required)
|
|
14
|
+
client = (
|
|
15
|
+
anthropic
|
|
16
|
+
.with_model("claude-opus-4-5")
|
|
17
|
+
.with_system("You are a helpful assistant")
|
|
18
|
+
.with_developer("Use markdown")
|
|
19
|
+
)
|
|
20
|
+
response = await client.chat("Hello!")
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
import asyncio
|
|
24
|
+
from typing import AsyncIterator, Optional, Union
|
|
25
|
+
|
|
26
|
+
from stratifyai import LLMClient
|
|
27
|
+
from stratifyai.models import ChatResponse, Message
|
|
28
|
+
from stratifyai.chat.builder import ChatBuilder, create_module_builder
|
|
29
|
+
|
|
30
|
+
# Default configuration (no default model - must be specified)
|
|
31
|
+
DEFAULT_TEMPERATURE = 0.7
|
|
32
|
+
DEFAULT_MAX_TOKENS = None
|
|
33
|
+
|
|
34
|
+
# Module-level client (lazy initialization)
|
|
35
|
+
_client: Optional[LLMClient] = None
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _get_client() -> LLMClient:
|
|
39
|
+
"""Get or create the module-level client."""
|
|
40
|
+
global _client
|
|
41
|
+
if _client is None:
|
|
42
|
+
_client = LLMClient(provider="anthropic")
|
|
43
|
+
return _client
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
# Module-level builder for chaining
|
|
47
|
+
_builder = create_module_builder(
|
|
48
|
+
provider="anthropic",
|
|
49
|
+
default_temperature=DEFAULT_TEMPERATURE,
|
|
50
|
+
default_max_tokens=DEFAULT_MAX_TOKENS,
|
|
51
|
+
client_factory=_get_client,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
# Builder pattern methods (delegate to _builder)
|
|
56
|
+
def with_model(model: str) -> ChatBuilder:
|
|
57
|
+
"""Set the model to use. Returns a new ChatBuilder for chaining."""
|
|
58
|
+
return _builder.with_model(model)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def with_system(prompt: str) -> ChatBuilder:
|
|
62
|
+
"""Set the system prompt. Returns a new ChatBuilder for chaining."""
|
|
63
|
+
return _builder.with_system(prompt)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def with_developer(instructions: str) -> ChatBuilder:
|
|
67
|
+
"""Set developer instructions. Returns a new ChatBuilder for chaining."""
|
|
68
|
+
return _builder.with_developer(instructions)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def with_temperature(temperature: float) -> ChatBuilder:
|
|
72
|
+
"""Set the temperature. Returns a new ChatBuilder for chaining."""
|
|
73
|
+
return _builder.with_temperature(temperature)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def with_max_tokens(max_tokens: int) -> ChatBuilder:
|
|
77
|
+
"""Set max tokens. Returns a new ChatBuilder for chaining."""
|
|
78
|
+
return _builder.with_max_tokens(max_tokens)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def with_options(**kwargs) -> ChatBuilder:
|
|
82
|
+
"""Set additional options. Returns a new ChatBuilder for chaining."""
|
|
83
|
+
return _builder.with_options(**kwargs)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
async def chat(
|
|
87
|
+
prompt: Union[str, list[Message]],
|
|
88
|
+
*,
|
|
89
|
+
model: str,
|
|
90
|
+
system: Optional[str] = None,
|
|
91
|
+
temperature: float = DEFAULT_TEMPERATURE,
|
|
92
|
+
max_tokens: Optional[int] = DEFAULT_MAX_TOKENS,
|
|
93
|
+
stream: bool = False,
|
|
94
|
+
**kwargs,
|
|
95
|
+
) -> Union[ChatResponse, AsyncIterator[ChatResponse]]:
|
|
96
|
+
"""
|
|
97
|
+
Send an async chat completion request to Anthropic Claude.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
prompt: User message string or list of Message objects.
|
|
101
|
+
model: Model name (required). E.g., "claude-sonnet-4-5", "claude-opus-4-5"
|
|
102
|
+
system: Optional system prompt (ignored if prompt is list of Messages).
|
|
103
|
+
temperature: Sampling temperature (0.0-1.0). Default: 0.7
|
|
104
|
+
max_tokens: Maximum tokens to generate. Default: None (model default)
|
|
105
|
+
stream: Whether to stream the response. Default: False
|
|
106
|
+
**kwargs: Additional parameters passed to the API.
|
|
107
|
+
|
|
108
|
+
Returns:
|
|
109
|
+
ChatResponse object, or AsyncIterator[ChatResponse] if streaming.
|
|
110
|
+
|
|
111
|
+
Example:
|
|
112
|
+
>>> from stratifyai.chat import anthropic
|
|
113
|
+
>>> response = await anthropic.chat("What is Python?", model="claude-sonnet-4-5")
|
|
114
|
+
>>> print(response.content)
|
|
115
|
+
"""
|
|
116
|
+
client = _get_client()
|
|
117
|
+
|
|
118
|
+
# Build messages list
|
|
119
|
+
if isinstance(prompt, str):
|
|
120
|
+
messages = []
|
|
121
|
+
if system:
|
|
122
|
+
messages.append(Message(role="system", content=system))
|
|
123
|
+
messages.append(Message(role="user", content=prompt))
|
|
124
|
+
else:
|
|
125
|
+
messages = prompt
|
|
126
|
+
|
|
127
|
+
return await client.chat(
|
|
128
|
+
model=model,
|
|
129
|
+
messages=messages,
|
|
130
|
+
temperature=temperature,
|
|
131
|
+
max_tokens=max_tokens,
|
|
132
|
+
stream=stream,
|
|
133
|
+
**kwargs,
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
async def chat_stream(
|
|
138
|
+
prompt: Union[str, list[Message]],
|
|
139
|
+
*,
|
|
140
|
+
model: str,
|
|
141
|
+
system: Optional[str] = None,
|
|
142
|
+
temperature: float = DEFAULT_TEMPERATURE,
|
|
143
|
+
max_tokens: Optional[int] = DEFAULT_MAX_TOKENS,
|
|
144
|
+
**kwargs,
|
|
145
|
+
) -> AsyncIterator[ChatResponse]:
|
|
146
|
+
"""
|
|
147
|
+
Send an async streaming chat completion request to Anthropic Claude.
|
|
148
|
+
|
|
149
|
+
Args:
|
|
150
|
+
prompt: User message string or list of Message objects.
|
|
151
|
+
model: Model name (required). E.g., "claude-sonnet-4-5"
|
|
152
|
+
system: Optional system prompt (ignored if prompt is list of Messages).
|
|
153
|
+
temperature: Sampling temperature (0.0-1.0). Default: 0.7
|
|
154
|
+
max_tokens: Maximum tokens to generate. Default: None (model default)
|
|
155
|
+
**kwargs: Additional parameters passed to the API.
|
|
156
|
+
|
|
157
|
+
Yields:
|
|
158
|
+
ChatResponse chunks.
|
|
159
|
+
|
|
160
|
+
Example:
|
|
161
|
+
>>> from stratifyai.chat import anthropic
|
|
162
|
+
>>> async for chunk in anthropic.chat_stream("Tell me a story", model="claude-sonnet-4-5"):
|
|
163
|
+
... print(chunk.content, end="", flush=True)
|
|
164
|
+
"""
|
|
165
|
+
return await chat(
|
|
166
|
+
prompt,
|
|
167
|
+
model=model,
|
|
168
|
+
system=system,
|
|
169
|
+
temperature=temperature,
|
|
170
|
+
max_tokens=max_tokens,
|
|
171
|
+
stream=True,
|
|
172
|
+
**kwargs,
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def chat_sync(
|
|
177
|
+
prompt: Union[str, list[Message]],
|
|
178
|
+
*,
|
|
179
|
+
model: str,
|
|
180
|
+
system: Optional[str] = None,
|
|
181
|
+
temperature: float = DEFAULT_TEMPERATURE,
|
|
182
|
+
max_tokens: Optional[int] = DEFAULT_MAX_TOKENS,
|
|
183
|
+
**kwargs,
|
|
184
|
+
) -> ChatResponse:
|
|
185
|
+
"""Synchronous wrapper for chat(). Model is required."""
|
|
186
|
+
return asyncio.run(chat(
|
|
187
|
+
prompt,
|
|
188
|
+
model=model,
|
|
189
|
+
system=system,
|
|
190
|
+
temperature=temperature,
|
|
191
|
+
max_tokens=max_tokens,
|
|
192
|
+
stream=False,
|
|
193
|
+
**kwargs,
|
|
194
|
+
))
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
"""AWS Bedrock chat interface for StratifyAI.
|
|
2
|
+
|
|
3
|
+
Provides convenient functions for AWS Bedrock chat completions.
|
|
4
|
+
Model must be specified for each request.
|
|
5
|
+
|
|
6
|
+
Requires: AWS credentials (env vars, ~/.aws/credentials, or IAM role)
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
# Model is always required
|
|
10
|
+
from stratifyai.chat import bedrock
|
|
11
|
+
response = await bedrock.chat("Hello!", model="anthropic.claude-3-5-sonnet-20241022-v2:0")
|
|
12
|
+
|
|
13
|
+
# Builder pattern (model required)
|
|
14
|
+
client = (
|
|
15
|
+
bedrock
|
|
16
|
+
.with_model("meta.llama3-3-70b-instruct-v1:0")
|
|
17
|
+
.with_system("You are a helpful assistant")
|
|
18
|
+
.with_developer("Use markdown")
|
|
19
|
+
)
|
|
20
|
+
response = await client.chat("Hello!")
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
import asyncio
|
|
24
|
+
from typing import AsyncIterator, Optional, Union
|
|
25
|
+
|
|
26
|
+
from stratifyai import LLMClient
|
|
27
|
+
from stratifyai.models import ChatResponse, Message
|
|
28
|
+
from stratifyai.chat.builder import ChatBuilder, create_module_builder
|
|
29
|
+
|
|
30
|
+
# Default configuration (no default model - must be specified)
|
|
31
|
+
DEFAULT_TEMPERATURE = 0.7
|
|
32
|
+
DEFAULT_MAX_TOKENS = None
|
|
33
|
+
|
|
34
|
+
# Module-level client (lazy initialization)
|
|
35
|
+
_client: Optional[LLMClient] = None
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _get_client() -> LLMClient:
|
|
39
|
+
"""Get or create the module-level client."""
|
|
40
|
+
global _client
|
|
41
|
+
if _client is None:
|
|
42
|
+
_client = LLMClient(provider="bedrock")
|
|
43
|
+
return _client
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
# Module-level builder for chaining
|
|
47
|
+
_builder = create_module_builder(
|
|
48
|
+
provider="bedrock",
|
|
49
|
+
default_temperature=DEFAULT_TEMPERATURE,
|
|
50
|
+
default_max_tokens=DEFAULT_MAX_TOKENS,
|
|
51
|
+
client_factory=_get_client,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
# Builder pattern methods (delegate to _builder)
|
|
56
|
+
def with_model(model: str) -> ChatBuilder:
|
|
57
|
+
"""Set the model to use. Returns a new ChatBuilder for chaining."""
|
|
58
|
+
return _builder.with_model(model)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def with_system(prompt: str) -> ChatBuilder:
|
|
62
|
+
"""Set the system prompt. Returns a new ChatBuilder for chaining."""
|
|
63
|
+
return _builder.with_system(prompt)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def with_developer(instructions: str) -> ChatBuilder:
|
|
67
|
+
"""Set developer instructions. Returns a new ChatBuilder for chaining."""
|
|
68
|
+
return _builder.with_developer(instructions)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def with_temperature(temperature: float) -> ChatBuilder:
|
|
72
|
+
"""Set the temperature. Returns a new ChatBuilder for chaining."""
|
|
73
|
+
return _builder.with_temperature(temperature)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def with_max_tokens(max_tokens: int) -> ChatBuilder:
|
|
77
|
+
"""Set max tokens. Returns a new ChatBuilder for chaining."""
|
|
78
|
+
return _builder.with_max_tokens(max_tokens)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def with_options(**kwargs) -> ChatBuilder:
|
|
82
|
+
"""Set additional options. Returns a new ChatBuilder for chaining."""
|
|
83
|
+
return _builder.with_options(**kwargs)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
async def chat(
|
|
87
|
+
prompt: Union[str, list[Message]],
|
|
88
|
+
*,
|
|
89
|
+
model: str,
|
|
90
|
+
system: Optional[str] = None,
|
|
91
|
+
temperature: float = DEFAULT_TEMPERATURE,
|
|
92
|
+
max_tokens: Optional[int] = DEFAULT_MAX_TOKENS,
|
|
93
|
+
stream: bool = False,
|
|
94
|
+
**kwargs,
|
|
95
|
+
) -> Union[ChatResponse, AsyncIterator[ChatResponse]]:
|
|
96
|
+
"""
|
|
97
|
+
Send a chat completion request to AWS Bedrock.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
prompt: User message string or list of Message objects.
|
|
101
|
+
model: Model name (required). E.g., "anthropic.claude-3-5-sonnet-20241022-v2:0"
|
|
102
|
+
system: Optional system prompt (ignored if prompt is list of Messages).
|
|
103
|
+
temperature: Sampling temperature (0.0-1.0). Default: 0.7
|
|
104
|
+
max_tokens: Maximum tokens to generate. Default: None (model default)
|
|
105
|
+
stream: Whether to stream the response. Default: False
|
|
106
|
+
**kwargs: Additional parameters passed to the API.
|
|
107
|
+
|
|
108
|
+
Returns:
|
|
109
|
+
ChatResponse object, or AsyncIterator[ChatResponse] if streaming.
|
|
110
|
+
|
|
111
|
+
Example:
|
|
112
|
+
>>> from stratifyai.chat import bedrock
|
|
113
|
+
>>> response = await bedrock.chat("What is Python?", model="anthropic.claude-3-5-sonnet-20241022-v2:0")
|
|
114
|
+
>>> print(response.content)
|
|
115
|
+
|
|
116
|
+
# Use a different model
|
|
117
|
+
>>> response = bedrock.chat(
|
|
118
|
+
... "Explain AI",
|
|
119
|
+
... model="meta.llama3-3-70b-instruct-v1:0"
|
|
120
|
+
... )
|
|
121
|
+
"""
|
|
122
|
+
client = _get_client()
|
|
123
|
+
|
|
124
|
+
# Build messages list
|
|
125
|
+
if isinstance(prompt, str):
|
|
126
|
+
messages = []
|
|
127
|
+
if system:
|
|
128
|
+
messages.append(Message(role="system", content=system))
|
|
129
|
+
messages.append(Message(role="user", content=prompt))
|
|
130
|
+
else:
|
|
131
|
+
messages = prompt
|
|
132
|
+
|
|
133
|
+
return await client.chat(
|
|
134
|
+
model=model,
|
|
135
|
+
messages=messages,
|
|
136
|
+
temperature=temperature,
|
|
137
|
+
max_tokens=max_tokens,
|
|
138
|
+
stream=stream,
|
|
139
|
+
**kwargs,
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
async def chat_stream(
|
|
144
|
+
prompt: Union[str, list[Message]],
|
|
145
|
+
*,
|
|
146
|
+
model: str,
|
|
147
|
+
system: Optional[str] = None,
|
|
148
|
+
temperature: float = DEFAULT_TEMPERATURE,
|
|
149
|
+
max_tokens: Optional[int] = DEFAULT_MAX_TOKENS,
|
|
150
|
+
**kwargs,
|
|
151
|
+
) -> AsyncIterator[ChatResponse]:
|
|
152
|
+
"""
|
|
153
|
+
Send a streaming chat completion request to AWS Bedrock.
|
|
154
|
+
|
|
155
|
+
Args:
|
|
156
|
+
prompt: User message string or list of Message objects.
|
|
157
|
+
model: Model name (required). E.g., "anthropic.claude-3-5-sonnet-20241022-v2:0"
|
|
158
|
+
system: Optional system prompt (ignored if prompt is list of Messages).
|
|
159
|
+
temperature: Sampling temperature (0.0-1.0). Default: 0.7
|
|
160
|
+
max_tokens: Maximum tokens to generate. Default: None (model default)
|
|
161
|
+
**kwargs: Additional parameters passed to the API.
|
|
162
|
+
|
|
163
|
+
Yields:
|
|
164
|
+
ChatResponse chunks.
|
|
165
|
+
|
|
166
|
+
Example:
|
|
167
|
+
>>> from stratifyai.chat import bedrock
|
|
168
|
+
>>> async for chunk in bedrock.chat_stream("Tell me a story", model="anthropic.claude-3-5-sonnet-20241022-v2:0"):
|
|
169
|
+
... print(chunk.content, end="", flush=True)
|
|
170
|
+
"""
|
|
171
|
+
return await chat(
|
|
172
|
+
prompt,
|
|
173
|
+
model=model,
|
|
174
|
+
system=system,
|
|
175
|
+
temperature=temperature,
|
|
176
|
+
max_tokens=max_tokens,
|
|
177
|
+
stream=True,
|
|
178
|
+
**kwargs,
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def chat_sync(
|
|
183
|
+
prompt,
|
|
184
|
+
*,
|
|
185
|
+
model: str,
|
|
186
|
+
system=None,
|
|
187
|
+
temperature=DEFAULT_TEMPERATURE,
|
|
188
|
+
max_tokens=DEFAULT_MAX_TOKENS,
|
|
189
|
+
**kwargs,
|
|
190
|
+
):
|
|
191
|
+
"""Synchronous wrapper for chat()."""
|
|
192
|
+
return asyncio.run(chat(
|
|
193
|
+
prompt,
|
|
194
|
+
model=model,
|
|
195
|
+
system=system,
|
|
196
|
+
temperature=temperature,
|
|
197
|
+
max_tokens=max_tokens,
|
|
198
|
+
stream=False,
|
|
199
|
+
**kwargs,
|
|
200
|
+
))
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"""DeepSeek chat interface for StratifyAI.
|
|
2
|
+
|
|
3
|
+
Provides convenient functions for DeepSeek chat completions.
|
|
4
|
+
Model must be specified for each request.
|
|
5
|
+
|
|
6
|
+
Environment Variable: DEEPSEEK_API_KEY
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
# Model is always required
|
|
10
|
+
from stratifyai.chat import deepseek
|
|
11
|
+
response = await deepseek.chat("Hello!", model="deepseek-chat")
|
|
12
|
+
|
|
13
|
+
# Builder pattern (model required)
|
|
14
|
+
client = (
|
|
15
|
+
deepseek
|
|
16
|
+
.with_model("deepseek-reasoner")
|
|
17
|
+
.with_system("You are a helpful assistant")
|
|
18
|
+
.with_developer("Use markdown")
|
|
19
|
+
)
|
|
20
|
+
response = await client.chat("Hello!")
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
import asyncio
|
|
24
|
+
from typing import AsyncIterator, Optional, Union
|
|
25
|
+
|
|
26
|
+
from stratifyai import LLMClient
|
|
27
|
+
from stratifyai.models import ChatResponse, Message
|
|
28
|
+
from stratifyai.chat.builder import ChatBuilder, create_module_builder
|
|
29
|
+
|
|
30
|
+
# Default configuration (no default model - must be specified)
|
|
31
|
+
DEFAULT_TEMPERATURE = 0.7
|
|
32
|
+
DEFAULT_MAX_TOKENS = None
|
|
33
|
+
|
|
34
|
+
# Module-level client (lazy initialization)
|
|
35
|
+
_client: Optional[LLMClient] = None
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _get_client() -> LLMClient:
|
|
39
|
+
"""Get or create the module-level client."""
|
|
40
|
+
global _client
|
|
41
|
+
if _client is None:
|
|
42
|
+
_client = LLMClient(provider="deepseek")
|
|
43
|
+
return _client
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
# Module-level builder for chaining
|
|
47
|
+
_builder = create_module_builder(
|
|
48
|
+
provider="deepseek",
|
|
49
|
+
default_temperature=DEFAULT_TEMPERATURE,
|
|
50
|
+
default_max_tokens=DEFAULT_MAX_TOKENS,
|
|
51
|
+
client_factory=_get_client,
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
# Builder pattern methods (delegate to _builder)
|
|
56
|
+
def with_model(model: str) -> ChatBuilder:
|
|
57
|
+
"""Set the model to use. Returns a new ChatBuilder for chaining."""
|
|
58
|
+
return _builder.with_model(model)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def with_system(prompt: str) -> ChatBuilder:
|
|
62
|
+
"""Set the system prompt. Returns a new ChatBuilder for chaining."""
|
|
63
|
+
return _builder.with_system(prompt)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def with_developer(instructions: str) -> ChatBuilder:
|
|
67
|
+
"""Set developer instructions. Returns a new ChatBuilder for chaining."""
|
|
68
|
+
return _builder.with_developer(instructions)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def with_temperature(temperature: float) -> ChatBuilder:
|
|
72
|
+
"""Set the temperature. Returns a new ChatBuilder for chaining."""
|
|
73
|
+
return _builder.with_temperature(temperature)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def with_max_tokens(max_tokens: int) -> ChatBuilder:
|
|
77
|
+
"""Set max tokens. Returns a new ChatBuilder for chaining."""
|
|
78
|
+
return _builder.with_max_tokens(max_tokens)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def with_options(**kwargs) -> ChatBuilder:
|
|
82
|
+
"""Set additional options. Returns a new ChatBuilder for chaining."""
|
|
83
|
+
return _builder.with_options(**kwargs)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
async def chat(
|
|
87
|
+
prompt: Union[str, list[Message]],
|
|
88
|
+
*,
|
|
89
|
+
model: str,
|
|
90
|
+
system: Optional[str] = None,
|
|
91
|
+
temperature: float = DEFAULT_TEMPERATURE,
|
|
92
|
+
max_tokens: Optional[int] = DEFAULT_MAX_TOKENS,
|
|
93
|
+
stream: bool = False,
|
|
94
|
+
**kwargs,
|
|
95
|
+
) -> Union[ChatResponse, AsyncIterator[ChatResponse]]:
|
|
96
|
+
"""
|
|
97
|
+
Send a chat completion request to DeepSeek.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
prompt: User message string or list of Message objects.
|
|
101
|
+
model: Model name (required). E.g., "deepseek-chat", "deepseek-reasoner"
|
|
102
|
+
system: Optional system prompt (ignored if prompt is list of Messages).
|
|
103
|
+
temperature: Sampling temperature (0.0-2.0). Default: 0.7
|
|
104
|
+
max_tokens: Maximum tokens to generate. Default: None (model default)
|
|
105
|
+
stream: Whether to stream the response. Default: False
|
|
106
|
+
**kwargs: Additional parameters passed to the API.
|
|
107
|
+
|
|
108
|
+
Returns:
|
|
109
|
+
ChatResponse object, or AsyncIterator[ChatResponse] if streaming.
|
|
110
|
+
|
|
111
|
+
Example:
|
|
112
|
+
>>> from stratifyai.chat import deepseek
|
|
113
|
+
>>> response = await deepseek.chat("What is Python?", model="deepseek-chat")
|
|
114
|
+
>>> print(response.content)
|
|
115
|
+
"""
|
|
116
|
+
client = _get_client()
|
|
117
|
+
|
|
118
|
+
# Build messages list
|
|
119
|
+
if isinstance(prompt, str):
|
|
120
|
+
messages = []
|
|
121
|
+
if system:
|
|
122
|
+
messages.append(Message(role="system", content=system))
|
|
123
|
+
messages.append(Message(role="user", content=prompt))
|
|
124
|
+
else:
|
|
125
|
+
messages = prompt
|
|
126
|
+
|
|
127
|
+
return await client.chat(
|
|
128
|
+
model=model,
|
|
129
|
+
messages=messages,
|
|
130
|
+
temperature=temperature,
|
|
131
|
+
max_tokens=max_tokens,
|
|
132
|
+
stream=stream,
|
|
133
|
+
**kwargs,
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
async def chat_stream(
|
|
138
|
+
prompt: Union[str, list[Message]],
|
|
139
|
+
*,
|
|
140
|
+
model: str,
|
|
141
|
+
system: Optional[str] = None,
|
|
142
|
+
temperature: float = DEFAULT_TEMPERATURE,
|
|
143
|
+
max_tokens: Optional[int] = DEFAULT_MAX_TOKENS,
|
|
144
|
+
**kwargs,
|
|
145
|
+
) -> AsyncIterator[ChatResponse]:
|
|
146
|
+
"""
|
|
147
|
+
Send a streaming chat completion request to DeepSeek.
|
|
148
|
+
|
|
149
|
+
Args:
|
|
150
|
+
prompt: User message string or list of Message objects.
|
|
151
|
+
model: Model name (required). E.g., "deepseek-chat"
|
|
152
|
+
system: Optional system prompt (ignored if prompt is list of Messages).
|
|
153
|
+
temperature: Sampling temperature (0.0-2.0). Default: 0.7
|
|
154
|
+
max_tokens: Maximum tokens to generate. Default: None (model default)
|
|
155
|
+
**kwargs: Additional parameters passed to the API.
|
|
156
|
+
|
|
157
|
+
Yields:
|
|
158
|
+
ChatResponse chunks.
|
|
159
|
+
|
|
160
|
+
Example:
|
|
161
|
+
>>> from stratifyai.chat import deepseek
|
|
162
|
+
>>> async for chunk in deepseek.chat_stream("Tell me a story", model="deepseek-chat"):
|
|
163
|
+
... print(chunk.content, end="", flush=True)
|
|
164
|
+
"""
|
|
165
|
+
return await chat(
|
|
166
|
+
prompt,
|
|
167
|
+
model=model,
|
|
168
|
+
system=system,
|
|
169
|
+
temperature=temperature,
|
|
170
|
+
max_tokens=max_tokens,
|
|
171
|
+
stream=True,
|
|
172
|
+
**kwargs,
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def chat_sync(
|
|
177
|
+
prompt,
|
|
178
|
+
*,
|
|
179
|
+
model: str,
|
|
180
|
+
system=None,
|
|
181
|
+
temperature=DEFAULT_TEMPERATURE,
|
|
182
|
+
max_tokens=DEFAULT_MAX_TOKENS,
|
|
183
|
+
**kwargs,
|
|
184
|
+
):
|
|
185
|
+
"""Synchronous wrapper for chat()."""
|
|
186
|
+
return asyncio.run(chat(
|
|
187
|
+
prompt,
|
|
188
|
+
model=model,
|
|
189
|
+
system=system,
|
|
190
|
+
temperature=temperature,
|
|
191
|
+
max_tokens=max_tokens,
|
|
192
|
+
stream=False,
|
|
193
|
+
**kwargs,
|
|
194
|
+
))
|