Skip to main content

🤖 AiChatClient

Build and manage AI assistants your own way

دستیار هوش مصنوعی خودت را بساز

PyPI Python Downloads OpenAI Compatible Flask

🌐 Language / زبان:   🇬🇧 English  |  🇮🇷 فارسی

pip install aichatclient

🇬🇧 English

AiChatClient is a Python toolkit for building custom assistant workflows on top of OpenAI-compatible chat APIs. You control the assistant's identity, instructions, reference data, memory, and saved configuration, in plain Python or through the bundled Flask web chat.

✨ Features

Feature What you get
💾 Saved configurations Create, load, list, rename, and delete assistants
🔌 Any compatible provider Any OpenAI-compatible base_url + model name
🎭 Assistant behavior System prompt, personality, expertise, limitations
🧠 Conversation memory Messages persisted in SQLite and reused as context
📚 Reference datasets .txt, .json, .jsonl with keyword-based matching
🗂️ Multiple conversations Separate conversation_id, history inspection and cleanup
🌐 Web interface Flask-based ChatApp

Scope. AiChatClient is a foundation for assistant workflows. It does not include autonomous task execution, built-in external tools, semantic/vector search, or an agent planner. Implement those in your application.

📦 Install

pip install aichatclient
python -m pip install --upgrade aichatclient   # upgrade

Requirements: a supported Python version (see package metadata), an API key, an OpenAI-compatible endpoint, and network access to it. The openai SDK and Flask are installed automatically.

🚀 Quick start

export AICUSTOM_API_KEY="your-api-key"      # PowerShell: $env:AICUSTOM_API_KEY = "your-api-key"
import os
from aichatclient import AICustom

assistant = AICustom(
    api_key=os.environ["AICUSTOM_API_KEY"],
    base_url="https://api.example.com/v1",
    model_name="provider/model-name",
    nickname="my_assistant",
    system_prompt="You are a helpful programming assistant.",
)
assistant.create_model()        # saves the config (the API key is NEVER saved)

print(assistant.chat("Hello! What can you help me with?"))

for m in assistant.get_history(limit=10):
    print(m["role"], m["content"])

Next time, just load it:

assistant = AICustom.load_model("my_assistant")   # key from AICUSTOM_API_KEY

🧩 Core classes

Class Role
AICustom Configuration, chat, memory, datasets, model management. Use it for everything.
AiClient Thin wrapper: load a saved model, chat, read history. Underlying model: client.ai.
ChatApp Flask web chat around an AICustom instance.

🛠️ Create an assistant

assistant = AICustom(
    api_key=api_key,
    base_url="https://api.example.com/v1",
    model_name="provider/model-name",
    nickname="python_mentor",
    system_prompt="You are a Python mentor. Explain accurately with small examples.",
    personality="Patient, clear, and practical",
    expertise="Python programming",
    limitations="If uncertain, say so.",
    memory=True,
    conversation_id="learning-session-1",
)
assistant.create_model()
Parameter Default Description
api_key required Provider key, used at runtime, never saved
base_url required OpenAI-compatible API base URL
model_name required Model identifier sent to the provider
nickname required Local name (letters, digits, _, -, .)
system_prompt "" Role and response instructions
model_provider / model_version / author "" Descriptive metadata
personality / expertise / limitations None Merged into the system message
dataset None Path to .txt / .json / .jsonl
memory True Store messages and reuse recent history
conversation_id "default" Keeps conversations separate
storage_dir None Storage root
timeout 60.0 Seconds (> 0)
max_retries 2 SDK retries (≥ 0)
history_limit 40 Max recent messages used as context (≥ 1)
extra_model_params None e.g. {"temperature": 0.4}; cannot override model/messages
model_id auto UUID Stable instance identifier

💬 Load and chat

assistant = AICustom.load_model(
    "my_assistant",
    api_key=api_key,                       # optional if AICUSTOM_API_KEY is set
    conversation_id="support-session-42",  # overrides apply to this instance only
    timeout=90,
)

