askai-python 0.1.5__tar.gz → 0.2.0__tar.gz

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.
Files changed (31) hide show
  1. askai_python-0.2.0/PKG-INFO +120 -0
  2. askai_python-0.2.0/README.md +116 -0
  3. {askai_python-0.1.5 → askai_python-0.2.0}/ask_ai/base.py +45 -2
  4. askai_python-0.2.0/ask_ai/exceptions.py +26 -0
  5. askai_python-0.2.0/askai_python.egg-info/PKG-INFO +120 -0
  6. {askai_python-0.1.5 → askai_python-0.2.0}/askai_python.egg-info/SOURCES.txt +1 -1
  7. askai_python-0.2.0/docs/PYPI_README.md +101 -0
  8. {askai_python-0.1.5 → askai_python-0.2.0}/pyproject.toml +2 -2
  9. askai_python-0.1.5/PKG-INFO +0 -135
  10. askai_python-0.1.5/PYPI_README.md +0 -116
  11. askai_python-0.1.5/README.md +0 -111
  12. askai_python-0.1.5/ask_ai/exceptions.py +0 -15
  13. askai_python-0.1.5/askai_python.egg-info/PKG-INFO +0 -135
  14. {askai_python-0.1.5 → askai_python-0.2.0}/LICENSE +0 -0
  15. {askai_python-0.1.5 → askai_python-0.2.0}/ask_ai/__init__.py +0 -0
  16. {askai_python-0.1.5 → askai_python-0.2.0}/ask_ai/__main__.py +0 -0
  17. {askai_python-0.1.5 → askai_python-0.2.0}/ask_ai/cli.py +0 -0
  18. {askai_python-0.1.5 → askai_python-0.2.0}/ask_ai/config.py +0 -0
  19. {askai_python-0.1.5 → askai_python-0.2.0}/ask_ai/media.py +0 -0
  20. {askai_python-0.1.5 → askai_python-0.2.0}/ask_ai/providers/__init__.py +0 -0
  21. {askai_python-0.1.5 → askai_python-0.2.0}/ask_ai/providers/anthropic_provider.py +0 -0
  22. {askai_python-0.1.5 → askai_python-0.2.0}/ask_ai/providers/azure_provider.py +0 -0
  23. {askai_python-0.1.5 → askai_python-0.2.0}/ask_ai/providers/google_provider.py +0 -0
  24. {askai_python-0.1.5 → askai_python-0.2.0}/ask_ai/providers/groq_provider.py +0 -0
  25. {askai_python-0.1.5 → askai_python-0.2.0}/ask_ai/providers/openai_provider.py +0 -0
  26. {askai_python-0.1.5 → askai_python-0.2.0}/ask_ai/providers/openrouter_provider.py +0 -0
  27. {askai_python-0.1.5 → askai_python-0.2.0}/askai_python.egg-info/dependency_links.txt +0 -0
  28. {askai_python-0.1.5 → askai_python-0.2.0}/askai_python.egg-info/requires.txt +0 -0
  29. {askai_python-0.1.5 → askai_python-0.2.0}/askai_python.egg-info/top_level.txt +0 -0
  30. {askai_python-0.1.5 → askai_python-0.2.0}/setup.cfg +0 -0
  31. {askai_python-0.1.5 → askai_python-0.2.0}/tests/test_core.py +0 -0
