philo-sdk 0.1.0__cp312-none-any.whl

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.
philo_sdk/__init__.pyc ADDED
Binary file
philo_sdk/__init__.pyi ADDED
@@ -0,0 +1,12 @@
1
+ from ._l2_inputs import InputStream as InputStream
2
+ from .assets import Image as Image, ReferenceAudio as ReferenceAudio
3
+ from .characters import Character as Character, ReferenceVoice as ReferenceVoice
4
+ from .client import PhiloClient as PhiloClient
5
+ from .errors import CapabilityUnavailable as CapabilityUnavailable, PhiloError as PhiloError
6
+ from .managed_assets import AssetRef as AssetRef
7
+ from .media import MediaChunk as MediaChunk
8
+ from .memory import MemoryState as MemoryState
9
+ from .sessions import Session as Session, SessionSnapshot as SessionSnapshot, SessionUsage as SessionUsage
10
+ from _typeshed import Incomplete
11
+
12
+ __all__: Incomplete
philo_sdk/_http.pyc ADDED
Binary file
philo_sdk/_http.pyi ADDED
@@ -0,0 +1,17 @@
1
+ import httpx
2
+ from .errors import PhiloError as PhiloError
3
+ from _typeshed import Incomplete
4
+
5
+ _MAX_JSON_BYTES: Incomplete
6
+
7
+ def validate_base_url(value: str) -> str: ...
8
+
9
+ class Http:
10
+ base_url: Incomplete
11
+ timeout: Incomplete
12
+ _api_key: Incomplete
13
+ _client: Incomplete
14
+ def __init__(self, api_key: str, base_url: str, timeout: float, *, transport: httpx.AsyncBaseTransport | None = None) -> None: ...
15
+ def redact(self, value: str) -> str: ...
16
+ async def request(self, method: str, path: str, body: dict | None = None, *, params: dict | None = None, binary: bool = False) -> dict | bytes: ...
17
+ async def close(self) -> None: ...
Binary file
@@ -0,0 +1 @@
1
+ def fetch_reply(need: dict, *, pcm16: bytes | None = None, prompt: str | None = None, final: bool = False) -> dict: ...
Binary file
@@ -0,0 +1,21 @@
1
+ from .errors import PhiloError as PhiloError
2
+ from _typeshed import Incomplete
3
+ from datetime import datetime
4
+
5
+ class InputStream:
6
+ _conversation: Incomplete
7
+ kind: Incomplete
8
+ stream_id: Incomplete
9
+ command_id: Incomplete
10
+ state: str
11
+ _sequence: int
12
+ _captured_at: datetime | None
13
+ _changed: Incomplete
14
+ _lock: Incomplete
15
+ _stop_id: str | None
16
+ def __init__(self, conversation, kind: str) -> None: ...
17
+ def _observe(self, event: dict) -> None: ...
18
+ async def wait_ready(self, *, timeout: float = 10) -> None: ...
19
+ async def send(self, data: bytes, *, captured_at: datetime) -> int: ...
20
+ async def stop(self) -> str: ...
21
+ def _closed(self) -> None: ...
Binary file
@@ -0,0 +1,44 @@
1
+ import asyncio
2
+ from ._l2_inputs import InputStream as InputStream
3
+ from ._stream import Stream as Stream
4
+ from .errors import CapabilityUnavailable as CapabilityUnavailable, PhiloError as PhiloError
5
+ from .media import DEFAULT_CODECS as DEFAULT_CODECS, MAX_FRAME_BYTES as MAX_FRAME_BYTES, MAX_HEADER_BYTES as MAX_HEADER_BYTES, MediaChunk as MediaChunk, decode_frame as decode_frame, encode_frame as encode_frame
6
+ from _typeshed import Incomplete
7
+ from collections.abc import Generator
8
+
9
+ class ConversationStream(Stream):
10
+ _session_id: Incomplete
11
+ _seq: int
12
+ _send_lock: Incomplete
13
+ _heartbeat_task: asyncio.Task | None
14
+ _heartbeat_failure: PhiloError | None
15
+ welcome: dict | None
16
+ _media: Incomplete
17
+ _codecs: Incomplete
18
+ _connection_id: str | None
19
+ _event_seq: int
20
+ _feedback_lock: Incomplete
21
+ _progress: dict[tuple[str, int], dict]
22
+ _latest_epoch: dict[str, int]
23
+ _captures: dict[str, InputStream]
24
+ _cuts: dict[str, dict]
25
+ _iterating: bool
26
+ _closed_stream: bool
27
+ def __init__(self, socket, http, session_id: str, *, media: bool = False, codecs=None) -> None: ...
28
+ async def _send(self, fields: dict, *, payload: bytes | None = None) -> None: ...
29
+ _max_frame: Incomplete
30
+ _max_header: Incomplete
31
+ async def start(self) -> None: ...
32
+ async def _heartbeat(self, interval: int) -> None: ...
33
+ def _check_event(self, event) -> None: ...
34
+ async def _messages(self) -> Generator[Incomplete]: ...
35
+ async def _received(self, chunk: MediaChunk) -> None: ...
36
+ async def feedback(self, chunk: MediaChunk, *, committed: int | None = None, played: int | None = None, released: int | None = None, buffered_ms: float = 0, paused: bool = False, played_at_ms: float | None = None) -> None: ...
37
+ async def acknowledge_cut(self, event: dict) -> None: ...
38
+ async def _start_input(self, kind: str) -> InputStream: ...
39
+ async def start_microphone(self) -> InputStream: ...
40
+ async def start_camera(self) -> InputStream: ...
41
+ async def send_text(self, text: str) -> str: ...
42
+ async def send_json(self, message: dict) -> None: ...
43
+ async def send_bytes(self, data: bytes) -> None: ...
44
+ async def close(self) -> None: ...
philo_sdk/_stream.pyc ADDED
Binary file
philo_sdk/_stream.pyi ADDED
@@ -0,0 +1,23 @@
1
+ from ._http import Http as Http
2
+ from ._l1_protocol import fetch_reply as fetch_reply
3
+ from .errors import PhiloError as PhiloError
4
+ from _typeshed import Incomplete
5
+ from collections.abc import AsyncIterator
6
+ from contextlib import asynccontextmanager
7
+ from websockets.asyncio.client import ClientConnection, connect
8
+
9
+ _LOG: Incomplete
10
+
11
+ class _NoRedirectConnect(connect):
12
+ def process_redirect(self, exc: Exception) -> Exception: ...
13
+
14
+ class Stream:
15
+ def __init__(self, socket: ClientConnection, http: Http, kind: str) -> None: ...
16
+ def __aiter__(self) -> AsyncIterator[dict | bytes]: ...
17
+ async def _messages(self) -> AsyncIterator[dict | bytes]: ...
18
+ async def send_json(self, message: dict) -> None: ...
19
+ async def send_bytes(self, data: bytes) -> None: ...
20
+ async def reply(self, need: dict, *, pcm16: bytes | None = None, prompt: str | None = None, final: bool = False) -> None: ...
21
+
22
+ @asynccontextmanager
23
+ async def open_stream(http: Http, path: str, expected_path: str, kind: str, *, media: bool = False, codecs=None): ...
philo_sdk/assets.pyc ADDED
Binary file
philo_sdk/assets.pyi ADDED
@@ -0,0 +1,25 @@
1
+ from _typeshed import Incomplete
2
+ from dataclasses import dataclass
3
+ from pathlib import Path
4
+ from typing import ClassVar, Self
5
+
6
+ _MAX_ASSET_BYTES: Incomplete
7
+
8
+ @dataclass(frozen=True, repr=False)
9
+ class InlineAsset:
10
+ data: bytes
11
+ mime_type: str
12
+ allowed_types: ClassVar[frozenset[str]] = ...
13
+ def __post_init__(self) -> None: ...
14
+ def __repr__(self) -> str: ...
15
+ @classmethod
16
+ def from_file(cls, path: str | Path, *, mime_type: str) -> Self: ...
17
+ def to_dict(self) -> dict: ...
18
+ @classmethod
19
+ def from_dict(cls, value: dict) -> Self: ...
20
+
21
+ class Image(InlineAsset):
22
+ allowed_types: Incomplete
23
+
24
+ class ReferenceAudio(InlineAsset):
25
+ allowed_types: Incomplete
Binary file
@@ -0,0 +1,28 @@
1
+ from .assets import Image as Image, ReferenceAudio as ReferenceAudio
2
+ from dataclasses import dataclass
3
+ from pathlib import Path
4
+ from typing import Self
5
+
6
+ @dataclass(frozen=True)
7
+ class ReferenceVoice:
8
+ audio: ReferenceAudio
9
+ transcript: str
10
+ language: str | None = ...
11
+ def __post_init__(self) -> None: ...
12
+ def to_dict(self) -> dict: ...
13
+ @classmethod
14
+ def from_dict(cls, value: dict) -> Self: ...
15
+
16
+ @dataclass(frozen=True)
17
+ class Character:
18
+ name: str
19
+ persona: str
20
+ image: Image
21
+ reference_voice: ReferenceVoice | None = ...
22
+ def __post_init__(self) -> None: ...
23
+ def to_dict(self) -> dict: ...
24
+ @classmethod
25
+ def from_dict(cls, value: dict) -> Self: ...
26
+ def save(self, path: str | Path) -> None: ...
27
+ @classmethod
28
+ def load(cls, path: str | Path) -> Self: ...
philo_sdk/client.pyc ADDED
Binary file
philo_sdk/client.pyi ADDED
@@ -0,0 +1,17 @@
1
+ import httpx
2
+ from ._http import Http as Http
3
+ from .managed_assets import ManagedAssets as ManagedAssets
4
+ from .sessions import Sessions as Sessions
5
+ from .video import Video as Video
6
+ from _typeshed import Incomplete
7
+
8
+ class PhiloClient:
9
+ _http: Incomplete
10
+ assets: ManagedAssets
11
+ video: Video
12
+ sessions: Sessions
13
+ def __init__(self, *, api_key: str, base_url: str = 'https://developer.philoai.xyz', timeout: float = 30, _transport: httpx.AsyncBaseTransport | None = None) -> None: ...
14
+ async def capabilities(self) -> dict: ...
15
+ async def close(self) -> None: ...
16
+ async def __aenter__(self) -> PhiloClient: ...
17
+ async def __aexit__(self, exc_type, exc, tb) -> None: ...
philo_sdk/devices.pyc ADDED
Binary file
philo_sdk/devices.pyi ADDED
@@ -0,0 +1,40 @@
1
+ from _typeshed import Incomplete
2
+ from dataclasses import dataclass
3
+ from datetime import datetime
4
+ from typing import Any
5
+
6
+ class DeviceError(RuntimeError): ...
7
+
8
+ @dataclass(frozen=True)
9
+ class CapturedInput:
10
+ data: bytes
11
+ captured_at: datetime
12
+
13
+ def _dependency(module: str) -> Any: ...
14
+ def microphone_devices() -> list[dict[str, Any]]: ...
15
+ def _microphone_worker(options, frames, status, stop) -> None: ...
16
+ def _encode_camera_frame(cv, frame) -> bytes: ...
17
+ def _camera_worker(options, frames, status, stop) -> None: ...
18
+ def _capture_worker(kind, options, frames, status, stop) -> None: ...
19
+
20
+ class _Capture:
21
+ _timeout: Incomplete
22
+ _process: Incomplete
23
+ _closed: bool
24
+ _ready: bool
25
+ _stopped: bool
26
+ def __init__(self, kind: str, options: dict, *, startup_timeout: float = 10) -> None: ...
27
+ def _check_status(self) -> None: ...
28
+ _frames: Incomplete
29
+ _stop: Incomplete
30
+ async def __aenter__(self): ...
31
+ def __aiter__(self): ...
32
+ async def __anext__(self) -> CapturedInput: ...
33
+ async def aclose(self) -> None: ...
34
+ async def __aexit__(self, exc_type, exc, tb) -> None: ...
35
+
36
+ class MicrophoneCapture(_Capture):
37
+ def __init__(self, device: int | str | None = None, *, startup_timeout: float = 10) -> None: ...
38
+
39
+ class CameraCapture(_Capture):
40
+ def __init__(self, device: int = 0, *, fps: float = 1, startup_timeout: float = 10) -> None: ...
philo_sdk/errors.pyc ADDED
Binary file
philo_sdk/errors.pyi ADDED
@@ -0,0 +1,14 @@
1
+ from _typeshed import Incomplete
2
+
3
+ class PhiloError(Exception):
4
+ code: Incomplete
5
+ message: Incomplete
6
+ status_code: Incomplete
7
+ request_id: Incomplete
8
+ retryable: Incomplete
9
+ outcome_unknown: Incomplete
10
+ def __init__(self, code: str, message: str, *, status_code: int | None = None, request_id: str | None = None, retryable: bool = False, outcome_unknown: bool = False) -> None: ...
11
+
12
+ class CapabilityUnavailable(PhiloError):
13
+ capability: Incomplete
14
+ def __init__(self, capability: str) -> None: ...
Binary file
@@ -0,0 +1,47 @@
1
+ from .assets import Image as Image, ReferenceAudio as ReferenceAudio
2
+ from _typeshed import Incomplete
3
+ from dataclasses import dataclass
4
+
5
+ def asset_id(value): ...
6
+
7
+ @dataclass(frozen=True)
8
+ class AssetRef:
9
+ id: str
10
+ revision: int
11
+ def __post_init__(self) -> None: ...
12
+ def to_dict(self): ...
13
+
14
+ class AssetLibrary:
15
+ def __init__(self, http, kind) -> None: ...
16
+ async def list(self, *, page: int = 1, page_size: int = 30, include_archived: bool = False, query: str = ''): ...
17
+ async def retrieve(self, id, *, revision=None): ...
18
+ async def archive(self, id, *, expected_revision, expected_metadata_revision=None): ...
19
+ async def restore(self, id, *, expected_revision, expected_metadata_revision=None): ...
20
+ async def _state(self, id, state, revision, metadata): ...
21
+ async def deletion_plan(self, id, *, expected_revision): ...
22
+ async def delete(self, id, *, plan_hash, request_id): ...
23
+
24
+ class Images(AssetLibrary):
25
+ async def upload(self, *, name, image: Image): ...
26
+ async def update(self, id, *, name, image: Image, expected_revision, expected_metadata_revision): ...
27
+ async def rename(self, id, *, name, expected_revision, expected_metadata_revision): ...
28
+ async def download(self, reference: AssetRef): ...
29
+
30
+ class Voices(Images):
31
+ async def upload(self, *, name, audio: ReferenceAudio, transcript, language): ...
32
+ async def update(self, id, *, name, audio: ReferenceAudio, transcript, language, expected_revision, expected_metadata_revision): ...
33
+ async def download(self, reference: AssetRef): ...
34
+
35
+ class Characters(AssetLibrary):
36
+ @staticmethod
37
+ def _body(name, persona, image, voice): ...
38
+ async def create(self, *, name, persona, image: AssetRef, voice: AssetRef | None = None): ...
39
+ async def update(self, id, *, expected_revision, name, persona, image: AssetRef, voice: AssetRef | None = None): ...
40
+
41
+ class ManagedAssets:
42
+ _http: Incomplete
43
+ images: Incomplete
44
+ voices: Incomplete
45
+ characters: Incomplete
46
+ def __init__(self, http) -> None: ...
47
+ async def deletion_receipt(self, request_id): ...
philo_sdk/media.pyc ADDED
Binary file
philo_sdk/media.pyi ADDED
@@ -0,0 +1,26 @@
1
+ from .errors import PhiloError as PhiloError
2
+ from _typeshed import Incomplete
3
+ from collections.abc import Mapping
4
+ from dataclasses import dataclass
5
+
6
+ MAX_FRAME_BYTES: Incomplete
7
+ MAX_HEADER_BYTES: Incomplete
8
+ DEFAULT_CODECS: Incomplete
9
+
10
+ @dataclass(frozen=True)
11
+ class MediaChunk:
12
+ header: Mapping
13
+ payload: bytes
14
+ @property
15
+ def stream_id(self) -> str: ...
16
+ @property
17
+ def epoch(self) -> int: ...
18
+ @property
19
+ def stream_seq(self) -> int: ...
20
+ @property
21
+ def chunk_kind(self) -> str: ...
22
+ @property
23
+ def content_type(self) -> str: ...
24
+
25
+ def decode_frame(data: bytes, *, max_frame: int, max_header: int) -> MediaChunk: ...
26
+ def encode_frame(header: dict, payload: bytes, *, max_frame: int, max_header: int) -> bytes: ...
philo_sdk/memory.pyc ADDED
Binary file
philo_sdk/memory.pyi ADDED
@@ -0,0 +1,15 @@
1
+ from dataclasses import dataclass
2
+ from pathlib import Path
3
+ from typing import Self
4
+
5
+ @dataclass(frozen=True)
6
+ class MemoryState:
7
+ format: str
8
+ data: dict
9
+ def __post_init__(self) -> None: ...
10
+ def to_dict(self) -> dict: ...
11
+ @classmethod
12
+ def from_dict(cls, value: dict) -> Self: ...
13
+ def save(self, path: str | Path) -> None: ...
14
+ @classmethod
15
+ def load(cls, path: str | Path) -> Self: ...
philo_sdk/py.typed ADDED
File without changes
philo_sdk/sessions.pyc ADDED
Binary file
philo_sdk/sessions.pyi ADDED
@@ -0,0 +1,55 @@
1
+ from ._http import Http as Http
2
+ from ._stream import open_stream as open_stream
3
+ from .characters import Character as Character
4
+ from .errors import CapabilityUnavailable as CapabilityUnavailable, PhiloError as PhiloError
5
+ from .managed_assets import AssetRef as AssetRef
6
+ from .memory import MemoryState as MemoryState
7
+ from _typeshed import Incomplete
8
+ from dataclasses import dataclass
9
+
10
+ def session_id(value: str) -> str: ...
11
+
12
+ @dataclass(frozen=True)
13
+ class SessionSnapshot:
14
+ id: str
15
+ state: str
16
+ stream_url: str
17
+ cleanup: dict
18
+ preparation: dict | None = ...
19
+ @classmethod
20
+ def parse(cls, value: dict, *, expected_id: str | None = None, mutation: bool = False): ...
21
+
22
+ @dataclass(frozen=True)
23
+ class SessionUsage:
24
+ session_id: str
25
+ unit: str
26
+ state: str
27
+ metering_state: str
28
+ connected_elapsed_ms: int | None
29
+ observed_ms: int | None
30
+ budget_seconds: int | None
31
+ charged_seconds: int | None
32
+ cleanup_confirmed: bool
33
+ @classmethod
34
+ def parse(cls, value: dict, *, expected_id: str): ...
35
+
36
+ class Session:
37
+ snapshot: Incomplete
38
+ _stream_opened: bool
39
+ def __init__(self, http: Http, snapshot: SessionSnapshot, *, kind: str) -> None: ...
40
+ @property
41
+ def id(self) -> str: ...
42
+ @property
43
+ def _path(self) -> str: ...
44
+ async def refresh(self) -> SessionSnapshot: ...
45
+ async def export_memory(self) -> MemoryState: ...
46
+ async def usage(self) -> SessionUsage: ...
47
+ async def stop(self) -> SessionSnapshot: ...
48
+ async def wait_ready(self, *, timeout: float | None = None) -> SessionSnapshot: ...
49
+ def stream(self, *, media: bool = False, codecs: tuple[str, ...] | None = None): ...
50
+
51
+ class Sessions:
52
+ _http: Incomplete
53
+ def __init__(self, http: Http) -> None: ...
54
+ async def create(self, *, language: str, character: Character | None = None, character_asset: AssetRef | None = None, memory: MemoryState | None = None) -> Session: ...
55
+ async def retrieve(self, id: str) -> Session: ...
philo_sdk/video.pyc ADDED
Binary file
philo_sdk/video.pyi ADDED
@@ -0,0 +1,11 @@
1
+ from ._http import Http as Http
2
+ from .assets import Image as Image
3
+ from .errors import CapabilityUnavailable as CapabilityUnavailable
4
+ from .sessions import Session as Session, SessionSnapshot as SessionSnapshot, session_id as session_id
5
+ from _typeshed import Incomplete
6
+
7
+ class Video:
8
+ _http: Incomplete
9
+ def __init__(self, http: Http) -> None: ...
10
+ async def create(self, *, image: Image, prompt: str, audio_mode: str = 'native', seed: int | None = None, max_frames: int | None = None) -> Session: ...
11
+ async def retrieve(self, id: str) -> Session: ...
@@ -0,0 +1,161 @@
1
+ Metadata-Version: 2.5
2
+ Name: philo-sdk
3
+ Version: 0.1.0
4
+ Summary: Python client for Philo digital-life conversations and video APIs
5
+ Project-URL: Homepage, https://developer.philoai.xyz
6
+ Project-URL: Documentation, https://developer.philoai.xyz/docs/en/
7
+ Project-URL: Getting started, https://developer.philoai.xyz/docs/en/get-started
8
+ Project-URL: Support, https://developer.philoai.xyz/docs/en/support
9
+ Author: Philo AI
10
+ License-Expression: LicenseRef-Philo-Proprietary
11
+ License-File: LICENSE
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3 :: Only
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Programming Language :: Python :: 3.14
18
+ Classifier: Programming Language :: Python :: Implementation :: CPython
19
+ Classifier: Typing :: Typed
20
+ Requires-Python: <3.15,>=3.11
21
+ Requires-Dist: httpx<1,>=0.27
22
+ Requires-Dist: opencv-python-headless<5,>=4.10
23
+ Requires-Dist: sounddevice<0.6,>=0.5
24
+ Requires-Dist: websockets<16,>=15
25
+ Provides-Extra: camera
26
+ Provides-Extra: devices
27
+ Provides-Extra: microphone
28
+ Description-Content-Type: text/markdown
29
+
30
+ # Philo Python SDK
31
+
32
+ Use **CPython 3.13** (supported: standard CPython 3.11–3.14).
33
+ Install from [PyPI](https://pypi.org/project/philo-sdk/):
34
+
35
+ ```bash
36
+ python -m pip install philo-sdk
37
+ ```
38
+
39
+ For the version used by this guide:
40
+
41
+ ```bash
42
+ python -m pip install "philo-sdk==0.1.0"
43
+ ```
44
+
45
+ Microphone and camera Python dependencies are included. Installation opens no
46
+ hardware or API session. The [preparation guide](https://developer.philoai.xyz/docs/en/api-token)
47
+ covers Python setup, virtual environments, upgrades and OS device requirements.
48
+ Using the service requires your own Developer API Token and available quota.
49
+
50
+ ## Start with a character
51
+
52
+ Set `PHILO_API_KEY` through your normal secret configuration. First list the
53
+ characters available to your Token; this does not start a session or upload media:
54
+
55
+ ```python
56
+ import asyncio
57
+ import os
58
+ from philo_sdk import PhiloClient
59
+
60
+
61
+ async def main():
62
+ async with PhiloClient(api_key=os.environ["PHILO_API_KEY"]) as client:
63
+ page = 1
64
+ while page is not None:
65
+ result = await client.assets.characters.list(page=page, page_size=100)
66
+ for role in result["items"]:
67
+ if role.get("state") == "active" and role.get("available"):
68
+ print(role["id"], role["revision"], role["name"])
69
+ page = result["next_page"]
70
+
71
+
72
+ asyncio.run(main())
73
+ ```
74
+
75
+ Choose a character explicitly. Create an L2 session with
76
+ `character_asset=AssetRef(id, revision)` and a conversation language. The service
77
+ resolves its image, reference voice and persona. No local character materials
78
+ are required. The [complete quick start](https://developer.philoai.xyz/docs/en/public-assets)
79
+ includes selection, audiovisual output, stopping and usage; further examples
80
+ reuse the same selection for conversation, microphone, camera and text Memory.
81
+ Session creation can consume quota. Reading the character list cannot.
82
+
83
+ ## Interfaces
84
+
85
+ | Interface | Purpose |
86
+ | --- | --- |
87
+ | `client.assets` | Authorized official characters and your private assets |
88
+ | `client.sessions.create(character_asset=…, language=…)` | Start with an existing character |
89
+ | `session.stream(media=True)` | Audiovisual output with explicit consumer feedback |
90
+ | `start_microphone()` / `start_camera()` | Send captured PCM / JPEG inputs |
91
+ | `session.export_memory()` | Export supported text state after a completed close |
92
+ | `session.stop()` / `session.usage()` | Request cleanup and read observed usage |
93
+ | `Character`, `Image`, `ReferenceVoice` | Advanced inline character materials |
94
+ | `client.video.create(...)` | Advanced L1 generation with final prompt and image |
95
+
96
+ Check capabilities and session readiness before use. Received media is distinct
97
+ from actual playback; the SDK does not include a full player.
98
+ Text Memory is explicitly exported/imported; it is not a running-session backup.
99
+ No automatic replay of billable requests or reconnection is performed. Preserve
100
+ session/request IDs when outcomes are uncertain.
101
+
102
+ Tokens stay on your backend. The SDK connects only to its configured API origin,
103
+ does not follow redirects, and never needs infrastructure credentials. Official
104
+ assets are read-only; private asset updates require ownership and revision checks.
105
+
106
+ ## Real microphone and camera
107
+
108
+ The standard SDK installation includes device capture. Download the
109
+ [complete editable examples](https://developer.philoai.xyz/docs/en/examples)
110
+ to run the microphone and camera programs. A versioned local-wheel bundle remains
111
+ available as an alternative; its `install.py` selects the matching wheel, and
112
+ third-party dependencies may still require internet access.
113
+
114
+ `philo_sdk.devices.MicrophoneCapture` yields 16 kHz mono PCM16 chunks;
115
+ `CameraCapture` yields proportionally resized JPEG frames. Both include UTC
116
+ capture timestamps. Use `async with` and `async for` to send them through an
117
+ already-ready `start_microphone()` or `start_camera()` input. Keep the session's
118
+ receiver running concurrently. Close the capture, input and session in `finally`.
119
+ The complete downloaded programs implement this lifecycle, device selection and
120
+ Ctrl+C: `python microphone.py`, `python camera.py --microphone`.
121
+
122
+ These commands reuse your selected managed character. To use local character
123
+ materials instead, append `--character my_character.json` to either command;
124
+ real devices work identically. `--wav speech.wav` and `--jpeg scene.jpg` are
125
+ explicit offline alternatives. No synthetic input is substituted on failure.
126
+
127
+ Run scripts on the computer that owns the devices, with a guarded
128
+ `if __name__ == '__main__':` entry point. Allow microphone/camera access in the
129
+ OS. Linux microphone capture may require `libportaudio2`; the microphone must
130
+ support 16 kHz mono input. No echo cancellation or resampling is provided: use
131
+ headphones. Audio overflow is an error, camera buffering keeps only the latest
132
+ frame. Native drivers run in owned processes with bounded shutdown; a blocked
133
+ driver is terminated without blocking session cleanup. Device libraries are loaded
134
+ only when capture is used; installing the SDK does not open any hardware.
135
+
136
+ ## Python version and distribution
137
+
138
+ Use **CPython 3.13** for the tutorial. Bytecode wheels are supplied separately for
139
+ CPython 3.11, 3.12, 3.13 and 3.14; PyPy and other Python minors are not supported by
140
+ this release. Each wheel is tagged for its interpreter (for example
141
+ `cp313-none-any`), not a universal `py3` wheel. The SDK implementation is `.pyc`,
142
+ with `.pyi` API signatures for IDEs; editable examples remain Python source.
143
+ Bytecode is not encryption and contains no embedded credentials. Source archives
144
+ are internal build artifacts, not part of the downloadable example bundle.
145
+
146
+ The [installation guide](https://developer.philoai.xyz/docs/en/api-token) covers
147
+ macOS, Linux and Windows, including Python installation and upgrades. Create a
148
+ new virtual environment when upgrading Python, then reinstall the matching wheel;
149
+ do not copy `site-packages` from the old environment. The SDK wheel has no native
150
+ extension; its device dependencies and OS drivers still need platform support.
151
+ Linux CPU qualification does not imply physical-device or macOS/Windows testing.
152
+
153
+ ## Documentation
154
+
155
+ - [Quick start](https://developer.philoai.xyz/docs/en/get-started)
156
+ - [Continue with the selected character](https://developer.philoai.xyz/docs/en/examples)
157
+ - [Customization and advanced use](https://developer.philoai.xyz/docs/en/advanced)
158
+ - [API and SDK reference](https://developer.philoai.xyz/docs/en/reference)
159
+
160
+ The SDK is proprietary; see the bundled LICENSE. Editable examples may be adapted
161
+ for your own Philo integrations. Third-party dependencies retain their own licenses.
@@ -0,0 +1,37 @@
1
+ philo_sdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ philo_sdk/__init__.pyc,sha256=w93BdTuYcgqWHAmwi09gxuZbwH5V7jwqy23mL0QJvlk,816
3
+ philo_sdk/__init__.pyi,sha256=zikN51uUoMtbaXc8Y2XgetThrKDiVq3BjnP2HbYN2cY,642
4
+ philo_sdk/_http.pyc,sha256=moN3tPsmQ7_Vmjt2dTdm4c7XlidbkVK-pQm6NY5NUH0,7596
5
+ philo_sdk/_http.pyi,sha256=AzEpYYeapijnUNXwdsVu1KG5Uu2fOVsXh1YOd66ms5I,649
6
+ philo_sdk/_l1_protocol.pyc,sha256=41tNWTTeAv4CvLeY1dboWs97-6NkcPZWQWqyMahtzvw,2846
7
+ philo_sdk/_l1_protocol.pyi,sha256=uoE8lG3kF3EVAczqLSCfYD8oI8x11OLxQUL5JPaiazo,120
8
+ philo_sdk/_l2_inputs.pyc,sha256=9swzEyxZ-73ge_E6Iitxyq9OilTHWdlodWz03dOgkaY,8484
9
+ philo_sdk/_l2_inputs.pyi,sha256=R-_DxxN3x0aSoncsN4QDGSY60-UW7sfq4-k5ihCLAfo,698
10
+ philo_sdk/_l2_stream.pyc,sha256=wuIrylG8OD5QFsOt6TImjaMpwNC-GK2ZkhZc-0UReN8,23640
11
+ philo_sdk/_l2_stream.pyi,sha256=hc9mgi-gJYbBWYQXFUBrewA0yM79LTFIgOo5y-SqqSE,2195
12
+ philo_sdk/_stream.pyc,sha256=SS0XhY-CXyMErDvDRrdG10_VHIUWTqOuGBGv-n5vyIc,8040
13
+ philo_sdk/_stream.pyi,sha256=bqR0MftxbxlCFVScZxghKNV5b9rk_uNRK8d5HjEcORQ,1042
14
+ philo_sdk/assets.pyc,sha256=rFG7r91knAc5yUw6yI5NcsEAgptFLWDAbRLKTWrjLG8,4048
15
+ philo_sdk/assets.pyi,sha256=HTPj9_V9Pacsle3hk8S5InSyKr48Xexuy4J6dk47waM,687
16
+ philo_sdk/characters.pyc,sha256=oi8wHZ6u1Rw2bDDJsTEaMH0keCBURqicVpXmtvJZwsQ,6690
17
+ philo_sdk/characters.pyi,sha256=UBL-rcjp2ECCQ3VADZLfutKajNkN3vhoyJ-A1wyodwQ,815
18
+ philo_sdk/client.pyc,sha256=nLbu1lST90F00unXKoNroIlDTuYb5JHPwGEhwiTensU,2255
19
+ philo_sdk/client.pyi,sha256=8Hysi3FalON5vL34O1XiPWnukcGxpJeunSSmIHSdEu0,695
20
+ philo_sdk/devices.pyc,sha256=ifAW1HnlCJPjU6w1YVsGSo8DRsaiTHQSBKEUz_cCRyw,16872
21
+ philo_sdk/devices.pyi,sha256=qdlDQE5yDhay1jQder9Et_X5ysnpk15H30TAIXnKZHE,1383
22
+ philo_sdk/errors.pyc,sha256=LbtN8qMkSolrSQc6kAciZU-p0OnLCOVpDKLZQKOl-rQ,1758
23
+ philo_sdk/errors.pyi,sha256=yXI6-gmvKv1bQ2D-DYXuavn_DqgXniFVAlEkIRAmKy4,526
24
+ philo_sdk/managed_assets.pyc,sha256=fmq5nsNTThp9V-V9dx__sWx2cDGTRzqk0SzyI-1HKyU,11529
25
+ philo_sdk/managed_assets.pyi,sha256=TBbYAiRWQ_cUSchZnxWwVtV_gr-M5CvqWUJReA2LoCk,2087
26
+ philo_sdk/media.pyc,sha256=6JyO1tReEVLFrXFmciUtxgEKRZYMxcxTdVTJFU_T0rw,5381
27
+ philo_sdk/media.pyi,sha256=7ckjxz0rw9I_ql0aHgbhlixO0sJT130fZG90V1mZ_UQ,749
28
+ philo_sdk/memory.pyc,sha256=iFAJLDI6-wh7gxBDOZHQriU1o4pxcuhEKjTuG1SXG30,4494
29
+ philo_sdk/memory.pyi,sha256=Di4xv3YfLL-ycDHkPezHUqZ2OHPgAmUouSifO5s8Sq0,416
30
+ philo_sdk/sessions.pyc,sha256=95LBEy-R8XxU2u43zIavft8_uHCBfKadE4GxFq8SaRw,16084
31
+ philo_sdk/sessions.pyi,sha256=YfH7UlCrjnbcjfM38d3vcghvCNdwfqpM2424HShLm7g,1970
32
+ philo_sdk/video.pyc,sha256=VGMxZtDRnYUJ6_6LfwotqgyP3hGNIwudOGRQ74GVEDQ,3484
33
+ philo_sdk/video.pyi,sha256=0ZBOs-H4MrD_L5_iKx9y9nWBQ4LIQDTiwWJkk6Mh0Vs,565
34
+ philo_sdk-0.1.0.dist-info/METADATA,sha256=VWDv3t8SrGCA44P0QfEEEHdWQSlf4QkgYP5v92D1rfQ,7824
35
+ philo_sdk-0.1.0.dist-info/WHEEL,sha256=W42mSZvXqZOhgG5BKkqFS8CDA1xDuga_DU8M52cvmEY,89
36
+ philo_sdk-0.1.0.dist-info/licenses/LICENSE,sha256=Y_6gBCNO7_PqhouGf7iDsRFeDuzmXVGnCQVUJ8w9yfc,819
37
+ philo_sdk-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.33.0
3
+ Root-Is-Purelib: true
4
+ Tag: cp312-none-any
@@ -0,0 +1,15 @@
1
+ Philo SDK License
2
+ Copyright (c) 2026 Philo AI. All rights reserved.
3
+
4
+ Permission is granted to download, install and use the Philo SDK to integrate
5
+ applications with Philo services, subject to the applicable Philo service terms
6
+ and account permissions. This permission does not grant access to Philo services
7
+ without authorization or waive service usage charges.
8
+
9
+ The SDK is proprietary software. No license to its implementation source code
10
+ or to redistribute, sublicense or sell the SDK is granted by this permission.
11
+ Separately distributed example programs may be modified for your own Philo
12
+ integrations. Third-party dependencies remain subject to their own licenses.
13
+
14
+ The SDK is provided "AS IS", without warranties, to the extent permitted by
15
+ applicable law. Rights not expressly granted are reserved by Philo AI.