eventide-sdk 0.1.0__tar.gz
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.
- eventide_sdk-0.1.0/PKG-INFO +34 -0
- eventide_sdk-0.1.0/README.md +22 -0
- eventide_sdk-0.1.0/eventide/__init__.py +13 -0
- eventide_sdk-0.1.0/eventide/client.py +94 -0
- eventide_sdk-0.1.0/eventide/types.py +73 -0
- eventide_sdk-0.1.0/eventide_sdk.egg-info/PKG-INFO +34 -0
- eventide_sdk-0.1.0/eventide_sdk.egg-info/SOURCES.txt +10 -0
- eventide_sdk-0.1.0/eventide_sdk.egg-info/dependency_links.txt +1 -0
- eventide_sdk-0.1.0/eventide_sdk.egg-info/requires.txt +5 -0
- eventide_sdk-0.1.0/eventide_sdk.egg-info/top_level.txt +1 -0
- eventide_sdk-0.1.0/pyproject.toml +20 -0
- eventide_sdk-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: eventide-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python SDK for the Eventide event gateway
|
|
5
|
+
License: MIT
|
|
6
|
+
Requires-Python: >=3.9
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: httpx>=0.25
|
|
9
|
+
Provides-Extra: dev
|
|
10
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
11
|
+
Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
|
|
12
|
+
|
|
13
|
+
# Eventide Python SDK
|
|
14
|
+
|
|
15
|
+
Python SDK for the Eventide event gateway, mirroring the reference-agent implementation.
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
import asyncio
|
|
21
|
+
from eventide import GatewayClient, Event, EventType, Level
|
|
22
|
+
|
|
23
|
+
async def main():
|
|
24
|
+
async with GatewayClient("http://127.0.0.1:18081") as client:
|
|
25
|
+
await client.append(Event(
|
|
26
|
+
thread_id="t1",
|
|
27
|
+
turn_id="turn1",
|
|
28
|
+
type=EventType.TURN_STARTED,
|
|
29
|
+
payload={"input": {"msg": "hello"}},
|
|
30
|
+
))
|
|
31
|
+
|
|
32
|
+
if __name__ == "__main__":
|
|
33
|
+
asyncio.run(main())
|
|
34
|
+
```
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Eventide Python SDK
|
|
2
|
+
|
|
3
|
+
Python SDK for the Eventide event gateway, mirroring the reference-agent implementation.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```python
|
|
8
|
+
import asyncio
|
|
9
|
+
from eventide import GatewayClient, Event, EventType, Level
|
|
10
|
+
|
|
11
|
+
async def main():
|
|
12
|
+
async with GatewayClient("http://127.0.0.1:18081") as client:
|
|
13
|
+
await client.append(Event(
|
|
14
|
+
thread_id="t1",
|
|
15
|
+
turn_id="turn1",
|
|
16
|
+
type=EventType.TURN_STARTED,
|
|
17
|
+
payload={"input": {"msg": "hello"}},
|
|
18
|
+
))
|
|
19
|
+
|
|
20
|
+
if __name__ == "__main__":
|
|
21
|
+
asyncio.run(main())
|
|
22
|
+
```
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""eventide-sdk — Python SDK for the Eventide event gateway."""
|
|
2
|
+
|
|
3
|
+
from .types import SPEC_VERSION, Event, EventType, Level
|
|
4
|
+
from .client import GatewayClient, GatewayError
|
|
5
|
+
|
|
6
|
+
__all__ = [
|
|
7
|
+
"SPEC_VERSION",
|
|
8
|
+
"Event",
|
|
9
|
+
"EventType",
|
|
10
|
+
"Level",
|
|
11
|
+
"GatewayClient",
|
|
12
|
+
"GatewayError",
|
|
13
|
+
]
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"""Gateway client — async HTTP client for POST /events:append."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from typing import List, Optional
|
|
7
|
+
|
|
8
|
+
import httpx
|
|
9
|
+
|
|
10
|
+
from .types import Event
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class GatewayError(Exception):
|
|
14
|
+
"""Raised when the gateway returns a non-2xx response."""
|
|
15
|
+
|
|
16
|
+
def __init__(self, status: int, body: str) -> None:
|
|
17
|
+
super().__init__(f"gateway responded with {status}: {body}")
|
|
18
|
+
self.status = status
|
|
19
|
+
self.body = body
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass
|
|
23
|
+
class AppendResult:
|
|
24
|
+
"""Result from a successful append call."""
|
|
25
|
+
|
|
26
|
+
event_id: str
|
|
27
|
+
seq: int
|
|
28
|
+
stream_id: Optional[str] = None
|
|
29
|
+
duplicated: bool = False
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class GatewayClient:
|
|
33
|
+
"""
|
|
34
|
+
Async client for the Eventide event gateway.
|
|
35
|
+
|
|
36
|
+
Usage::
|
|
37
|
+
|
|
38
|
+
async with GatewayClient("http://127.0.0.1:18081") as client:
|
|
39
|
+
await client.append(Event(
|
|
40
|
+
thread_id="t1",
|
|
41
|
+
turn_id="turn1",
|
|
42
|
+
type=EventType.TURN_STARTED,
|
|
43
|
+
payload={"input": {"msg": "hi"}},
|
|
44
|
+
))
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
def __init__(self, base_url: str, *, timeout: float = 10.0) -> None:
|
|
48
|
+
self.base_url = base_url.rstrip("/")
|
|
49
|
+
self._client = httpx.AsyncClient(timeout=timeout)
|
|
50
|
+
|
|
51
|
+
async def __aenter__(self) -> "GatewayClient":
|
|
52
|
+
return self
|
|
53
|
+
|
|
54
|
+
async def __aexit__(self, *exc) -> None:
|
|
55
|
+
await self.close()
|
|
56
|
+
|
|
57
|
+
async def close(self) -> None:
|
|
58
|
+
"""Close the underlying HTTP client."""
|
|
59
|
+
await self._client.aclose()
|
|
60
|
+
|
|
61
|
+
async def append(self, event: Event) -> AppendResult:
|
|
62
|
+
"""
|
|
63
|
+
Append a single event to the gateway.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
event: The event to send.
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
AppendResult with the assigned event_id, seq, etc.
|
|
70
|
+
|
|
71
|
+
Raises:
|
|
72
|
+
GatewayError: If the gateway returns a non-2xx status.
|
|
73
|
+
"""
|
|
74
|
+
resp = await self._client.post(
|
|
75
|
+
f"{self.base_url}/events:append",
|
|
76
|
+
json={"event": event.to_dict()},
|
|
77
|
+
)
|
|
78
|
+
if resp.status_code < 200 or resp.status_code >= 300:
|
|
79
|
+
raise GatewayError(resp.status_code, resp.text)
|
|
80
|
+
|
|
81
|
+
data = resp.json()
|
|
82
|
+
return AppendResult(
|
|
83
|
+
event_id=data.get("event_id", ""),
|
|
84
|
+
seq=data.get("seq", 0),
|
|
85
|
+
stream_id=data.get("stream_id"),
|
|
86
|
+
duplicated=data.get("duplicated", False),
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
async def append_all(self, events: List[Event]) -> List[AppendResult]:
|
|
90
|
+
"""Append multiple events sequentially."""
|
|
91
|
+
results = []
|
|
92
|
+
for event in events:
|
|
93
|
+
results.append(await self.append(event))
|
|
94
|
+
return results
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""Core event types — mirrors internal/eventproto/."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass, field, asdict
|
|
6
|
+
from enum import Enum
|
|
7
|
+
from typing import Any, Dict, Optional
|
|
8
|
+
|
|
9
|
+
SPEC_VERSION = "agent-events/1.0"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class EventType(str, Enum):
|
|
13
|
+
"""Event type constants — mirrors internal/eventproto/types.go."""
|
|
14
|
+
|
|
15
|
+
THREAD_READY = "thread.ready"
|
|
16
|
+
THREAD_HEARTBEAT = "thread.heartbeat"
|
|
17
|
+
THREAD_SUSPENDED = "thread.suspended"
|
|
18
|
+
THREAD_RESUMED = "thread.resumed"
|
|
19
|
+
|
|
20
|
+
TURN_STARTED = "turn.started"
|
|
21
|
+
TURN_INPUT = "turn.input"
|
|
22
|
+
TURN_COMPLETED = "turn.completed"
|
|
23
|
+
TURN_FAILED = "turn.failed"
|
|
24
|
+
TURN_CANCELLED = "turn.cancelled"
|
|
25
|
+
|
|
26
|
+
ASSISTANT_DELTA = "assistant.message.delta"
|
|
27
|
+
ASSISTANT_COMPLETED = "assistant.message.completed"
|
|
28
|
+
|
|
29
|
+
STATE_CHECKPOINT = "state.checkpoint"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class Level(str, Enum):
|
|
33
|
+
"""Event level constants — mirrors internal/eventproto/event.go."""
|
|
34
|
+
|
|
35
|
+
DEBUG = "debug"
|
|
36
|
+
INFO = "info"
|
|
37
|
+
WARN = "warn"
|
|
38
|
+
ERROR = "error"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@dataclass
|
|
42
|
+
class Event:
|
|
43
|
+
"""
|
|
44
|
+
Represents a single event to send to the gateway.
|
|
45
|
+
|
|
46
|
+
Only ``thread_id``, ``turn_id``, ``type``, and ``level`` are required.
|
|
47
|
+
The gateway auto-fills ``spec_version``, ``event_id``, ``ts``, and ``seq``
|
|
48
|
+
when omitted.
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
thread_id: str
|
|
52
|
+
turn_id: str
|
|
53
|
+
type: str # use EventType values
|
|
54
|
+
level: str = Level.INFO # use Level values
|
|
55
|
+
payload: Any = field(default_factory=dict)
|
|
56
|
+
|
|
57
|
+
# Optional — auto-filled by gateway when omitted/empty
|
|
58
|
+
spec_version: str = SPEC_VERSION
|
|
59
|
+
event_id: str = ""
|
|
60
|
+
ts: str = ""
|
|
61
|
+
seq: int = 0
|
|
62
|
+
|
|
63
|
+
# Optional metadata
|
|
64
|
+
content_type: Optional[str] = None
|
|
65
|
+
source: Optional[Dict[str, Any]] = None
|
|
66
|
+
trace: Optional[Dict[str, Any]] = None
|
|
67
|
+
tags: Optional[Dict[str, str]] = None
|
|
68
|
+
|
|
69
|
+
def to_dict(self) -> dict:
|
|
70
|
+
"""Serialize to the JSON structure expected by POST /events:append."""
|
|
71
|
+
d = asdict(self)
|
|
72
|
+
# Remove None optional fields to keep the payload clean
|
|
73
|
+
return {k: v for k, v in d.items() if v is not None}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: eventide-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python SDK for the Eventide event gateway
|
|
5
|
+
License: MIT
|
|
6
|
+
Requires-Python: >=3.9
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: httpx>=0.25
|
|
9
|
+
Provides-Extra: dev
|
|
10
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
11
|
+
Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
|
|
12
|
+
|
|
13
|
+
# Eventide Python SDK
|
|
14
|
+
|
|
15
|
+
Python SDK for the Eventide event gateway, mirroring the reference-agent implementation.
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
import asyncio
|
|
21
|
+
from eventide import GatewayClient, Event, EventType, Level
|
|
22
|
+
|
|
23
|
+
async def main():
|
|
24
|
+
async with GatewayClient("http://127.0.0.1:18081") as client:
|
|
25
|
+
await client.append(Event(
|
|
26
|
+
thread_id="t1",
|
|
27
|
+
turn_id="turn1",
|
|
28
|
+
type=EventType.TURN_STARTED,
|
|
29
|
+
payload={"input": {"msg": "hello"}},
|
|
30
|
+
))
|
|
31
|
+
|
|
32
|
+
if __name__ == "__main__":
|
|
33
|
+
asyncio.run(main())
|
|
34
|
+
```
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
eventide/__init__.py
|
|
4
|
+
eventide/client.py
|
|
5
|
+
eventide/types.py
|
|
6
|
+
eventide_sdk.egg-info/PKG-INFO
|
|
7
|
+
eventide_sdk.egg-info/SOURCES.txt
|
|
8
|
+
eventide_sdk.egg-info/dependency_links.txt
|
|
9
|
+
eventide_sdk.egg-info/requires.txt
|
|
10
|
+
eventide_sdk.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
eventide
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "eventide-sdk"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Python SDK for the Eventide event gateway"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
dependencies = [
|
|
13
|
+
"httpx>=0.25",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
[project.optional-dependencies]
|
|
17
|
+
dev = [
|
|
18
|
+
"pytest>=7.0",
|
|
19
|
+
"pytest-asyncio>=0.21",
|
|
20
|
+
]
|