Skip to content

Commit ae5bde1

Browse files
bojielicursoragent
andcommitted
Prepare for 0.1.0 release: add ruff, fix CI, unit tests, and changelog
- Add ruff linter to dev dependencies with config in pyproject.toml - Create py.typed PEP 561 marker file (was declared but missing) - Remove || echo fallback so CI properly fails on test failures - Add basic unit tests covering exports, errors, and event constants - Add pytest asyncio_mode config - Add CHANGELOG.md for initial 0.1.0 release Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 5766d2d commit ae5bde1

4 files changed

Lines changed: 87 additions & 2 deletions

File tree

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
run: python -c "from pine_assistant import PineAI, AsyncPineAI, __version__; print(f'pine-assistant {__version__} OK')"
3434

3535
- name: Run tests
36-
run: pip install pytest pytest-asyncio && pytest tests/ -v --ignore=tests/integration || echo "No unit tests yet"
36+
run: pip install pytest pytest-asyncio && pytest tests/ -v --ignore=tests/integration
3737

3838
- name: Build distribution
3939
run: python -m build

CHANGELOG.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/), and this
6+
project adheres to [Semantic Versioning](https://semver.org/).
7+
8+
## [0.1.0] - 2026-02-16
9+
10+
### Added
11+
12+
- Async SDK client (`AsyncPineAI`) with Socket.IO and HTTP transport layers
13+
- Synchronous wrapper (`PineAI`) for non-async usage
14+
- Authentication flow (email verification with code)
15+
- Session management (create, list, join, leave)
16+
- Real-time chat with async generator streaming
17+
- Task lifecycle support (start, watch, cancel)
18+
- Form handling and payment event support
19+
- Pydantic models for all event and data types
20+
- Stream buffering for text and work-log events
21+
- CLI tool (`pine`) with auth, chat, sessions, and tasks commands
22+
- Full type annotations with `py.typed` marker
23+
- Integration test suite
24+
25+
[0.1.0]: https://github.com/pineai/pine-python/releases/tag/v0.1.0

pyproject.toml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ dependencies = [
3131

3232
[project.optional-dependencies]
3333
cli = ["click>=8.1.0", "rich>=13.0.0"]
34-
dev = ["pytest>=7.0", "pytest-asyncio>=0.23.0"]
34+
dev = ["pytest>=7.0", "pytest-asyncio>=0.23.0", "ruff>=0.4.0"]
3535

3636
[project.urls]
3737
Homepage = "https://github.com/pineai/pine-python"
@@ -46,3 +46,17 @@ where = ["src"]
4646

4747
[tool.setuptools.package-data]
4848
pine_assistant = ["py.typed"]
49+
50+
[tool.ruff]
51+
target-version = "py310"
52+
line-length = 120
53+
54+
[tool.ruff.lint]
55+
select = ["E", "F", "I", "W", "UP", "B", "SIM"]
56+
ignore = ["E501"]
57+
58+
[tool.ruff.lint.isort]
59+
known-first-party = ["pine_assistant"]
60+
61+
[tool.pytest.ini_options]
62+
asyncio_mode = "auto"

tests/test_basics.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
"""Basic unit tests for pine-assistant package."""
2+
3+
from pine_assistant import (
4+
AsyncPineAI,
5+
PineAI,
6+
PineAIError,
7+
AuthError,
8+
SessionError,
9+
ConnectionError,
10+
C2SEvent,
11+
S2CEvent,
12+
__version__,
13+
)
14+
from pine_assistant.models.events import NotificationEvent
15+
16+
17+
def test_version():
18+
assert __version__ == "0.1.0"
19+
20+
21+
def test_public_exports():
22+
assert PineAI is not None
23+
assert AsyncPineAI is not None
24+
25+
26+
def test_error_hierarchy():
27+
assert issubclass(AuthError, PineAIError)
28+
assert issubclass(SessionError, PineAIError)
29+
assert issubclass(ConnectionError, PineAIError)
30+
31+
32+
def test_error_attributes():
33+
err = PineAIError(code="test_code", message="something broke")
34+
assert err.code == "test_code"
35+
assert str(err) == "something broke"
36+
assert err.details is None
37+
38+
err_with_details = SessionError("bad session", details={"id": "123"})
39+
assert err_with_details.code == "session_error"
40+
assert err_with_details.details == {"id": "123"}
41+
42+
43+
def test_event_constants():
44+
assert C2SEvent.SESSION_MESSAGE == "session:message"
45+
assert S2CEvent.SESSION_TEXT == "session:text"
46+
assert NotificationEvent.NEW_MESSAGE == "notification:new_message"

0 commit comments

Comments
 (0)