Skip to content

Commit 0c95775

Browse files
committed
feat: added aistudio support
0 parents  commit 0c95775

14 files changed

Lines changed: 1152 additions & 0 deletions

File tree

.gitignore

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# --- General ---
2+
.DS_Store
3+
.vscode/
4+
.idea/
5+
*.log
6+
*.png
7+
8+
# --- Python ---
9+
__pycache__/
10+
*.py[cod]
11+
*$py.class
12+
*.so
13+
.Python
14+
build/
15+
develop-eggs/
16+
dist/
17+
downloads/
18+
eggs/
19+
.eggs/
20+
lib/
21+
lib64/
22+
parts/
23+
sdist/
24+
var/
25+
wheels/
26+
*.egg-info/
27+
.installed.cfg
28+
*.egg
29+
MANIFEST
30+
.env
31+
venv/
32+
env/
33+
ENV/
34+
.venv/
35+
36+
# --- Verification ---
37+
verify_aistudio.py
38+
verify_flow.py
39+
40+
# --- Playwright ---
41+
test-results/
42+
playwright-report/
43+
blob-report/
44+
playwright/.cache/
45+
46+
# --- OS Generated ---
47+
Thumbs.db
48+
ehthumbs.db
49+
Desktop.ini

CONTRIBUTING.md

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# Contributing to LLMSession
2+
3+
Thank you for your interest in contributing to **LLMSession**! This project is a monorepo containing both the Python and Node.js implementations. We welcome contributions to either (or both) parts of the library.
4+
5+
## 1. Project Structure
6+
7+
* **`python/`**: Contains the Python source code and packaging config.
8+
* **`node/`**: Contains the TypeScript source code and NPM config.
9+
10+
Please ensure you are working in the correct subdirectory for your changes.
11+
12+
## 2. Python Development
13+
14+
### Setup
15+
1. Navigate to the python directory: `cd python`
16+
2. Create a virtual environment (optional but recommended):
17+
```bash
18+
python -m venv venv
19+
source venv/bin/activate # Linux/Mac
20+
# or
21+
.\venv\Scripts\activate # Windows
22+
```
23+
3. Install the package in **Editable Mode**:
24+
```bash
25+
pip install -e .
26+
```
27+
*This allows you to modify code in `src/` and test it immediately without reinstalling.*
28+
29+
### Testing
30+
We use a manual verification script to test the full flow (Browser launch -> Auth -> Prompt).
31+
```bash
32+
python verify_flow.py
33+
```
34+
*Tip: You can modify `verify_flow.py` to use `headless=False` to watch the bot work.*
35+
36+
## 3. Node.js Development
37+
38+
### Setup
39+
1. Navigate to the node directory: `cd node`
40+
2. Install dependencies:
41+
```bash
42+
npm install
43+
```
44+
45+
### Building
46+
Since this is a TypeScript project, you must compile the code.
47+
* **One-off build**:
48+
```bash
49+
npm run build
50+
```
51+
* **Watch mode (Recommended for Dev)**:
52+
```bash
53+
npx tsc -w
54+
```
55+
*Keep this running in a separate terminal to auto-compile changes.*
56+
57+
### Testing
58+
To run the verification flow using `ts-node` (skips build step) or the compiled dist:
59+
```bash
60+
# Run directly from TypeScript source
61+
npx ts-node verify_flow.ts
62+
```
63+
64+
## 4. Safety Warning (Credentials)
65+
66+
To test changes, you will likely need to put real credentials into `verify_flow.py` or `verify_flow.ts`.
67+
68+
> [!CAUTION]
69+
> **NEVER commit files containing your real passwords.**
70+
> If you modify the verification scripts with real credentials, please revert those changes before pushing, or ensure they are ignored.
71+
72+
## 5. Pull Request Process
73+
74+
1. **Fork & Clone**: Fork the repo and clone it locally.
75+
2. **Branch**: Create a feature branch (`git checkout -b feature/amazing-feature`).
76+
3. **Code**: Implement your changes.
77+
* **Python**: Adhere to PEP 8.
78+
* **Node**: Adhere to standard ESLint/Prettier conventions.
79+
4. **Verify**: Run the verification scripts in both languages if your change affects shared logic (like selectors).
80+
5. **Commit**: Use descriptive commit messages.
81+
6. **Push & PR**: Push to your fork and open a Pull Request against `main`.
82+
83+
## 6. Adding New Selectors
84+
85+
If you are fixing a broken selector because ChatGPT updated their UI:
86+
1. Update `python/src/llm_session/providers/chatgpt.py`
87+
2. Update `node/src/providers/ChatGPT.ts`
88+
3. **Please update both** if possible to keep the libraries in sync.
89+
90+
## License
91+
92+
By contributing, you agree that your contributions will be licensed under the MIT License.

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
# LLMSession
2+
3+
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
4+
[![PyPI version](https://badge.fury.io/py/llm-session.svg)](https://pypi.org/project/llm-session/)
5+
[![npm version](https://badge.fury.io/js/llm-session.svg)](https://www.npmjs.com/package/llm-session)
6+
7+
A zero-configuration tool to automate interactions with web-based LLM providers (currently ChatGPT). It handles authentication, session persistence, and chained prompt execution programmatically.
8+
9+
## Features
10+
- **Zero-Config Setup**: Automatically handles browser binaries via Playwright.
11+
- **Session Persistence**: Reuses cookies/storage for subsequent runs (no need to login every time).
12+
- **Cross-Language Sharing**: Sessions are shared between Python and Node.js environments automatically.
13+
- **Smart OTP Handling**: Supports non-blocking callbacks for 2FA/OTP challenges.
14+
- **Resilient**: Allows custom CSS selectors to adapt to UI changes without updating the library.
15+
16+
## Prerequisites
17+
You must set the following environment variables, or pass them directly to the constructor:
18+
- `CHATGPT_EMAIL`
19+
- `CHATGPT_PASSWORD`
20+
- `CHATGPT_GOOGLE_LOGIN` (Optional: set to "true" if using Google Auth. *Note: Google Auth is experimental and may require manual intervention.*)
21+
22+
## Disclaimer
23+
> [!WARNING]
24+
> **Cloudflare/Bot Detection**: Automated interactions with ChatGPT are subject to high-security bot detection (Cloudflare). This library uses standard browser automation and may be blocked. For production reliability, please use the Official OpenAI API.
25+
26+
This tool automates a third-party web interface. It is subject to breakage if the target website changes its DOM structure. Use responsibly and in accordance with the provider's Terms of Service.
27+
28+
---
29+
30+
## Python Usage
31+
32+
### Installation
33+
```bash
34+
pip install llm-session
35+
```
36+
37+
### Quick Start
38+
```python
39+
import logging
40+
from llm_session import Automator
41+
42+
# 1. Configure Standard Logging
43+
logging.basicConfig(level=logging.INFO)
44+
45+
# 2. Define OTP Callback (Optional, but recommended for headless envs)
46+
def my_otp_handler():
47+
# In production, you might fetch this from an email API
48+
return input("Enter OTP Code sent to email: ")
49+
50+
# 3. Initialize
51+
bot = Automator(
52+
provider="chatgpt",
53+
headless=False, # Set to True for production (CURRENTLY ONLY WORKS WITH headless=False)
54+
credentials={
55+
"email": "your_email@example.com",
56+
"password": "your_password",
57+
"method": "email" # or "google"
58+
},
59+
on_otp_required=my_otp_handler
60+
)
61+
62+
# 4. Single Prompt
63+
print(bot.process_prompt("Hello, world!"))
64+
65+
# 5. Chained Prompt (Inject previous response)
66+
chain = [
67+
"Write a haiku about Python.",
68+
"Translate this haiku to Spanish: {{previous}}"
69+
]
70+
responses = bot.process_chain(chain)
71+
print(responses)
72+
73+
bot.close()
74+
```
75+
76+
---
77+
78+
## Node.js Usage
79+
80+
### Installation
81+
```bash
82+
npm install llm-session
83+
```
84+
85+
### Quick Start
86+
```typescript
87+
import { Automator } from 'llm-session';
88+
89+
async function main() {
90+
// 1. Define OTP Callback
91+
const onOtpRequired = async () => {
92+
console.log("Please check your email for code.");
93+
// Return code from your logic here
94+
return "123456";
95+
};
96+
97+
// 2. Initialize
98+
const bot = new Automator(
99+
"chatgpt",
100+
false, // headless
101+
{
102+
email: "your_email@example.com",
103+
password: "your_password"
104+
},
105+
undefined, // sessionPath (optional)
106+
{
107+
onOtpRequired: onOtpRequired,
108+
// Optional: Inject your own logger (e.g., Winston, Pino)
109+
// logger: myLoggerInstance
110+
}
111+
);
112+
113+
try {
114+
await bot.init();
115+
116+
const response = await bot.processPrompt("Hello from Node.js!");
117+
console.log(response);
118+
119+
} finally {
120+
await bot.close();
121+
}
122+
}
123+
main();
124+
```
125+
126+
---
127+
128+
## Advanced Configuration (Resilience)
129+
130+
Websites change their layout often. If ChatGPT updates their CSS class names, you don't need to wait for a package update. You can inject your own selectors during initialization.
131+
132+
**Python:**
133+
```python
134+
bot = Automator(
135+
provider="chatgpt",
136+
config={
137+
"selectors": {
138+
"textarea": "#new-prompt-id",
139+
"send_btn": ".new-send-button-class",
140+
"assistant_msg": ".new-message-wrapper"
141+
}
142+
}
143+
)
144+
```
145+
146+
**Node.js:**
147+
```typescript
148+
const bot = new Automator("chatgpt", true, undefined, undefined, {
149+
selectors: {
150+
textarea: "#new-prompt-id",
151+
send_btn: ".new-send-button-class"
152+
}
153+
});
154+
```
155+
156+
## Session Management
157+
This library stores browser cookies and local storage in your OS's standard user data directory (e.g., `%LOCALAPPDATA%/LLMSession` on Windows, `~/.local/share/LLMSession` on Linux).
158+
159+
* **Cross-Language:** If you login using the Python script, the Node.js script will automatically detect the existing session and skip login (and vice-versa).
160+
* **Persistence:** Sessions persist across reboots.
161+
162+
## Contributing
163+
We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines on how to build the project locally.
164+
165+
## License
166+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

pyproject.toml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
[build-system]
2+
requires = ["setuptools>=61.0"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[project]
6+
name = "llm_session"
7+
version = "0.1.3"
8+
description = "A zero-configuration tool to automate web-based LLM interactions."
9+
readme = "README.md"
10+
authors = [{ name = "LLM_Session", email = "shoaib.star.a@gmail.com" }]
11+
license = { text = "MIT" }
12+
classifiers = [
13+
"Programming Language :: Python :: 3",
14+
"License :: OSI Approved :: MIT License",
15+
"Operating System :: OS Independent",
16+
]
17+
dependencies = [
18+
"playwright>=1.30.0",
19+
"appdirs>=1.4.4",
20+
]
21+
requires-python = ">=3.8"
22+
23+
[project.urls]
24+
"Homepage" = "https://github.com/star-173/llm_session"
25+
26+
[tool.setuptools.packages.find]
27+
where = ["src"]
28+
exclude = ["tests*", "node_modules*", "dist*", "build*"]

src/llm_session/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from .automator import Automator
2+
3+
__all__ = ["Automator"]

0 commit comments

Comments
 (0)