genailit 0.0.1__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.
- genailit-0.0.1/PKG-INFO +53 -0
- genailit-0.0.1/README.md +43 -0
- genailit-0.0.1/pyproject.toml +25 -0
- genailit-0.0.1/src/genailit/__init__.py +13 -0
- genailit-0.0.1/src/genailit/adapters/__init__.py +7 -0
- genailit-0.0.1/src/genailit/adapters/base.py +38 -0
- genailit-0.0.1/src/genailit/events.py +13 -0
- genailit-0.0.1/src/genailit/telemetry.py +23 -0
- genailit-0.0.1/tests/conftest.py +12 -0
- genailit-0.0.1/tests/test_base_adapter.py +33 -0
- genailit-0.0.1/tests/test_events.py +16 -0
- genailit-0.0.1/tests/test_telemetry.py +17 -0
genailit-0.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: genailit
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Open source Python library for multi-agent web interfaces.
|
|
5
|
+
Requires-Python: >=3.10
|
|
6
|
+
Requires-Dist: pydantic>=2
|
|
7
|
+
Provides-Extra: dev
|
|
8
|
+
Requires-Dist: pytest; extra == 'dev'
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
|
|
11
|
+
# GenAILit
|
|
12
|
+
|
|
13
|
+
GenAILit is a small Python base for building web interfaces for multi-agent systems.
|
|
14
|
+
|
|
15
|
+
This milestone only includes the package foundation:
|
|
16
|
+
|
|
17
|
+
- `GenAILitEvent`
|
|
18
|
+
- `TelemetryStore`
|
|
19
|
+
- `AdapterContext`
|
|
20
|
+
- `BaseAgentAdapter`
|
|
21
|
+
|
|
22
|
+
## Requirements
|
|
23
|
+
|
|
24
|
+
- Python 3.10+
|
|
25
|
+
- `pydantic>=2`
|
|
26
|
+
- `pytest` for tests
|
|
27
|
+
|
|
28
|
+
## Install
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install genailit
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Example
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
from genailit import AdapterContext, BaseAgentAdapter, GenAILitEvent, TelemetryStore
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class EchoAdapter(BaseAgentAdapter):
|
|
41
|
+
def build_events(self, context: AdapterContext):
|
|
42
|
+
yield GenAILitEvent(name="ready")
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
telemetry = TelemetryStore()
|
|
46
|
+
context = AdapterContext(session_id="demo", telemetry=telemetry)
|
|
47
|
+
events = EchoAdapter().run(context)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Scope
|
|
51
|
+
|
|
52
|
+
This milestone intentionally does not add LangGraph, React, CLI commands, or FastAPI application code.
|
|
53
|
+
|
genailit-0.0.1/README.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# GenAILit
|
|
2
|
+
|
|
3
|
+
GenAILit is a small Python base for building web interfaces for multi-agent systems.
|
|
4
|
+
|
|
5
|
+
This milestone only includes the package foundation:
|
|
6
|
+
|
|
7
|
+
- `GenAILitEvent`
|
|
8
|
+
- `TelemetryStore`
|
|
9
|
+
- `AdapterContext`
|
|
10
|
+
- `BaseAgentAdapter`
|
|
11
|
+
|
|
12
|
+
## Requirements
|
|
13
|
+
|
|
14
|
+
- Python 3.10+
|
|
15
|
+
- `pydantic>=2`
|
|
16
|
+
- `pytest` for tests
|
|
17
|
+
|
|
18
|
+
## Install
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pip install genailit
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Example
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
from genailit import AdapterContext, BaseAgentAdapter, GenAILitEvent, TelemetryStore
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class EchoAdapter(BaseAgentAdapter):
|
|
31
|
+
def build_events(self, context: AdapterContext):
|
|
32
|
+
yield GenAILitEvent(name="ready")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
telemetry = TelemetryStore()
|
|
36
|
+
context = AdapterContext(session_id="demo", telemetry=telemetry)
|
|
37
|
+
events = EchoAdapter().run(context)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Scope
|
|
41
|
+
|
|
42
|
+
This milestone intentionally does not add LangGraph, React, CLI commands, or FastAPI application code.
|
|
43
|
+
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "genailit"
|
|
7
|
+
version = "0.0.1"
|
|
8
|
+
description = "Open source Python library for multi-agent web interfaces."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"pydantic>=2",
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
[project.optional-dependencies]
|
|
16
|
+
dev = [
|
|
17
|
+
"pytest",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
[tool.hatch.build.targets.wheel]
|
|
21
|
+
packages = ["src/genailit"]
|
|
22
|
+
|
|
23
|
+
[tool.pytest.ini_options]
|
|
24
|
+
testpaths = ["tests"]
|
|
25
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from .adapters import AdapterContext, BaseAgentAdapter
|
|
2
|
+
from .events import GenAILitEvent
|
|
3
|
+
from .telemetry import TelemetryStore
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"AdapterContext",
|
|
7
|
+
"BaseAgentAdapter",
|
|
8
|
+
"GenAILitEvent",
|
|
9
|
+
"TelemetryStore",
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
__version__ = "0.0.1"
|
|
13
|
+
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
from dataclasses import dataclass, field
|
|
5
|
+
from collections.abc import Iterable, Mapping
|
|
6
|
+
from typing import Any
|
|
7
|
+
|
|
8
|
+
from ..events import GenAILitEvent
|
|
9
|
+
from ..telemetry import TelemetryStore
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass(frozen=True, slots=True)
|
|
13
|
+
class AdapterContext:
|
|
14
|
+
session_id: str
|
|
15
|
+
telemetry: TelemetryStore | None = None
|
|
16
|
+
metadata: Mapping[str, Any] = field(default_factory=dict)
|
|
17
|
+
|
|
18
|
+
def with_metadata(self, **items: Any) -> "AdapterContext":
|
|
19
|
+
merged = dict(self.metadata)
|
|
20
|
+
merged.update(items)
|
|
21
|
+
return AdapterContext(
|
|
22
|
+
session_id=self.session_id,
|
|
23
|
+
telemetry=self.telemetry,
|
|
24
|
+
metadata=merged,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class BaseAgentAdapter(ABC):
|
|
29
|
+
@abstractmethod
|
|
30
|
+
def build_events(self, context: AdapterContext) -> Iterable[GenAILitEvent]:
|
|
31
|
+
raise NotImplementedError
|
|
32
|
+
|
|
33
|
+
def run(self, context: AdapterContext) -> tuple[GenAILitEvent, ...]:
|
|
34
|
+
events = tuple(self.build_events(context))
|
|
35
|
+
if context.telemetry is not None:
|
|
36
|
+
context.telemetry.extend(events)
|
|
37
|
+
return events
|
|
38
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class GenAILitEvent(BaseModel):
|
|
9
|
+
model_config = ConfigDict(extra="forbid", frozen=True)
|
|
10
|
+
|
|
11
|
+
name: str
|
|
12
|
+
payload: dict[str, Any] = Field(default_factory=dict)
|
|
13
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Iterable
|
|
4
|
+
|
|
5
|
+
from .events import GenAILitEvent
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class TelemetryStore:
|
|
9
|
+
def __init__(self) -> None:
|
|
10
|
+
self._events: list[GenAILitEvent] = []
|
|
11
|
+
|
|
12
|
+
def record(self, event: GenAILitEvent) -> None:
|
|
13
|
+
self._events.append(event)
|
|
14
|
+
|
|
15
|
+
def extend(self, events: Iterable[GenAILitEvent]) -> None:
|
|
16
|
+
self._events.extend(events)
|
|
17
|
+
|
|
18
|
+
def snapshot(self) -> tuple[GenAILitEvent, ...]:
|
|
19
|
+
return tuple(self._events)
|
|
20
|
+
|
|
21
|
+
def clear(self) -> None:
|
|
22
|
+
self._events.clear()
|
|
23
|
+
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from genailit import AdapterContext, BaseAgentAdapter, GenAILitEvent, TelemetryStore
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_base_agent_adapter_is_abstract() -> None:
|
|
7
|
+
with pytest.raises(TypeError):
|
|
8
|
+
BaseAgentAdapter() # type: ignore[abstract]
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def test_base_agent_adapter_runs_and_records_telemetry() -> None:
|
|
12
|
+
class DemoAdapter(BaseAgentAdapter):
|
|
13
|
+
def build_events(self, context: AdapterContext):
|
|
14
|
+
yield GenAILitEvent(name="ready", payload={"session_id": context.session_id})
|
|
15
|
+
|
|
16
|
+
telemetry = TelemetryStore()
|
|
17
|
+
context = AdapterContext(session_id="abc", telemetry=telemetry)
|
|
18
|
+
|
|
19
|
+
events = DemoAdapter().run(context)
|
|
20
|
+
|
|
21
|
+
assert events == (GenAILitEvent(name="ready", payload={"session_id": "abc"}),)
|
|
22
|
+
assert telemetry.snapshot() == events
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_adapter_context_merges_metadata() -> None:
|
|
26
|
+
context = AdapterContext(session_id="abc", metadata={"alpha": 1})
|
|
27
|
+
|
|
28
|
+
updated = context.with_metadata(beta=2)
|
|
29
|
+
|
|
30
|
+
assert updated.session_id == "abc"
|
|
31
|
+
assert updated.metadata == {"alpha": 1, "beta": 2}
|
|
32
|
+
assert context.metadata == {"alpha": 1}
|
|
33
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from genailit import GenAILitEvent
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_genailit_event_models_name_and_payload() -> None:
|
|
7
|
+
event = GenAILitEvent(name="step_started", payload={"step": 1})
|
|
8
|
+
|
|
9
|
+
assert event.name == "step_started"
|
|
10
|
+
assert event.payload == {"step": 1}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def test_genailit_event_rejects_unknown_fields() -> None:
|
|
14
|
+
with pytest.raises(ValueError):
|
|
15
|
+
GenAILitEvent(name="x", unknown=True) # type: ignore[call-arg]
|
|
16
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from genailit import GenAILitEvent, TelemetryStore
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def test_telemetry_store_records_and_clears_events() -> None:
|
|
5
|
+
store = TelemetryStore()
|
|
6
|
+
first = GenAILitEvent(name="a")
|
|
7
|
+
second = GenAILitEvent(name="b")
|
|
8
|
+
|
|
9
|
+
store.record(first)
|
|
10
|
+
store.extend([second])
|
|
11
|
+
|
|
12
|
+
assert store.snapshot() == (first, second)
|
|
13
|
+
|
|
14
|
+
store.clear()
|
|
15
|
+
|
|
16
|
+
assert store.snapshot() == ()
|
|
17
|
+
|