assistant.chat("Explain Python decorators.")
assistant.chat("What is a decorator?", short=True)   # brief, direct reply

Overrides don't change the saved file; call create_model() to persist them. Lightweight wrapper:

from aichatclient.aiclient import AiClient

client = AiClient.load_model(name="my_assistant", api_key=api_key)
client.chat("Lists vs tuples?")
client.get_history(limit=25)

🧠 Memory & history

assistant.get_history(limit=20)                         # current model + conversation
AICustom.list_history(nickname="my_assistant",
                      conversation_id="default", limit=100)
assistant.clear_history()                               # returns deleted row count
AICustom.clear_all_history(nickname="my_assistant",
                           conversation_id="support-session-42")

⚠️ AICustom.clear_all_history() with no filters deletes every message in the database. Config files are not affected.

  • Separate conversations: use a different conversation_id per user/session. IDs are labels, not access control.
  • Disable memory: memory=False. Nothing is sent from history or saved; existing history stays.

📚 Reference datasets

assistant = AICustom(
    api_key=api_key,
    base_url="https://api.example.com/v1",
    model_name="provider/model-name",
    nickname="product_helper",
    system_prompt="Answer using the supplied product data.",
    dataset="data/products.jsonl",
)

Simple token-overlap matching adds up to five matching lines (within a context-size limit) to the system message. It is not embedding search, a vector DB, or fine-tuning.

🗃️ Manage saved models

assistant.create_model()                              # save non-secret config
AICustom.list_models(storage_dir="./assistant_data")  # sorted names
AICustom.delete_model("my_assistant")                 # config only; history is kept
assistant.rename_model("support_assistant")           # FileExistsError if taken

🌐 Web chat

from aichatclient import AICustom, ChatApp

ai = AICustom.load_model("my_assistant")
ChatApp(ai=ai).run(host="127.0.0.1", port=5000, debug=False)

Open http://127.0.0.1:5000. Keep host="127.0.0.1" and debug=False unless you have deliberately secured the deployment.

📁 Storage & environment variables

.ai_custom/
├── configs/<nickname>.json      # non-secret configuration
├── databases/history.sqlite3    # conversation history
├── datasets/
└── logs/
Variable Purpose
AICUSTOM_HOME Default storage root (storage_dir takes precedence)
AICUSTOM_API_KEY Default key for AICustom.load_model()

🧯 Errors & troubleshooting

Exception Typical cause
ValueError Empty required text, invalid options, missing API key, bad dataset
TypeError Wrong parameter type (e.g. non-boolean memory)
FileNotFoundError Saved model or dataset not found
FileExistsError Rename target already exists
RuntimeError API returned no choices or text
  • Missing API key: pass api_key= or set AICUSTOM_API_KEY. Keys are never stored, so each process needs one.
  • Model not found: check AICustom.list_models() and the same storage_dir / AICUSTOM_HOME.
  • Empty history: history is per model and conversation_id; check memory=True.
  • Provider rejects a request: remove unsupported extra_model_params; verify base_url and model_name.

🔐 Security

  1. Never hard-code or commit API keys. If a key was ever exposed, revoke it and create a new one.
  2. Don't commit .ai_custom/, history databases, or private datasets.
  3. Protect the storage directory; history may contain sensitive data.
  4. Authenticate and authorize users in your own app.
  5. Treat dataset files as untrusted input.
  6. Use HTTPS endpoints.
  7. Double-check the scope before clear_all_history().

🇮🇷 فارسی

AiChatClient یک ابزار پایتونی برای ساخت دستیارهای هوش مصنوعی سفارشی روی APIهای چت سازگار با OpenAI است. هویت دستیار، دستورالعمل‌ها، داده‌های مرجع، حافظه و تنظیمات ذخیره‌شده دست خودت است. هم در کد پایتون کار می‌کند و هم با رابط وب Flask که همراه بسته است.

✨ ویژگی‌ها

