diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..730293e9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,159 @@
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+cover/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+.python-version
+
+# pipenv
+Pipfile.lock
+
+# poetry
+poetry.lock
+
+# pdm
+.pdm.toml
+.pdm-python
+.pdm-build/
+
+# PEP 582
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
+
+# Cython debug symbols
+cython_debug/
+
+# IDEs
+.vscode/
+.idea/
+*.swp
+*.swo
+*~
+.DS_Store
+
+# Backup files
+*.bak
+
+# UV
+.uv/
+uv.lock
+
+# Ruff
+.ruff_cache/
+
+# Security reports
+bandit-report.json
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 00000000..31d00b9b
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,61 @@
+# See https://pre-commit.com for more information
+repos:
+ - repo: https://github.com/pre-commit/pre-commit-hooks
+ rev: v6.0.0
+ hooks:
+ - id: no-commit-to-branch
+ name: "๐ซ Prevent commits to protected branches"
+ args: [--branch, main, --branch, master, --branch, develop]
+ - id: trailing-whitespace
+ - id: end-of-file-fixer
+ - id: check-yaml
+ - id: check-added-large-files
+ - id: check-toml
+ - id: check-merge-conflict
+ - id: check-json
+ - id: debug-statements # Check for print/pdb statements
+
+ - repo: https://github.com/astral-sh/ruff-pre-commit
+ rev: v0.14.3
+ hooks:
+ - id: ruff-check
+ args: [--fix]
+ files: ^(src/celeste|tests)/
+ name: "๐ Lint with Ruff"
+ - id: ruff-format
+ files: ^(src/celeste|tests)/
+ name: "๐ Format with Ruff"
+
+ - repo: local
+ hooks:
+ - id: mypy
+ name: "๐ Type check with mypy"
+ entry: uv run mypy -p celeste
+ language: system
+ types: [python]
+ pass_filenames: false
+ - id: mypy-tests
+ name: "๐ Type check tests with mypy"
+ entry: uv run mypy tests/
+ language: system
+ types: [python]
+ pass_filenames: false
+
+ - repo: https://github.com/PyCQA/bandit
+ rev: 1.8.6
+ hooks:
+ - id: bandit
+ name: "๐ Security check with Bandit"
+ args: ["-c", "pyproject.toml", "-r", "src/"]
+ additional_dependencies: ["bandit[toml]"]
+
+ - repo: local
+ hooks:
+ - id: pytest
+ name: "๐งช Run tests with coverage"
+ entry: uv run pytest tests/ --cov=celeste --cov-report=term-missing
+ language: system
+ types: [python]
+ pass_filenames: false
+ always_run: true
+ stages: [pre-push] # Run on push, not commit (keeps commits fast)
diff --git a/Makefile b/Makefile
new file mode 100644
index 00000000..6e8fbd68
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,79 @@
+.PHONY: help sync lint lint-fix format typecheck test security ci clean
+
+# Default target
+help:
+ @echo "Available commands:"
+ @echo " make sync - Update and sync all dependencies with all extras"
+ @echo " make lint - Run Ruff linting"
+ @echo " make format - Apply Ruff formatting"
+ @echo " make typecheck - Run mypy type checking"
+ @echo " make test - Run pytest with coverage"
+ @echo " make security - Run Bandit security scan"
+ @echo " make ci - Run full CI/CD pipeline"
+ @echo " make clean - Clean cache directories"
+
+# Complete dependency sync - update lock, sync everything
+sync:
+ @echo "๐ Updating dependencies..."
+ @uv sync --all-packages --all-extras --upgrade
+ @echo "โ
All dependencies synced and updated"
+
+# Linting
+lint:
+ uv run ruff check src/celeste tests/
+
+# Linting with auto-fix
+lint-fix:
+ uv run ruff check --fix src/celeste tests/
+
+# Formatting
+format:
+ uv run ruff format src/celeste tests/
+
+# Type checking (fail fast on any error)
+typecheck:
+ @uv run mypy -p celeste && uv run mypy tests/
+
+# Testing
+test:
+ uv run pytest tests/ --cov=celeste --cov-report=term-missing --cov-fail-under=90
+
+# Security scanning (config reads from pyproject.toml)
+security:
+ uv run bandit -c pyproject.toml -r src/ -f screen
+
+# Full CI/CD pipeline - what GitHub Actions will run
+ci:
+ @echo "๐ Running Full CI/CD Pipeline..."
+ @echo "================================="
+ @echo "1๏ธโฃ Ruff Linting (with auto-fix)..."
+ @$(MAKE) lint-fix || (echo "โ Linting failed" && exit 1)
+ @echo "โ
Linting passed"
+ @echo ""
+ @echo "2๏ธโฃ Ruff Formatting..."
+ @$(MAKE) format || (echo "โ Formatting failed" && exit 1)
+ @echo "โ
Formatting applied"
+ @echo ""
+ @echo "3๏ธโฃ MyPy Type Checking (parallel)..."
+ @$(MAKE) typecheck || (echo "โ Type checking failed" && exit 1)
+ @echo "โ
Type checking passed"
+ @echo ""
+ @echo "4๏ธโฃ Bandit Security Scan..."
+ @$(MAKE) security || (echo "โ Security scan failed" && exit 1)
+ @echo "โ
Security scan passed"
+ @echo ""
+ @echo "5๏ธโฃ Running Tests with Coverage..."
+ @$(MAKE) test || (echo "โ Tests failed" && exit 1)
+ @echo ""
+ @echo "================================="
+ @echo "๐ All CI/CD checks passed! Ready to commit."
+
+# Clean cache directories
+clean:
+ rm -rf .pytest_cache
+ rm -rf .mypy_cache
+ rm -rf .ruff_cache
+ rm -rf __pycache__
+ find . -type d -name "__pycache__" -exec rm -rf {} + 2>/dev/null || true
+ find . -type d -name ".pytest_cache" -exec rm -rf {} + 2>/dev/null || true
+ find . -type f -name "*.pyc" -delete
diff --git a/README.md b/README.md
new file mode 100644
index 00000000..eef1cd9b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,134 @@
+
+
+# Celeste AI
+
+

