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.
@@ -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,5 @@
1
+ httpx>=0.25
2
+
3
+ [dev]
4
+ pytest>=7.0
5
+ pytest-asyncio>=0.21
@@ -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
+ ]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+