ویژگی توضیح
💾 تنظیمات ذخیره‌شده ساخت، بارگذاری، فهرست، تغییر نام و حذف دستیار
🔌 هر سرویس‌دهنده سازگار هر base_url سازگار با OpenAI به‌همراه نام مدل
🎭 رفتار دستیار پرامپت سیستمی، شخصیت، تخصص و محدودیت‌ها
🧠 حافظه گفتگو ذخیره پیام‌ها در SQLite و استفاده مجدد به‌عنوان زمینه
📚 دیتاست مرجع فایل‌های .txt و .json و .jsonl با تطبیق کلیدواژه‌ای
🗂️ چند گفتگوی مستقل conversation_id جدا، مشاهده و پاک‌سازی تاریخچه
🌐 رابط وب ChatApp مبتنی بر Flask

دامنه کار: AiChatClient پایه‌ای برای ساخت دستیار است. اجرای خودکار کارها، ابزارهای بیرونی داخلی، جست‌وجوی معنایی (برداری) و برنامه‌ریز عامل (Agent) ندارد. این‌ها را باید در برنامه‌ی خودت پیاده کنی.

📦 نصب

pip install aichatclient
python -m pip install --upgrade aichatclient   # به‌روزرسانی

پیش‌نیازها: نسخه‌ی پشتیبانی‌شده‌ی پایتون (در متادیتای بسته ببین)، یک کلید API، یک endpoint سازگار با OpenAI و دسترسی شبکه به آن. کتابخانه‌ی openai و Flask خودکار نصب می‌شوند.

🚀 شروع سریع

ابتدا کلید را در متغیر محیطی بگذار (نه داخل کد):

export AICUSTOM_API_KEY="your-api-key"      # PowerShell: $env:AICUSTOM_API_KEY = "your-api-key"
import os
from aichatclient import AICustom

assistant = AICustom(
    api_key=os.environ["AICUSTOM_API_KEY"],
    base_url="https://api.example.com/v1",
    model_name="provider/model-name",
    nickname="my_assistant",
    system_prompt="تو یک دستیار برنامه‌نویسی مفید هستی.",
)
assistant.create_model()        # تنظیمات ذخیره می‌شود (کلید API هرگز ذخیره نمی‌شود)

print(assistant.chat("سلام! چه کمکی از تو برمی‌آید؟"))

for m in assistant.get_history(limit=10):
    print(m["role"], m["content"])

دفعه‌ی بعد فقط بارگذاری کن:

assistant = AICustom.load_model("my_assistant")   # کلید از AICUSTOM_API_KEY خوانده می‌شود

🧩 کلاس‌های اصلی

کلاس نقش
AICustom تنظیمات، چت، حافظه، دیتاست و مدیریت مدل‌ها. برای همه‌چیز از همین استفاده کن.
AiClient پوشش سبک: بارگذاری مدل ذخیره‌شده، چت و خواندن تاریخچه. مدل اصلی: client.ai
ChatApp چت وب مبتنی بر Flask روی یک نمونه‌ی AICustom

🛠️ ساخت دستیار

پارامتر پیش‌فرض توضیح
api_key الزامی کلید سرویس‌دهنده؛ فقط هنگام اجرا استفاده می‌شود و ذخیره نمی‌شود
base_url الزامی آدرس پایه‌ی API سازگار با OpenAI
model_name الزامی شناسه‌ی مدل
nickname الزامی نام محلی (حروف، عدد، _ و - و .)
system_prompt "" نقش و دستورالعمل پاسخ‌گویی
model_provider / model_version / author "" اطلاعات توصیفی
personality / expertise / limitations None به پیام سیستمی اضافه می‌شوند
dataset None مسیر فایل .txt یا .json یا .jsonl
memory True ذخیره‌ی پیام‌ها و استفاده از تاریخچه‌ی اخیر
conversation_id "default" جداسازی گفتگوها
storage_dir None پوشه‌ی ریشه‌ی ذخیره‌سازی
timeout 60.0 ثانیه (بزرگ‌تر از صفر)
max_retries 2 تعداد تلاش مجدد (≥ ۰)
history_limit 40 حداکثر پیام اخیر در زمینه (≥ ۱)
extra_model_params None مثلاً {"temperature": 0.4}؛ نمی‌تواند model و messages را بازنویسی کند
model_id UUID خودکار شناسه‌ی پایدار نمونه

