connectonion 0.5.3__py3-none-any.whl → 0.5.5__py3-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.
- connectonion/__init__.py +1 -1
- connectonion/asgi.py +14 -1
- connectonion/host.py +17 -11
- connectonion/usage.py +10 -5
- {connectonion-0.5.3.dist-info → connectonion-0.5.5.dist-info}/METADATA +1 -1
- {connectonion-0.5.3.dist-info → connectonion-0.5.5.dist-info}/RECORD +8 -8
- {connectonion-0.5.3.dist-info → connectonion-0.5.5.dist-info}/WHEEL +0 -0
- {connectonion-0.5.3.dist-info → connectonion-0.5.5.dist-info}/entry_points.txt +0 -0
connectonion/__init__.py
CHANGED
connectonion/asgi.py
CHANGED
|
@@ -9,6 +9,19 @@ See: docs/design-decisions/022-raw-asgi-implementation.md
|
|
|
9
9
|
import json
|
|
10
10
|
from pathlib import Path
|
|
11
11
|
|
|
12
|
+
from pydantic import BaseModel
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _json_default(obj):
|
|
16
|
+
"""Handle non-serializable objects like Pydantic models.
|
|
17
|
+
|
|
18
|
+
This enables native JSON serialization for Pydantic BaseModel instances
|
|
19
|
+
nested in API response dicts, following FastAPI's pattern.
|
|
20
|
+
"""
|
|
21
|
+
if isinstance(obj, BaseModel):
|
|
22
|
+
return obj.model_dump()
|
|
23
|
+
raise TypeError(f"Object of type {type(obj).__name__} is not JSON serializable")
|
|
24
|
+
|
|
12
25
|
|
|
13
26
|
async def read_body(receive) -> bytes:
|
|
14
27
|
"""Read complete request body from ASGI receive."""
|
|
@@ -23,7 +36,7 @@ async def read_body(receive) -> bytes:
|
|
|
23
36
|
|
|
24
37
|
async def send_json(send, data: dict, status: int = 200):
|
|
25
38
|
"""Send JSON response via ASGI send."""
|
|
26
|
-
body = json.dumps(data).encode()
|
|
39
|
+
body = json.dumps(data, default=_json_default).encode()
|
|
27
40
|
await send({"type": "http.response.start", "status": status,
|
|
28
41
|
"headers": [[b"content-type", b"application/json"]]})
|
|
29
42
|
await send({"type": "http.response.body", "body": body})
|
connectonion/host.py
CHANGED
|
@@ -16,10 +16,10 @@ import logging
|
|
|
16
16
|
import os
|
|
17
17
|
import time
|
|
18
18
|
import uuid
|
|
19
|
-
from dataclasses import dataclass, asdict
|
|
20
19
|
from pathlib import Path
|
|
21
|
-
from typing import Union
|
|
20
|
+
from typing import Optional, Union
|
|
22
21
|
|
|
22
|
+
from pydantic import BaseModel
|
|
23
23
|
from rich.console import Console
|
|
24
24
|
from rich.panel import Panel
|
|
25
25
|
|
|
@@ -38,15 +38,21 @@ def get_default_trust() -> str:
|
|
|
38
38
|
|
|
39
39
|
# === Types ===
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
class Session(BaseModel):
|
|
42
|
+
"""Session record for tracking agent requests.
|
|
43
|
+
|
|
44
|
+
Uses Pydantic BaseModel for:
|
|
45
|
+
- Native JSON serialization via .model_dump()
|
|
46
|
+
- Type validation
|
|
47
|
+
- API response compatibility
|
|
48
|
+
"""
|
|
43
49
|
session_id: str
|
|
44
50
|
status: str
|
|
45
51
|
prompt: str
|
|
46
|
-
result: str = None
|
|
47
|
-
created: float = None
|
|
48
|
-
expires: float = None
|
|
49
|
-
duration_ms: int = None
|
|
52
|
+
result: Optional[str] = None
|
|
53
|
+
created: Optional[float] = None
|
|
54
|
+
expires: Optional[float] = None
|
|
55
|
+
duration_ms: Optional[int] = None
|
|
50
56
|
|
|
51
57
|
|
|
52
58
|
# === Storage ===
|
|
@@ -60,7 +66,7 @@ class SessionStorage:
|
|
|
60
66
|
|
|
61
67
|
def save(self, session: Session):
|
|
62
68
|
with open(self.path, "a") as f:
|
|
63
|
-
f.write(
|
|
69
|
+
f.write(session.model_dump_json() + "\n")
|
|
64
70
|
|
|
65
71
|
def get(self, session_id: str) -> Session | None:
|
|
66
72
|
if not self.path.exists():
|
|
@@ -149,12 +155,12 @@ def input_handler(agent, storage: SessionStorage, prompt: str, result_ttl: int,
|
|
|
149
155
|
def session_handler(storage: SessionStorage, session_id: str) -> dict | None:
|
|
150
156
|
"""GET /sessions/{id}"""
|
|
151
157
|
session = storage.get(session_id)
|
|
152
|
-
return
|
|
158
|
+
return session.model_dump() if session else None
|
|
153
159
|
|
|
154
160
|
|
|
155
161
|
def sessions_handler(storage: SessionStorage) -> dict:
|
|
156
162
|
"""GET /sessions"""
|
|
157
|
-
return {"sessions": [
|
|
163
|
+
return {"sessions": [s.model_dump() for s in storage.list()]}
|
|
158
164
|
|
|
159
165
|
|
|
160
166
|
def health_handler(agent, start_time: float) -> dict:
|
connectonion/usage.py
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Purpose: Token usage tracking and cost calculation for LLM calls
|
|
3
3
|
LLM-Note:
|
|
4
|
-
Dependencies:
|
|
4
|
+
Dependencies: pydantic | imported by [llm.py, agent.py]
|
|
5
5
|
Data flow: receives model name + token counts → returns cost in USD
|
|
6
6
|
Integration: exposes TokenUsage, MODEL_PRICING, MODEL_CONTEXT_LIMITS, calculate_cost(), get_context_limit()
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
|
-
from
|
|
9
|
+
from pydantic import BaseModel
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
class TokenUsage(BaseModel):
|
|
13
|
+
"""Token usage from a single LLM call.
|
|
14
|
+
|
|
15
|
+
Uses Pydantic BaseModel for:
|
|
16
|
+
- Native JSON serialization via .model_dump()
|
|
17
|
+
- Type validation at runtime
|
|
18
|
+
- Future-proof API response compatibility
|
|
19
|
+
"""
|
|
15
20
|
input_tokens: int = 0
|
|
16
21
|
output_tokens: int = 0
|
|
17
22
|
cached_tokens: int = 0 # Tokens read from cache (subset of input_tokens)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: connectonion
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.5
|
|
4
4
|
Summary: A simple Python framework for creating AI agents with behavior tracking
|
|
5
5
|
Project-URL: Homepage, https://github.com/openonion/connectonion
|
|
6
6
|
Project-URL: Documentation, https://docs.connectonion.com
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
connectonion/__init__.py,sha256=
|
|
1
|
+
connectonion/__init__.py,sha256=GD9bUY240o5usP-GNHm2n2o_sYwBhITqSCecZxhkRWw,1887
|
|
2
2
|
connectonion/address.py,sha256=YOzpMOej-HqJUE6o0i0fG8rB7HM-Iods36s9OD--5ig,10852
|
|
3
3
|
connectonion/agent.py,sha256=BHnP4N0odXCSn9xT0QnJpXj3VV-E_vUtNXJ0M6k3RNs,18889
|
|
4
4
|
connectonion/announce.py,sha256=47Lxe8S4yyTbpsmYUmakU_DehrGvljyldmPfKnAOrFQ,3365
|
|
5
|
-
connectonion/asgi.py,sha256=
|
|
5
|
+
connectonion/asgi.py,sha256=lKjwTOUmCQkytmS9iJ14pBUJzb-Ucww_7q8-hVQVCPY,7682
|
|
6
6
|
connectonion/auto_debug_exception.py,sha256=iA-b5GC40AI4YVXen2UCkDkfHLVZehFPgZrinIxykWI,8147
|
|
7
7
|
connectonion/connect.py,sha256=dn5dWDkZZpKGW5St-CtAAfTM2-1IOe3luv0vQSA2ogk,5311
|
|
8
8
|
connectonion/console.py,sha256=6_J1ItkLJCHDpdJY-tCuw4jMcS09S-a5juZSDSIr1Nc,21254
|
|
9
9
|
connectonion/debugger_ui.py,sha256=QMyoZkhGbt-pStHHjpnCBXtfzvfqPW94tXiL07KZiAw,41741
|
|
10
10
|
connectonion/decorators.py,sha256=YFmZMptcchIgNriKFf_vOyacor5i_j6Cy_igTJhdKm4,7141
|
|
11
11
|
connectonion/events.py,sha256=jJOMt1PhRl-ef4R8-WpAq8pUbZ8GKIl0wOB2kJUVyWg,9151
|
|
12
|
-
connectonion/host.py,sha256=
|
|
12
|
+
connectonion/host.py,sha256=PkBZmmy9mjium1ELctr7ilScsvrgXM0PFAumW4IzqM4,18300
|
|
13
13
|
connectonion/interactive_debugger.py,sha256=XHSCGJp9YV6VAZM1gk_AuxKAdBODJQUcLVWaLuTMqv0,16277
|
|
14
14
|
connectonion/llm.py,sha256=IzjlOT6Dj5xIplIymjcaHZ_abwE5wDHEE4pa8zjlEGY,32952
|
|
15
15
|
connectonion/llm_do.py,sha256=YI7kGFKpB6KUEG_CKtP3Bl4IWmRac7TCa9GK5FSV624,12000
|
|
@@ -22,7 +22,7 @@ connectonion/tool_registry.py,sha256=rTe8RJnWXpmHXWznP468fhWvmRknk-TlF9Iz8G9_qus
|
|
|
22
22
|
connectonion/trust.py,sha256=It4ueuMvCmHOD7FwaV-jSwlonWFsFgNH1gz9fJtmfW4,6692
|
|
23
23
|
connectonion/trust_agents.py,sha256=XDedEhxGRfu9KeYhX-Z1a5tRA-2Zbwz4ztnlA2Lnaf0,2968
|
|
24
24
|
connectonion/trust_functions.py,sha256=jRgfPm5z8oy9x8IYJd20UUMCz7cc1Pd7zyqQK5SDdLc,3564
|
|
25
|
-
connectonion/usage.py,sha256=
|
|
25
|
+
connectonion/usage.py,sha256=mS_J5it9NMDI1CjycNUJEnXGNXAo1lQ1ICEZvqftTpU,6205
|
|
26
26
|
connectonion/xray.py,sha256=TA_VychqQRtfSzO3RmTqnDZZNx3LjycbgUWVyMswAIw,18542
|
|
27
27
|
connectonion/cli/__init__.py,sha256=Pd1iKp0rUghs2kmdAhyp9hK8j0uWkNxOagBkdCGrG4I,55
|
|
28
28
|
connectonion/cli/docs.md,sha256=Fk_JT8jFXXDpXTvU0ZUigMW1UR6ERmX-HDheYPPRNY8,3231
|
|
@@ -107,7 +107,7 @@ connectonion/useful_tools/slash_command.py,sha256=VKl7SKLyaxHcHwfE8rgzBCQ2-KQtL0
|
|
|
107
107
|
connectonion/useful_tools/terminal.py,sha256=PtzGHN6vnWROmssi37YOZ5U-d0Z7Fe79bocoKAngoxg,9330
|
|
108
108
|
connectonion/useful_tools/todo_list.py,sha256=wVEt4kt-MczIcP3xvKelfshGHZ6EATpDFzQx0zov8cw,7483
|
|
109
109
|
connectonion/useful_tools/web_fetch.py,sha256=CysJLOdDIkbMVJ12Dj3WgsytLu1-o2wrwNopqA_S1jk,7253
|
|
110
|
-
connectonion-0.5.
|
|
111
|
-
connectonion-0.5.
|
|
112
|
-
connectonion-0.5.
|
|
113
|
-
connectonion-0.5.
|
|
110
|
+
connectonion-0.5.5.dist-info/METADATA,sha256=eAQTWZLZiuahMr5qb9pcrkLj4vNIMR0-kDcE3z0F_f0,21902
|
|
111
|
+
connectonion-0.5.5.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
112
|
+
connectonion-0.5.5.dist-info/entry_points.txt,sha256=XDB-kVN7Qgy4DmYTkjQB_O6hZeUND-SqmZbdoQPn6WA,90
|
|
113
|
+
connectonion-0.5.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|