+
+**The primitive layer for multi-modal AI**
+
+All capabilities. All providers. One interface.
+
+Primitives, not frameworks.
+
+[](https://www.python.org/)
+[](LICENSE)
+[](https://pypi.org/project/celeste-ai/)
+
+[Quick Start](#-quick-start) โข [Request Provider](https://github.com/withceleste/celeste-python/issues/new)
+
+
+
+---
+
+## ๐ Quick Start
+
+```python
+from celeste import create_client, Capability, Provider
+
+# Create client
+client = create_client(
+ capability=Capability.TEXT_GENERATION,
+ provider=Provider.ANTHROPIC,
+ api_key="your-api-key", # Or loads automatically from environment
+)
+
+# Generate
+response = await client.generate(prompt="Explain quantum computing")
+print(response.content)
+```
+
+**Install:**
+```bash
+uv add "celeste-ai[text-generation]" # Text only
+uv add "celeste-ai[image-generation]" # Image generation
+uv add "celeste-ai[all]" # Everything
+```
+
+---
+
+## ๐จ Multi-Modal Example
+
+```python
+# Same API, different modalities
+text_client = create_client(Capability.TEXT_GENERATION, Provider.ANTHROPIC)
+image_client = create_client(Capability.IMAGE_GENERATION, Provider.OPENAI)
+video_client = create_client(Capability.VIDEO_GENERATION, Provider.GOOGLE)
+
+text = await text_client.generate(prompt="Write a haiku about AI")
+image = await image_client.generate(prompt="A sunset over mountains")
+video = await video_client.generate(prompt="Waves crashing on a beach")
+```
+
+No special cases. No separate libraries. **One consistent interface.**
+
+---
+
+
+
+
+

+

+

+

+

+

+

+

+

+

+

+

+

+

+

+
+**and many more**
+
+**Missing a provider?** [Request it](https://github.com/withceleste/celeste-python/issues/new) โ โก **we ship fast**.
+
+
+
+---
+
+## ๐ง Type-Safe by Design
+
+```python
+# Full IDE autocomplete
+response = await client.generate(
+ prompt="Explain AI",
+ temperature=0.7, # โ
Validated (0.0-2.0)
+ max_tokens=100, # โ
Validated (int)
+)
+
+# Typed response
+print(response.content) # str (IDE knows the type)
+print(response.usage.input_tokens) # int
+print(response.metadata["model"]) # str
+```
+
+Catch errors **before** production.
+
+---
+
+## ๐ค Contributing
+
+We welcome contributions! See [CONTRIBUTING.md](CONTRIBUTING.md).
+
+**Request a provider:** [GitHub Issues](https://github.com/withceleste/celeste-python/issues/new)
+**Report bugs:** [GitHub Issues](https://github.com/withceleste/celeste-python/issues)
+
+---
+
+## ๐ License
+
+Apache 2.0 license โ see [LICENSE](LICENSE) for details.
+
+---
+
+
+
+**[Get Started](https://withceleste.ai/docs/quickstart)** โข **[Documentation](https://withceleste.ai/docs)** โข **[GitHub](https://github.com/withceleste/celeste-python)**
+
+Made with โค๏ธ by developers tired of framework lock-in
+
+
diff --git a/logo.svg b/logo.svg
new file mode 100644
index 00000000..2703d56b
--- /dev/null
+++ b/logo.svg
@@ -0,0 +1,11 @@
+
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 00000000..8499ac44
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,150 @@
+[project]
+name = "celeste-ai"
+version = "0.0.2"
+description = "Open source, type-safe primitives for multi-modal AI. All capabilities, all providers, one interface"
+authors = [{name = "Kamilbenkirane", email = "kamil@withceleste.ai"}]
+readme = "README.md"
+license = {text = "Apache-2.0"}
+requires-python = ">=3.12"
+classifiers = [
+ "Development Status :: 3 - Alpha",
+ "Intended Audience :: Developers",
+ "License :: OSI Approved :: Apache Software License",
+ "Programming Language :: Python :: 3",
+ "Programming Language :: Python :: 3.12",
+ "Programming Language :: Python :: 3.13",
+ "Operating System :: OS Independent",
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
+ "Typing :: Typed",
+]
+keywords = ["ai", "multimodal", "sdk", "openai", "anthropic", "claude", "gemini", "text-generation", "image-generation", "video-generation", "embeddings"]
+dependencies = [
+ "pydantic>=2.0",
+ "pydantic-settings>=2.0",
+ "httpx>=0.27.0",
+ "httpx-sse>=0.4.0",
+ "python-dotenv>=1.0.0",
+]
+
+[project.urls]
+Homepage = "https://withceleste.ai"
+Documentation = "https://withceleste.ai/docs"
+Repository = "https://github.com/withceleste/celeste-python"
+Issues = "https://github.com/withceleste/celeste-python/issues"
+
+[dependency-groups]
+dev = [
+ "pytest>=8.0",
+ "pytest-cov>=7.0",
+ "pytest-randomly>=4.0",
+ "pytest-asyncio>=1.2.0",
+ "ruff>=0.8.0",
+ "mypy>=1.13.0",
+ "types-requests>=2.31.0",
+ "bandit[toml]>=1.7.5",
+ "pre-commit>=3.5.0",
+]
+
+[project.entry-points."celeste.packages"]
+# Example entry points for packages to register their models and clients:
+# text_generation = "text_generation:register_models"
+# image_generation = "image_generation:register_models"
+
+[tool.uv.workspace]
+members = ["packages/*"]
+
+[build-system]
+requires = ["hatchling"]
+build-backend = "hatchling.build"
+
+[tool.hatch.build.targets.wheel]
+packages = ["src/celeste"]
+
+[tool.pytest.ini_options]
+minversion = "8.0"
+testpaths = ["tests"]
+addopts = "-ra --strict-markers --strict-config"
+asyncio_mode = "auto"
+markers = [
+ "slow: marks tests as slow (deselect with '-m \"not slow\"')",
+ "smoke: quick checks for critical paths",
+]
+
+[tool.coverage.run]
+branch = true
+# dynamic_context handled by pytest-cov's --cov-context option
+
+[tool.coverage.report]
+show_missing = true
+fail_under = 90
+
+[tool.ruff]
+# Same as Black's default
+line-length = 88
+target-version = "py312"
+
+[tool.ruff.lint]
+select = [
+ "E", # pycodestyle errors
+ "F", # Pyflakes (unused imports, undefined names)
+ "I", # isort (import sorting)
+ "UP", # pyupgrade (upgrade syntax for newer Python)
+ "B", # flake8-bugbear (catches common bugs)
+ "SIM", # flake8-simplify (code simplification)
+ "RUF", # Ruff-specific rules
+ "ANN", # flake8-annotations (enforce type annotations)
+ "A", # flake8-builtins (prevent shadowing builtins)
+]
+ignore = [
+ "E501", # Line too long - trust formatter's judgment
+ "SIM108", # Use ternary operator instead of if-else-block (sometimes less readable)
+]
+fixable = ["ALL"]
+unfixable = []
+
+[tool.ruff.format]
+# Match Black's style
+quote-style = "double"
+indent-style = "space"
+docstring-code-format = true
+
+[tool.ruff.lint.isort]
+known-first-party = ["celeste"]
+
+[tool.ruff.lint.per-file-ignores]
+"tests/*" = ["D"] # No docstrings required in tests
+
+[tool.mypy]
+python_version = "3.12"
+mypy_path = "src"
+# Strict type checking for production code
+warn_return_any = true
+warn_unused_configs = true
+disallow_untyped_defs = true # Require type hints
+disallow_any_unimported = true
+disallow_incomplete_defs = true
+check_untyped_defs = true
+no_implicit_optional = true
+warn_redundant_casts = true
+warn_unused_ignores = true
+strict_equality = true
+
+[[tool.mypy.overrides]]
+module = "tests.*"
+disallow_untyped_defs = false # Relax for tests
+disallow_incomplete_defs = false
+
+[[tool.mypy.overrides]]
+module = "httpx"
+ignore_missing_imports = true
+
+[[tool.mypy.overrides]]
+module = "httpx_sse"
+ignore_missing_imports = true
+
+[tool.bandit]
+exclude_dirs = [".venv", "__pycache__"]
+skips = ["B101"] # Skip B101 (assert_used) since we use pytest
+
+[tool.bandit.assert_used]
+skips = ["*/test_*.py", "*_test.py"] # Allow assertions in test files