فیلدهای شخصیت و تخصص مدل را راهنمایی می‌کنند، اما جایگزین اعتبارسنجی، احراز هویت و کنترل‌های ایمنی در برنامه‌ی تو نیستند.

💬 بارگذاری و چت

assistant = AICustom.load_model(
    "my_assistant",
    api_key=api_key,                       # اگر AICUSTOM_API_KEY تنظیم باشد اختیاری است
    conversation_id="support-session-42",  # فقط روی همین نمونه اعمال می‌شود
    timeout=90,
)

assistant.chat("دکوراتور در پایتون چیست؟")
assistant.chat("دکوراتور چیست؟", short=True)   # پاسخ کوتاه و مستقیم

مقادیر override فایل ذخیره‌شده را تغییر نمی‌دهند؛ برای ماندگار کردن آن‌ها create_model() را صدا بزن. نسخه‌ی سبک:

from aichatclient import AiClient

client = AiClient.load_model(name="my_assistant", api_key=api_key)
client.chat("تفاوت list و tuple چیست؟")
client.get_history(limit=25)

🧠 حافظه و تاریخچه

assistant.get_history(limit=20)                         # مدل و گفتگوی فعلی
AICustom.list_history(nickname="my_assistant",
                      conversation_id="default", limit=100)
assistant.clear_history()                               # تعداد ردیف‌های حذف‌شده را برمی‌گرداند
AICustom.clear_all_history(nickname="my_assistant",
                           conversation_id="support-session-42")

⚠️ هشدار: AICustom.clear_all_history() بدون فیلتر، همه‌ی پیام‌های دیتابیس را پاک می‌کند. فایل‌های تنظیمات دست‌نخورده می‌مانند.

  • گفتگوهای جدا: برای هر کاربر یا نشست یک conversation_id متفاوت بده. این شناسه فقط برچسب است، نه کنترل دسترسی.
  • خاموش کردن حافظه: با memory=False نه تاریخچه به مدل می‌رسد و نه پیام جدیدی ذخیره می‌شود. تاریخچه‌ی قبلی حذف نمی‌شود.

📚 دیتاست مرجع

assistant = AICustom(
    api_key=api_key,
    base_url="https://api.example.com/v1",
    model_name="provider/model-name",
    nickname="product_helper",
    system_prompt="فقط بر اساس داده‌های محصول پاسخ بده.",
    dataset="data/products.jsonl",
)

با یک تطبیق ساده‌ی هم‌پوشانی کلمات، حداکثر پنج خط مرتبط (در محدوده‌ی اندازه‌ی زمینه) به پیام سیستمی اضافه می‌شود. این روش جست‌وجوی معنایی، دیتابیس برداری یا فاین‌تیون نیست.

🗃️ مدیریت مدل‌های ذخیره‌شده

assistant.create_model()                              # ذخیره‌ی تنظیمات غیرمحرمانه
AICustom.list_models(storage_dir="./assistant_data")  # فهرست مرتب‌شده‌ی نام‌ها
AICustom.delete_model("my_assistant")                 # فقط تنظیمات؛ تاریخچه می‌ماند
assistant.rename_model("support_assistant")           # اگر نام تکراری باشد FileExistsError

🌐 چت وب

from aichatclient import AICustom, ChatApp

ai = AICustom.load_model("my_assistant")
ChatApp(ai=ai).run(host="127.0.0.1", port=5000, debug=False)

آدرس http://127.0.0.1:5000 را باز کن. مگر اینکه استقرار را عمداً امن کرده باشی، host="127.0.0.1" و debug=False را نگه دار.

📁 ذخیره‌سازی و متغیرهای محیطی