@@ -0,0 +1,120 @@
1
+ Metadata-Version: 2.4
2
+ Name: askai-python
3
+ Version: 0.2.0
4
+ Summary: AI Made Stupid Simple. Unified API for OpenAI, Groq, Google, and more.
5
+ Author-email: Hossein Ghorbani <hosseingh1068@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://hosseinghorbani0.ir/
8
+ Project-URL: Bug Tracker, https://github.com/Hosseinghorbani0/ask-ai/issues
9
+ Requires-Python: >=3.8
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Requires-Dist: openai>=1.0.0
13
+ Requires-Dist: groq
14
+ Requires-Dist: google-generativeai
15
+ Requires-Dist: anthropic
16
+ Requires-Dist: requests
17
+ Requires-Dist: Pillow
18
+ Dynamic: license-file
19
+
20
+ # askai-python 🚀
21
+
22
+ **A minimal Python SDK to switch between LLM providers in one line.**
23
+ No frameworks. No servers. No overengineering.
24
+
25
+ [![PyPI version](https://img.shields.io/pypi/v/askai-python.svg)](https://pypi.org/project/askai-python/)
26
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
27
+ [![GitHub](https://img.shields.io/badge/GitHub-View%20Source-blue.svg)](https://github.com/Hosseinghorbani0/ask-ai)
28
+
29
+ ---
30
+
31
+ ## ⚡ Quick Start (5 seconds)
32
+
33
+ ```bash
34
+ pip install askai-python
35
+ ```
36
+
37
+ ```python
38
+ from ask_ai import OpenAI, Groq
39
+
40
+ # Auto-detects OPENAI_API_KEY from environment
41
+ print(OpenAI().ask("Explain black holes like I'm 5").text)
42
+
43
+ # Switch provider instantly
44
+ print(Groq().ask("Explain black holes like I'm 5").text)
45
+ ```
46
+
47
+ ---
48
+
49
+ ## 🧐 Why ask-ai?
50
+
51
+ - **One function**: Just call `.ask()`
52
+ - **Multiple providers**: OpenAI, Anthropic, Google Gemini, Groq, Azure, OpenRouter
53
+ - **Zero config**: Keys are pulled from the environment automatically
54
+ - **SDK-first, not a framework**: It stays out of your way.
55
+
56
+ ## ⚖️ How it compares
57
+
58
+ | Feature | ask-ai | LangChain |
59
+ | -------------- | ------ | --------- |
60
+ | Setup time | 30 sec | 1 hour |
61
+ | Learning curve | ⭐ | ⭐⭐⭐⭐⭐ |
62
+ | Async support | ⏳ *(Coming soon)* | ⚠️ Complex |
63
+ | Retry/Timeout | ✅ Built-in | ❌ Manual |
64
+ | Gateway needed | ❌ No | ❌ No |
65
+
66
+ ## 🚫 What this project is NOT
67
+
68
+ > ❌ Not an AI framework
69
+ > ❌ Not an API gateway
70
+ > ❌ Not an agent memory system
71
+
72
+ It does one thing perfectly: **Simplifying the API call to LLMs.**
73
+
74
+ ---
75
+
76
+ ## 🚀 Built-in Resiliency (Retries & Timeouts)
77
+
78
+ Build reliable apps without writing your own loops. `askai-python` handles rate limits (`429`) and network drops via an internal exponential backoff.
79
+
80
+ ```python
81
+ from ask_ai import OpenAI
82
+
83
+ ai = OpenAI()
84
+
85
+ # Automatically retries up to 3 times on transient errors, with a 15-second timeout
86
+ response = ai.ask(
87
+ "Write a complex python script",
88
+ retry=3,
89
+ timeout=15
90
+ )
91
+ ```
92
+
93
+ ## 🔌 Supported Providers
94
+
95
+ | Provider | Class | Capabilities |
96
+ |----------|-------|-------------|
97
+ | **OpenAI** | `OpenAI` | Text, Images (DALL-E), Vision |
98
+ | **Anthropic** | `Anthropic` | Text, Vision (Claude 3.5) |
99
+ | **Google** | `Google` | Text, Images, Video, Audio |
100
+ | **Groq** | `Groq` | Ultra-fast Llama 3 & Mixtral |
101
+ | **Azure** | `Azure` | Enterprise-grade OpenAI |
102
+ | **OpenRouter**| `OpenRouter`| 100+ community models |
103
+
104
+ ---
105
+
106
+ ## 🗺️ Roadmap
107
+
108
+ - [x] Baseline multiple providers
109
+ - [x] Automated Retry & Timeout controls
110
+ - [ ] Async API (`await ask_async`)
111
+ - [ ] Provider Fallback (`fallback=[Groq()]`)
112
+ - [ ] Structured Outputs (Pydantic Support)
113
+
114
+ ---
115
+
116
+ ## 🔗 Important Links
117
+
118
+ - **GitHub Repository**: [Hosseinghorbani0/ask-ai](https://github.com/Hosseinghorbani0/ask-ai) (Star us! ⭐)
119
+ - **Official Website**: [hosseinghorbani0.ir](https://hosseinghorbani0.ir/)
120
+ - **Bug Tracker**: [Report an Issue](https://github.com/Hosseinghorbani0/ask-ai/issues)
@@ -0,0 +1,116 @@
1
+ # ask-ai
2
+
3
+ <p align="center">
4
+ 🌍 <b>Readme:</b>
5
+ <a href="README.md"><img src="https://flagcdn.com/20x15/us.png" alt="English"> English</a> ·
6
+ <a href="docs/README_fa.md"><img src="https://flagcdn.com/20x15/ir.png" alt="Persian"> فارسی</a> ·
7
+ <a href="docs/README_zh.md"><img src="https://flagcdn.com/20x15/cn.png" alt="Chinese"> 中文</a> ·
8
+ <a href="docs/README_tr.md"><img src="https://flagcdn.com/20x15/tr.png" alt="Turkish"> Türkçe</a> ·
9
+ <a href="docs/README_ar.md"><img src="https://flagcdn.com/20x15/sa.png" alt="Arabic"> العربية</a> ·
10
+ <a href="docs/README_ru.md"><img src="https://flagcdn.com/20x15/ru.png" alt="Russian"> Русский</a> ·
11
+ <a href="docs/README_es.md"><img src="https://flagcdn.com/20x15/es.png" alt="Spanish"> Español</a> ·
12
+ <a href="docs/README_ja.md"><img src="https://flagcdn.com/20x15/jp.png" alt="Japanese"> 日本語</a>
13
+ </p>
14
+
15
+ <p align="center">
16
+ <b>A minimal Python SDK to switch between LLM providers in one line.</b><br/>
17
+ No frameworks. No servers. No overengineering.
18
+ </p>
19
+
20
+ [![PyPI version](https://img.shields.io/pypi/v/askai-python.svg)](https://pypi.org/project/askai-python/)
21
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
22
+ [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
23
+
24
+ ---
25
+
26
+ ## ⚡ Quick Start (5 seconds)
27
+
28
+ ```bash
29
+ pip install askai-python
30
+ ```
31
+
32
+ ```python
33
+ from ask_ai import OpenAI, Groq
34
+
35
+ # Auto-detects OPENAI_API_KEY from environment
36
+ OpenAI().ask("Explain black holes like I'm 5").text
37
+
38
+ # Switch provider effortlessly
39
+ Groq().ask("Explain black holes like I'm 5").text
40
+ ```
41
+
42
+ ---
43
+
44
+ ## 🧐 Why ask-ai?
45
+
46
+ - **One function**: Just call `.ask()`
47
+ - **Multiple providers**: OpenAI, Anthropic, Google Gemini, Groq, Azure, OpenRouter
48
+ - **Zero config**: Keys are pulled from the environment automatically
49
+ - **SDK-first, not a framework**: It stays out of your way.
50
+
51
+ ## ⚖️ How it compares
52
+
53
+ | Feature | ask-ai | LangChain |
54
+ | -------------- | ------ | --------- |
55
+ | Setup time | 30 sec | 1 hour |
56
+ | Learning curve | ⭐ | ⭐⭐⭐⭐⭐ |
57
+ | Async support | ⏳ *(Coming soon)* | ⚠️ Complex |
58
+ | Retry/Timeout | ✅ Built-in | ❌ Manual |
59
+ | Gateway needed | ❌ No | ❌ No |
60
+ | Lines to switch| **1** | 20+ |
61
+
62
+ ## 🚫 What this project is NOT
63
+
64
+ > ❌ Not an AI framework
65
+ > ❌ Not an API gateway
66
+ > ❌ Not an agent memory system
67
+
68
+ It does one thing perfectly: **Simplifying the API call to LLMs.**
69
+
70
+ ---
71
+
72
+ ## 🛠️ Advanced Usage
73
+
74
+ ### Built-in Retries & Timeout (Resiliency)
75
+ Handle rate limits (`429`) and network drops automatically:
76
+
77
+ ```python
78
+ from ask_ai import OpenAI
79
+ ai = OpenAI()
80
+
81
+ # Will retry up to 3 times on RateLimit/Network errors, with generic timeout
82
+ response = ai.ask("Write a script", retry=3, timeout=10)
83
+ ```
84
+
85
+ ### System Configuration
86
+ Set system prompts and temperature directly:
87
+
88
+ ```python
89
+ ai.advanced(
90
+ temperature=0.7,
91
+ prompt="You are a senior DevOps engineer."
92
+ )
93
+
94
+ print(ai.ask("How do I optimize a Dockerfile?").text)
95
+ ```
96
+
97
+ ---
98
+
99
+ ## 🗺️ Roadmap
100
+
101
+ - [x] OpenAI, Groq, Gemini, Anthropic, Azure, OpenRouter support
102
+ - [x] Text to Image (DALL-E) and Text to Audio
103
+ - [x] Automated Retry & Timeout controls
104
+ - [ ] Async Support (`await ask_async`)
105
+ - [ ] Provider Fallback (`ask(..., providers=[OpenAI, Groq])`)
106
+ - [ ] Streaming Support (`ask_stream`)
107
+ - [ ] Structured Output (Pydantic Support)
108
+
109
+ ---
110
+
111
+ ## 🔗 Important Links
112
+
113
+ - **PyPI**: [askai-python](https://pypi.org/project/askai-python/)
114
+ - **GitHub Repository**: [Hosseinghorbani0/ask-ai](https://github.com/Hosseinghorbani0/ask-ai) (Star us! ⭐)
115
+ - **Official Website**: [hosseinghorbani0.ir](https://hosseinghorbani0.ir/)
116
+ - **Bug Tracker**: [Report an Issue](https://github.com/Hosseinghorbani0/ask-ai/issues)
@@ -82,8 +82,51 @@ class BaseProvider:
82
82
  # 3. Check for specific output_type override (e.g. user forced image)
83
83
  output_type = kwargs.get('output_type')
84
84
 
85
- # 4. Call Provider Implementation
86
- return self._send_request(messages, final_config, output_type)
85
+ # 4. Extract timeout and retry safely
86
+ timeout_val = kwargs.get('timeout', final_config.extra.get('timeout', 30))
87
+ retry_val = kwargs.get('retry', final_config.extra.get('retry', 0))
88
+
89
+ timeout = float(timeout_val) if timeout_val is not None else 30.0
90
+ retry = int(retry_val) if retry_val is not None else 0
91
+
92
+ final_config.extra['timeout'] = timeout # Pass down to providers
93
+
94
+ # 5. Execute with Retry Logic
95
+ attempts = 0
96
+ last_error = None
97
+ while attempts <= retry:
98
+ try:
99
+ return self._send_request(messages, final_config, output_type)
100
+ except Exception as e:
101
+ last_error = e
102
+ if self._is_retryable_error(e) and attempts < retry:
103
+ attempts += 1
104
+ delay = 2 ** attempts # 2s, 4s, 8s...
105
+ print(f"[ask-ai] Transient error ({e.__class__.__name__}). Retrying in {delay}s... ({attempts}/{retry})")
106
+ import time
107
+ time.sleep(delay)
108
+ else:
109
+ raise e
110
+
111
+ # Fallback if loop exits without returning
112
+ from .exceptions import AskAINetworkError
113
+ raise AskAINetworkError(f"Request failed after {retry} retries. Last error: {last_error}")
114
+
115
+ def _is_retryable_error(self, e: Exception) -> bool:
116
+ """Dynamically detect rate limits and network timeouts across different provider SDKs."""
117
+ err_str = str(e).lower()
118
+ err_cls = e.__class__.__name__.lower()
119
+
120
+ # Explicit ask-ai errors
121
+ from .exceptions import AskAINetworkError, AskAIRateLimitError
122
+ if isinstance(e, (AskAINetworkError, AskAIRateLimitError)): return True
123
+
124
+ # Heuristics for underlying provider SDKs (OpenAI, Anthropic, etc.)
125
+ if "ratelimit" in err_cls or "rate_limit" in err_cls or "429" in err_str: return True
126
+ if "timeout" in err_cls or "timeout" in err_str: return True
127
+ if "connection" in err_cls or "connecterror" in err_cls: return True
128
+
129
+ return False
87
130
 
88
131
  def _merge_configs(self, global_conf: AdvancedConfig, req_conf: AdvancedConfig) -> AdvancedConfig:
89
132
  return global_conf.merge(req_conf) # We need to implement merge logic in AdvancedConfig properly or here
@@ -0,0 +1,26 @@
1
+ class AskAIError(Exception):
2
+ """Base exception for all ask-ai errors."""
3
+ pass
4
+
5
+ class AskAIConfigError(AskAIError):
6
+ """Raised when configuration (like API keys) is missing or invalid."""
7
+ pass
8
+
9
+ class AskAINetworkError(AskAIError):
10
+ """Raised when a network connection fails (timeout, disconnect)."""
11
+ pass
12
+
13
+ class AskAIRateLimitError(AskAIError):
14
+ """Raised when the provider rate limits the request (429)."""
15
+ pass
16
+
17
+ class ProviderError(AskAIError):
18
+ """Raised when the provider API fails (e.g. 500 error or bad request)."""
19
+ pass
20
+
21
+ class MediaTypeNotSupportedError(AskAIError):
22
+ """Raised when a provider can't handle the requested media type."""
23
+ pass
24
+
25
+ # Alias for backwards compatibility internally
26
+ APIKeyError = AskAIConfigError
@@ -0,0 +1,120 @@
1
+ Metadata-Version: 2.4
2
+ Name: askai-python
3
+ Version: 0.2.0
4
+ Summary: AI Made Stupid Simple. Unified API for OpenAI, Groq, Google, and more.
5
+ Author-email: Hossein Ghorbani <hosseingh1068@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://hosseinghorbani0.ir/
8
+ Project-URL: Bug Tracker, https://github.com/Hosseinghorbani0/ask-ai/issues
9
+ Requires-Python: >=3.8
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Requires-Dist: openai>=1.0.0
13
+ Requires-Dist: groq
14
+ Requires-Dist: google-generativeai
15
+ Requires-Dist: anthropic
16
+ Requires-Dist: requests
17
+ Requires-Dist: Pillow
18
+ Dynamic: license-file
19
+
20
+ # askai-python 🚀
21
+
22
+ **A minimal Python SDK to switch between LLM providers in one line.**
23
+ No frameworks. No servers. No overengineering.
24
+
25
+ [![PyPI version](https://img.shields.io/pypi/v/askai-python.svg)](https://pypi.org/project/askai-python/)
26
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
27
+ [![GitHub](https://img.shields.io/badge/GitHub-View%20Source-blue.svg)](https://github.com/Hosseinghorbani0/ask-ai)
28
+
29
+ ---
30
+
31
+ ## ⚡ Quick Start (5 seconds)
32
+
33
+ ```bash
34
+ pip install askai-python
35
+ ```
36
+
37
+ ```python
38
+ from ask_ai import OpenAI, Groq
39
+
40
+ # Auto-detects OPENAI_API_KEY from environment
41
+ print(OpenAI().ask("Explain black holes like I'm 5").text)
42
+
43
+ # Switch provider instantly
44
+ print(Groq().ask("Explain black holes like I'm 5").text)
45
+ ```
46
+
47
+ ---
48
+
49
+ ## 🧐 Why ask-ai?
50
+
51
+ - **One function**: Just call `.ask()`
52
+ - **Multiple providers**: OpenAI, Anthropic, Google Gemini, Groq, Azure, OpenRouter
53
+ - **Zero config**: Keys are pulled from the environment automatically
54
+ - **SDK-first, not a framework**: It stays out of your way.
55
+
56
+ ## ⚖️ How it compares
57
+
58
+ | Feature | ask-ai | LangChain |
59
+ | -------------- | ------ | --------- |
60
+ | Setup time | 30 sec | 1 hour |
61
+ | Learning curve | ⭐ | ⭐⭐⭐⭐⭐ |
62
+ | Async support | ⏳ *(Coming soon)* | ⚠️ Complex |
63
+ | Retry/Timeout | ✅ Built-in | ❌ Manual |
64
+ | Gateway needed | ❌ No | ❌ No |
65
+
66
+ ## 🚫 What this project is NOT
67
+
68
+ > ❌ Not an AI framework
69
+ > ❌ Not an API gateway
70
+ > ❌ Not an agent memory system
71
+
72
+ It does one thing perfectly: **Simplifying the API call to LLMs.**
73
+
74
+ ---
75
+
76
+ ## 🚀 Built-in Resiliency (Retries & Timeouts)
77
+
78
+ Build reliable apps without writing your own loops. `askai-python` handles rate limits (`429`) and network drops via an internal exponential backoff.
79
+
80
+ ```python
81
+ from ask_ai import OpenAI
82
+
83
+ ai = OpenAI()
84
+
85
+ # Automatically retries up to 3 times on transient errors, with a 15-second timeout
86
+ response = ai.ask(
87
+ "Write a complex python script",
88
+ retry=3,
89
+ timeout=15
90
+ )
91
+ ```
92
+
93
+ ## 🔌 Supported Providers
94
+
95
+ | Provider | Class | Capabilities |
96
+ |----------|-------|-------------|
97
+ | **OpenAI** | `OpenAI` | Text, Images (DALL-E), Vision |
98
+ | **Anthropic** | `Anthropic` | Text, Vision (Claude 3.5) |
99
+ | **Google** | `Google` | Text, Images, Video, Audio |
100
+ | **Groq** | `Groq` | Ultra-fast Llama 3 & Mixtral |
101
+ | **Azure** | `Azure` | Enterprise-grade OpenAI |
102
+ | **OpenRouter**| `OpenRouter`| 100+ community models |
103
+
104
+ ---
105
+
106
+ ## 🗺️ Roadmap
107
+
108
+ - [x] Baseline multiple providers
109
+ - [x] Automated Retry & Timeout controls
110
+ - [ ] Async API (`await ask_async`)
111
+ - [ ] Provider Fallback (`fallback=[Groq()]`)
112
+ - [ ] Structured Outputs (Pydantic Support)
113
+
114
+ ---
115
+
116
+ ## 🔗 Important Links
117
+
118
+ - **GitHub Repository**: [Hosseinghorbani0/ask-ai](https://github.com/Hosseinghorbani0/ask-ai) (Star us! ⭐)
119
+ - **Official Website**: [hosseinghorbani0.ir](https://hosseinghorbani0.ir/)
120
+ - **Bug Tracker**: [Report an Issue](https://github.com/Hosseinghorbani0/ask-ai/issues)
@@ -1,5 +1,4 @@
1
1
  LICENSE
2
- PYPI_README.md
3
2
  README.md
4
3
  pyproject.toml
5
4
  ask_ai/__init__.py
@@ -21,4 +20,5 @@ askai_python.egg-info/SOURCES.txt
21
20
  askai_python.egg-info/dependency_links.txt
22
21
  askai_python.egg-info/requires.txt
23
22
  askai_python.egg-info/top_level.txt
23
+ docs/PYPI_README.md
24
24
  tests/test_core.py
@@ -0,0 +1,101 @@
1
+ # askai-python 🚀
2
+
3
+ **A minimal Python SDK to switch between LLM providers in one line.**
4
+ No frameworks. No servers. No overengineering.
5
+
6
+ [![PyPI version](https://img.shields.io/pypi/v/askai-python.svg)](https://pypi.org/project/askai-python/)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
+ [![GitHub](https://img.shields.io/badge/GitHub-View%20Source-blue.svg)](https://github.com/Hosseinghorbani0/ask-ai)
9
+
10
+ ---
11
+
12
+ ## ⚡ Quick Start (5 seconds)
13
+
14
+ ```bash
15
+ pip install askai-python
16
+ ```
17
+
18
+ ```python
19
+ from ask_ai import OpenAI, Groq
20
+
21
+ # Auto-detects OPENAI_API_KEY from environment
22
+ print(OpenAI().ask("Explain black holes like I'm 5").text)
23
+
24
+ # Switch provider instantly
25
+ print(Groq().ask("Explain black holes like I'm 5").text)
26
+ ```
27
+
28
+ ---
29
+
30
+ ## 🧐 Why ask-ai?
31
+
32
+ - **One function**: Just call `.ask()`
33
+ - **Multiple providers**: OpenAI, Anthropic, Google Gemini, Groq, Azure, OpenRouter
34
+ - **Zero config**: Keys are pulled from the environment automatically
35
+ - **SDK-first, not a framework**: It stays out of your way.
36
+
37
+ ## ⚖️ How it compares
38
+
39
+ | Feature | ask-ai | LangChain |
40
+ | -------------- | ------ | --------- |
41
+ | Setup time | 30 sec | 1 hour |
42
+ | Learning curve | ⭐ | ⭐⭐⭐⭐⭐ |
43
+ | Async support | ⏳ *(Coming soon)* | ⚠️ Complex |
44
+ | Retry/Timeout | ✅ Built-in | ❌ Manual |
45
+ | Gateway needed | ❌ No | ❌ No |
46
+
47
+ ## 🚫 What this project is NOT
48
+
49
+ > ❌ Not an AI framework
50
+ > ❌ Not an API gateway
51
+ > ❌ Not an agent memory system
52
+
53
+ It does one thing perfectly: **Simplifying the API call to LLMs.**
54
+
55
+ ---
56
+
57
+ ## 🚀 Built-in Resiliency (Retries & Timeouts)
58
+
59
+ Build reliable apps without writing your own loops. `askai-python` handles rate limits (`429`) and network drops via an internal exponential backoff.
60
+
61
+ ```python
62
+ from ask_ai import OpenAI
63
+
64
+ ai = OpenAI()
65
+
66
+ # Automatically retries up to 3 times on transient errors, with a 15-second timeout
67
+ response = ai.ask(
68
+ "Write a complex python script",
69
+ retry=3,
70
+ timeout=15
71
+ )
72
+ ```
73
+
74
+ ## 🔌 Supported Providers
75
+
76
+ | Provider | Class | Capabilities |
77
+ |----------|-------|-------------|
78
+ | **OpenAI** | `OpenAI` | Text, Images (DALL-E), Vision |
79
+ | **Anthropic** | `Anthropic` | Text, Vision (Claude 3.5) |
80
+ | **Google** | `Google` | Text, Images, Video, Audio |
81
+ | **Groq** | `Groq` | Ultra-fast Llama 3 & Mixtral |
82
+ | **Azure** | `Azure` | Enterprise-grade OpenAI |
83
+ | **OpenRouter**| `OpenRouter`| 100+ community models |
84
+
85
+ ---
86
+
87
+ ## 🗺️ Roadmap
88
+
89
+ - [x] Baseline multiple providers
90
+ - [x] Automated Retry & Timeout controls
91
+ - [ ] Async API (`await ask_async`)
92
+ - [ ] Provider Fallback (`fallback=[Groq()]`)
93
+ - [ ] Structured Outputs (Pydantic Support)
94
+
95
+ ---
96
+
97
+ ## 🔗 Important Links
98
+
99
+ - **GitHub Repository**: [Hosseinghorbani0/ask-ai](https://github.com/Hosseinghorbani0/ask-ai) (Star us! ⭐)
100
+ - **Official Website**: [hosseinghorbani0.ir](https://hosseinghorbani0.ir/)
101
+ - **Bug Tracker**: [Report an Issue](https://github.com/Hosseinghorbani0/ask-ai/issues)
@@ -4,9 +4,9 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "askai-python"
7
- version = "0.1.5"
7
+ version = "0.2.0"
8
8
  description = "AI Made Stupid Simple. Unified API for OpenAI, Groq, Google, and more."
9
- readme = "PYPI_README.md"
9
+ readme = "docs/PYPI_README.md"
10
10
  requires-python = ">=3.8"
11
11
  license = {text = "MIT"}
12
12
  authors = [
@@ -1,135 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: askai-python
3
- Version: 0.1.5
4
- Summary: AI Made Stupid Simple. Unified API for OpenAI, Groq, Google, and more.
5
- Author-email: Hossein Ghorbani <hosseingh1068@gmail.com>
6
- License: MIT
7
- Project-URL: Homepage, https://hosseinghorbani0.ir/
8
- Project-URL: Bug Tracker, https://github.com/Hosseinghorbani0/ask-ai/issues
9
- Requires-Python: >=3.8
10
- Description-Content-Type: text/markdown
11
- License-File: LICENSE
12
- Requires-Dist: openai>=1.0.0
13
- Requires-Dist: groq
14
- Requires-Dist: google-generativeai
15
- Requires-Dist: anthropic
16
- Requires-Dist: requests
17
- Requires-Dist: Pillow
18
- Dynamic: license-file
19
-
20
- # askai-python 🚀
21
-
22
- **AI Made Stupid Simple.** One unified Python client for OpenAI, Claude, Gemini, Groq, and Azure.
23
-
24
- [![PyPI version](https://img.shields.io/pypi/v/askai-python.svg)](https://pypi.org/project/askai-python/)
25
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
26
- [![GitHub](https://img.shields.io/badge/GitHub-View%20Source-blue.svg)](https://github.com/Hosseinghorbani0/ask-ai)
27
-
28
- ---
29
-
30
- ## ⚡ What is askai-python?
31
-
32
- `askai-python` is a lightweight, zero-dependency-logic wrapper that provides a **single API** for all major AI providers. Stop learning multiple SDKs; just call `.ask()` and get your answer.
33
-
34
- - **Unified Interface**: One syntax for OpenAI, Anthropic, Google, and more.
35
- - **Zero-Config**: Seamlessly uses environment variables for API keys.
36
- - **Smart Media**: Easy handling of images and audio (Provider permitting).
37
- - **Production Grade**: Built-in robust error handling and type hints.
38
-
39
- ---
40
-
41
- ## 📦 Installation
42
-
43
- ```bash
44
- pip install askai-python
45
- ```
46
-
47
- ---
48
-
49
- ## 🚀 Examples & Tutorials
50
-
51
- ### 1. Basic Usage (The 3-Line Magic)
52
- ```python
53
- from ask_ai import OpenAI
54
-
55
- ai = OpenAI() # Auto-loads OPENAI_API_KEY from env
56
- print(ai.ask("What is the capital of France?").text)
57
- ```
58
-
59
- ### 2. Multi-Provider Mastery
60
- Switching between top-tier models has never been easier:
61
-
62
- ```python
63
- from ask_ai import OpenAI, Anthropic, Google
64
-
65
- prompt = "Explain quantum computing to a 5-year-old."
66
-
67
- # OpenAI (GPT-4o)
68
- print(OpenAI().ask(prompt).text)
69
-
70
- # Anthropic (Claude 3.5 Sonnet)
71
- print(Anthropic().ask(prompt).text)
72
-
73
- # Google (Gemini 1.5 Pro)
74
- print(Google().ask(prompt).text)
75
- ```
76
-
77
- ### 3. Advanced Configuration (System Personas)
78
- You can set a system prompt and temperature globally for an instance or per-request.
79
-
80
- ```python
81
- from ask_ai import OpenAI
82
-
83
- ai = OpenAI()
84
-
85
- # Global config
86
- ai.advanced(
87
- prompt="You are a sarcastic robot from the year 3000.",
88
- temperature=0.9
89
- )
90
-
91
- print(ai.ask("What is love?").text)
92
-
93
- # Per-request override
94
- print(ai.ask("What is 1+1?", temperature=0.1).text)
95
- ```
96
-
97
- ### 4. Handling Structured Exceptions
98
- Build reliable apps by catching specific AI errors:
99
-
100
- ```python
101
- from ask_ai import OpenAI
102
- from ask_ai.exceptions import AskAIError, APIKeyError
103
-
104
- try:
105
- ai = OpenAI(api_key="invalid-key")
106
- ai.ask("Hello")
107
- except APIKeyError:
108
- print("Check your API keys!")
109
- except AskAIError as e:
110
- print(f"An AI error occurred: {e}")
111
- ```
112
-
113
- ---
114
-
115
- ## 🔌 Supported Providers
116
-
117
- | Provider | Class | Capabilities |
118
- |----------|-------|-------------|
119
- | **OpenAI** | `OpenAI` | Text, Images (DALL-E), Vision |
120
- | **Anthropic** | `Anthropic` | Text, Vision (Claude 3.5) |
121
- | **Google** | `Google` | Text, Images, Video, Audio |
122
- | **Groq** | `Groq` | Ultra-fast Llama 3 & Mixtral |
123
- | **Azure** | `Azure` | Enterprise-grade OpenAI |
124
- | **OpenRouter**| `OpenRouter`| 100+ community models |
125
-
126
- ---
127
-
128
- ## 🔗 Important Links
129
-
130
- - **GitHub Repository**: [Hosseinghorbani0/ask-ai](https://github.com/Hosseinghorbani0/ask-ai) (Star us! ⭐)
131
- - **Official Website**: [hosseinghorbani0.ir](https://hosseinghorbani0.ir/)
132
- - **Bug Tracker**: [Report an Issue](https://github.com/Hosseinghorbani0/ask-ai/issues)
133
-
134
- ---
135
- *Built with ❤️ by [Hossein Ghorbani](https://github.com/Hosseinghorbani0).*
@@ -1,116 +0,0 @@
1
- # askai-python 🚀
2
-
3
- **AI Made Stupid Simple.** One unified Python client for OpenAI, Claude, Gemini, Groq, and Azure.
4
-
5
- [![PyPI version](https://img.shields.io/pypi/v/askai-python.svg)](https://pypi.org/project/askai-python/)
6
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
- [![GitHub](https://img.shields.io/badge/GitHub-View%20Source-blue.svg)](https://github.com/Hosseinghorbani0/ask-ai)
8
-
9
- ---
10
-
11
- ## ⚡ What is askai-python?
12
-
13
- `askai-python` is a lightweight, zero-dependency-logic wrapper that provides a **single API** for all major AI providers. Stop learning multiple SDKs; just call `.ask()` and get your answer.
14
-
15
- - **Unified Interface**: One syntax for OpenAI, Anthropic, Google, and more.
16
- - **Zero-Config**: Seamlessly uses environment variables for API keys.
17
- - **Smart Media**: Easy handling of images and audio (Provider permitting).
18
- - **Production Grade**: Built-in robust error handling and type hints.
19
-
20
- ---
21
-
22
- ## 📦 Installation
23
-
24
- ```bash
25
- pip install askai-python
26
- ```
27
-
28
- ---
29
-
30
- ## 🚀 Examples & Tutorials
31
-
32
- ### 1. Basic Usage (The 3-Line Magic)
33
- ```python
34
- from ask_ai import OpenAI
35
-
36
- ai = OpenAI() # Auto-loads OPENAI_API_KEY from env
37
- print(ai.ask("What is the capital of France?").text)
38
- ```
39
-
40
- ### 2. Multi-Provider Mastery
41
- Switching between top-tier models has never been easier:
42
-
43
- ```python
44
- from ask_ai import OpenAI, Anthropic, Google
45
-
46
- prompt = "Explain quantum computing to a 5-year-old."
47
-
48
- # OpenAI (GPT-4o)
49
- print(OpenAI().ask(prompt).text)
50
-
51
- # Anthropic (Claude 3.5 Sonnet)
52
- print(Anthropic().ask(prompt).text)
53
-
54
- # Google (Gemini 1.5 Pro)
55
- print(Google().ask(prompt).text)
56
- ```
57
-
58
- ### 3. Advanced Configuration (System Personas)
59
- You can set a system prompt and temperature globally for an instance or per-request.
60
-
61
- ```python
62
- from ask_ai import OpenAI
63
-
64
- ai = OpenAI()
65
-
66
- # Global config
67
- ai.advanced(
68
- prompt="You are a sarcastic robot from the year 3000.",
69
- temperature=0.9
70
- )
71
-
72
- print(ai.ask("What is love?").text)
73
-
74
- # Per-request override
75
- print(ai.ask("What is 1+1?", temperature=0.1).text)
76
- ```
77
-
78
- ### 4. Handling Structured Exceptions
79
- Build reliable apps by catching specific AI errors:
80
-
81
- ```python
82
- from ask_ai import OpenAI
83
- from ask_ai.exceptions import AskAIError, APIKeyError
84
-
85
- try:
86
- ai = OpenAI(api_key="invalid-key")
87
- ai.ask("Hello")
88
- except APIKeyError:
89
- print("Check your API keys!")
90
- except AskAIError as e:
91
- print(f"An AI error occurred: {e}")
92
- ```
93
-
94
- ---
95
-
96
- ## 🔌 Supported Providers
97
-
98
- | Provider | Class | Capabilities |
99
- |----------|-------|-------------|
100
- | **OpenAI** | `OpenAI` | Text, Images (DALL-E), Vision |
101
- | **Anthropic** | `Anthropic` | Text, Vision (Claude 3.5) |
102
- | **Google** | `Google` | Text, Images, Video, Audio |
103
- | **Groq** | `Groq` | Ultra-fast Llama 3 & Mixtral |
104
- | **Azure** | `Azure` | Enterprise-grade OpenAI |
105
- | **OpenRouter**| `OpenRouter`| 100+ community models |
106
-
107
- ---
108
-
109
- ## 🔗 Important Links
110
-
111
- - **GitHub Repository**: [Hosseinghorbani0/ask-ai](https://github.com/Hosseinghorbani0/ask-ai) (Star us! ⭐)
112
- - **Official Website**: [hosseinghorbani0.ir](https://hosseinghorbani0.ir/)
113
- - **Bug Tracker**: [Report an Issue](https://github.com/Hosseinghorbani0/ask-ai/issues)
114
-
115
- ---
116
- *Built with ❤️ by [Hossein Ghorbani](https://github.com/Hosseinghorbani0).*
@@ -1,111 +0,0 @@
1
- # ask-ai
2
-
3
- <p align="center">
4
- 🌍 <b>Readme:</b>
5
- <a href="README.md"><img src="https://flagcdn.com/20x15/us.png" alt="English"> English</a> ·
6
- <a href="docs/README_fa.md"><img src="https://flagcdn.com/20x15/ir.png" alt="Persian"> فارسی</a> ·
7
- <a href="docs/README_zh.md"><img src="https://flagcdn.com/20x15/cn.png" alt="Chinese"> 中文</a> ·
8
- <a href="docs/README_tr.md"><img src="https://flagcdn.com/20x15/tr.png" alt="Turkish"> Türkçe</a> ·
9
- <a href="docs/README_ar.md"><img src="https://flagcdn.com/20x15/sa.png" alt="Arabic"> العربية</a> ·
10
- <a href="docs/README_ru.md"><img src="https://flagcdn.com/20x15/ru.png" alt="Russian"> Русский</a> ·
11
- <a href="docs/README_es.md"><img src="https://flagcdn.com/20x15/es.png" alt="Spanish"> Español</a> ·
12
- <a href="docs/README_ja.md"><img src="https://flagcdn.com/20x15/jp.png" alt="Japanese"> 日本語</a>
13
- </p>
14
-
15
- <p align="center">
16
- <b>AI Made Simple.</b><br/>
17
- One unified Python client for OpenAI, Claude, Gemini, Groq & more.
18
- </p>
19
-
20
- > Stop rewriting AI code for every provider. Use one line. Switch models anytime.
21
-
22
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
23
- [![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
24
-
25
- ---
26
-
27
- ## ⚡ Why ask-ai?
28
-
29
- - **No SDK lock-in**: Don't learn 5 different libraries. Learn one.
30
- - **Unified API**: `ai.ask()` works for text, images, and audio across all providers.
31
- - **Production Ready**: Built-in type safety, error handling, and environment management.
32
- - **Zero-Config**: Auto-detects API keys from your environment.
33
-
34
- ---
35
-
36
- ## 🚀 The Golden Example
37
-
38
- See the power of `ask-ai` in 3 lines of code:
39
-
40
- ```python
41
- from ask_ai import OpenAI, Anthropic, Google
42
-
43
- prompt = "Explain quantum computing in one sentence."
44
-
45
- # Switch providers instantly
46
- print("OpenAI: ", OpenAI().ask(prompt))
47
- print("Claude: ", Anthropic().ask(prompt))
48
- print("Gemini: ", Google().ask(prompt))
49
- ```
50
-
51
- ---
52
-
53
- ## 📦 Installation
54
-
55
- ```bash
56
- pip install askai-python
57
- ```
58
-
59
- ---
60
-
61
- ## 📖 Quick Start
62
-
63
- ### 1. Setup
64
- Export your API keys (or pass them explicitly).
65
- ```bash
66
- export OPENAI_API_KEY="sk-..."
67
- export ANTHROPIC_API_KEY="sk-ant-..."
68
- ```
69
-
70
- ### 2. Standard Usage
71
- ```python
72
- from ask_ai import OpenAI
73
-
74
- ai = OpenAI()
75
- print(ai.ask("Hello, World!"))
76
- ```
77
-
78
- ### 3. Advanced Usage
79
- Control `temperature`, `top_p`, and system personas for professional results.
80
- ```python
81
- ai.advanced(
82
- temperature=0.7,
83
- prompt="You are a senior DevOps engineer."
84
- )
85
-
86
- print(ai.ask("How do I optimize a Dockerfile?"))
87
- ```
88
-
89
- ---
90
-
91
- ## 🔌 Supported Providers
92
-
93
- | Provider | Class | Feature Set |
94
- |----------|-------|-------------|
95
- | **OpenAI** | `OpenAI` | All Models (GPT-4o, o1, etc.) |
96
- | **Anthropic** | `Anthropic` | All Models (Claude 3.5, Opus) |
97
- | **Google** | `Google` | All Models (Gemini 1.5 Pro/Flash) |
98
- | **Groq** | `Groq` | All Models (Llama 3, Mixtral) |
99
- | **Azure** | `Azure` | All Deployments |
100
- | **OpenRouter**| `OpenRouter`| All Models (100+) |
101
-
102
- ---
103
-
104
- ## ⭐ Support the Project
105
-
106
- If this project saved you time, please consider giving it a star on GitHub! It helps us grow.
107
-
108
- **[Give it a Star!](https://github.com/Hosseinghorbani0/ask-ai)**
109
-
110
- ---
111
- *Built by [Hossein Ghorbani](https://hosseinghorbani0.ir/) | [GitHub](https://github.com/Hosseinghorbani0).*
@@ -1,15 +0,0 @@
1
- class AskAIError(Exception):
2
- """Base exception for all ask-ai errors."""
3
- pass
4
-
5
- class APIKeyError(AskAIError):
6
- """Raised when API key is missing or invalid."""
7
- pass
8
-
9
- class ProviderError(AskAIError):
10
- """Raised when the provider API fails (e.g. 500 error)."""
11
- pass
12
-
13
- class MediaTypeNotSupportedError(AskAIError):
14
- """Raised when a provider can't handle the requested media type."""
15
- pass
@@ -1,135 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: askai-python
3
- Version: 0.1.5
4
- Summary: AI Made Stupid Simple. Unified API for OpenAI, Groq, Google, and more.
5
- Author-email: Hossein Ghorbani <hosseingh1068@gmail.com>
6
- License: MIT
7
- Project-URL: Homepage, https://hosseinghorbani0.ir/
8
- Project-URL: Bug Tracker, https://github.com/Hosseinghorbani0/ask-ai/issues
9
- Requires-Python: >=3.8
10
- Description-Content-Type: text/markdown
11
- License-File: LICENSE
12
- Requires-Dist: openai>=1.0.0
13
- Requires-Dist: groq
14
- Requires-Dist: google-generativeai
15
- Requires-Dist: anthropic
16
- Requires-Dist: requests
17
- Requires-Dist: Pillow
18
- Dynamic: license-file
19
-
20
- # askai-python 🚀
21
-
22
- **AI Made Stupid Simple.** One unified Python client for OpenAI, Claude, Gemini, Groq, and Azure.
23
-
24
- [![PyPI version](https://img.shields.io/pypi/v/askai-python.svg)](https://pypi.org/project/askai-python/)
25
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
26
- [![GitHub](https://img.shields.io/badge/GitHub-View%20Source-blue.svg)](https://github.com/Hosseinghorbani0/ask-ai)
27
-
28
- ---
29
-
30
- ## ⚡ What is askai-python?
31
-
32
- `askai-python` is a lightweight, zero-dependency-logic wrapper that provides a **single API** for all major AI providers. Stop learning multiple SDKs; just call `.ask()` and get your answer.
33
-
34
- - **Unified Interface**: One syntax for OpenAI, Anthropic, Google, and more.
35
- - **Zero-Config**: Seamlessly uses environment variables for API keys.
36
- - **Smart Media**: Easy handling of images and audio (Provider permitting).
37
- - **Production Grade**: Built-in robust error handling and type hints.
38
-
39
- ---
40
-
41
- ## 📦 Installation
42
-
43
- ```bash
44
- pip install askai-python
45
- ```
46
-
47
- ---
48
-
49
- ## 🚀 Examples & Tutorials
50
-
51
- ### 1. Basic Usage (The 3-Line Magic)
52
- ```python
53
- from ask_ai import OpenAI
54
-
55
- ai = OpenAI() # Auto-loads OPENAI_API_KEY from env
56
- print(ai.ask("What is the capital of France?").text)
57
- ```
58
-
59
- ### 2. Multi-Provider Mastery
60
- Switching between top-tier models has never been easier:
61
-
62
- ```python
63
- from ask_ai import OpenAI, Anthropic, Google
64
-
65
- prompt = "Explain quantum computing to a 5-year-old."
66
-
67
- # OpenAI (GPT-4o)
68
- print(OpenAI().ask(prompt).text)
69
-
70
- # Anthropic (Claude 3.5 Sonnet)
71
- print(Anthropic().ask(prompt).text)
72
-
73
- # Google (Gemini 1.5 Pro)
74
- print(Google().ask(prompt).text)
75
- ```
76
-
77
- ### 3. Advanced Configuration (System Personas)
78
- You can set a system prompt and temperature globally for an instance or per-request.
79
-
80
- ```python
81
- from ask_ai import OpenAI
82
-
83
- ai = OpenAI()
84
-
85
- # Global config
86
- ai.advanced(
87
- prompt="You are a sarcastic robot from the year 3000.",
88
- temperature=0.9
89
- )
90
-
91
- print(ai.ask("What is love?").text)
92
-
93
- # Per-request override
94
- print(ai.ask("What is 1+1?", temperature=0.1).text)
95
- ```
96
-
97
- ### 4. Handling Structured Exceptions
98
- Build reliable apps by catching specific AI errors:
99
-
100
- ```python
101
- from ask_ai import OpenAI
102
- from ask_ai.exceptions import AskAIError, APIKeyError
103
-
104
- try:
105
- ai = OpenAI(api_key="invalid-key")
106
- ai.ask("Hello")
107
- except APIKeyError:
108
- print("Check your API keys!")
109
- except AskAIError as e:
110
- print(f"An AI error occurred: {e}")
111
- ```
112
-
113
- ---
114
-
115
- ## 🔌 Supported Providers
116
-
117
- | Provider | Class | Capabilities |
118
- |----------|-------|-------------|
119
- | **OpenAI** | `OpenAI` | Text, Images (DALL-E), Vision |
120
- | **Anthropic** | `Anthropic` | Text, Vision (Claude 3.5) |
121
- | **Google** | `Google` | Text, Images, Video, Audio |
122
- | **Groq** | `Groq` | Ultra-fast Llama 3 & Mixtral |
123
- | **Azure** | `Azure` | Enterprise-grade OpenAI |
124
- | **OpenRouter**| `OpenRouter`| 100+ community models |
125
-
126
- ---
127
-
128
- ## 🔗 Important Links
129
-
130
- - **GitHub Repository**: [Hosseinghorbani0/ask-ai](https://github.com/Hosseinghorbani0/ask-ai) (Star us! ⭐)
131
- - **Official Website**: [hosseinghorbani0.ir](https://hosseinghorbani0.ir/)
132
- - **Bug Tracker**: [Report an Issue](https://github.com/Hosseinghorbani0/ask-ai/issues)
133
-
134
- ---
135
- *Built with ❤️ by [Hossein Ghorbani](https://github.com/Hosseinghorbani0).*
File without changes
File without changes
File without changes