.ai_custom/
├── configs/<nickname>.json      # تنظیمات غیرمحرمانه
├── databases/history.sqlite3    # تاریخچه‌ی گفتگو
├── datasets/
└── logs/
متغیر کاربرد
AICUSTOM_HOME پوشه‌ی پیش‌فرض ذخیره‌سازی (آرگومان storage_dir اولویت دارد)
AICUSTOM_API_KEY کلید پیش‌فرض برای AICustom.load_model()

🧯 خطاها و رفع اشکال

استثنا علت معمول
ValueError متن الزامی خالی، گزینه‌ی نامعتبر، نبود کلید API، دیتاست نامعتبر
TypeError نوع پارامتر اشتباه (مثلاً memory غیر بولی)
FileNotFoundError مدل ذخیره‌شده یا فایل دیتاست پیدا نشد
FileExistsError نام مقصد در تغییر نام از قبل وجود دارد
RuntimeError API پاسخ یا متنی برنگرداند
  • کلید API پیدا نشد: api_key= بده یا AICUSTOM_API_KEY را تنظیم کن. کلید هرگز ذخیره نمی‌شود، پس هر پردازش جدید به آن نیاز دارد.
  • مدل پیدا نشد: AICustom.list_models() را بررسی کن و مطمئن شو storage_dir یا AICUSTOM_HOME همان است که هنگام ذخیره بود.
  • تاریخچه خالی است: تاریخچه به مدل و conversation_id وابسته است؛ memory=True را هم چک کن.
  • سرویس‌دهنده درخواست را رد می‌کند: پارامترهای پشتیبانی‌نشده را از extra_model_params حذف کن و base_url و model_name را بررسی کن.

🔐 امنیت

  1. کلید API را هرگز در کد نگذار و commit نکن. اگر کلیدی لو رفته، همان لحظه آن را باطل (revoke) و کلید جدید بساز.
  2. پوشه‌ی .ai_custom/، دیتابیس تاریخچه و دیتاست‌های خصوصی را commit نکن.
  3. پوشه‌ی ذخیره‌سازی را محافظت کن؛ تاریخچه ممکن است اطلاعات حساس داشته باشد.
  4. احراز هویت و سطح دسترسی کاربران را در برنامه‌ی خودت پیاده کن.
  5. فایل‌های دیتاست را ورودی غیرقابل‌اعتماد در نظر بگیر.
  6. از endpointهای HTTPS استفاده کن.
  7. پیش از clear_all_history() دامنه‌ی حذف را دوباره بررسی کن.

📄 License: see the GitHub repository  |  مجوز: به مخزن گیت‌هاب مراجعه کنید

Metadata

Release files for aichatclient 4.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for aichatclient 4.1.0
File Size Uploaded Provenance Actions
aichatclient-4.1.0.tar.gz 30.9 kB Without provenance Details for aichatclient-4.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for aichatclient 4.1.0
File Interpreter ABI Platform Actions
aichatclient-4.1.0-py3-none-any.whl Python 3 none any Details for aichatclient-4.1.0-py3-none-any.whl

Total release size: 54.9 kB

Release files / aichatclient-4.1.0.tar.gz

Download URL aichatclient-4.1.0.tar.gz
Size 30.9 kB
Tags Source
SHA-256 checksum
How to use checksums
a5d6b7f9157d8533e78bd157b9744e8822114420d7c7e827fff3eea7464e03f3
BLAKE2b-256 checksum
How to use checksums
ba2267c333bac00dbcc8de59f341a801adcea0fff3d9a9f41c0ad8a040d9e779
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Release files / aichatclient-4.1.0-py3-none-any.whl

Download URL aichatclient-4.1.0-py3-none-any.whl
Size 24.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
55e8a753af98c351f6d232214e0d5fb16335af34802113a94abb7d37659bcbe1
BLAKE2b-256 checksum
How to use checksums
4c5ea13a4b518cda850f7bad20e0e7fa7d07dff8a0df791f84329df952cfba19
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.10

Security for aichatclient 4.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page