copilotkit-intelligence-runtime 0.1.0__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.
@@ -0,0 +1,77 @@
1
+ """Public configuration and trusted request identity."""
2
+
3
+ from dataclasses import dataclass, field
4
+ from typing import Any
5
+ from urllib.parse import urlsplit
6
+
7
+ Json = dict[str, Any]
8
+
9
+
10
+ @dataclass(frozen=True)
11
+ class User:
12
+ """Application user returned by the host's authentication callback."""
13
+
14
+ id: str
15
+ name: str = ""
16
+
17
+
18
+ @dataclass(frozen=True)
19
+ class RuntimeConfig:
20
+ """Intelligence transport settings. Credentials never reach the browser."""
21
+
22
+ api_key: str = field(repr=False)
23
+ api_url: str = "https://api.intelligence.copilotkit.ai"
24
+ runner_url: str = "wss://realtime.intelligence.copilotkit.ai/runner"
25
+ client_url: str = "wss://realtime.intelligence.copilotkit.ai/client"
26
+ base_path: str = "/copilotkit"
27
+ request_timeout: float = 30
28
+ ack_timeout: float = 10
29
+ max_delivery_attempts: int = 5
30
+ lock_ttl_seconds: int = 60
31
+ lock_heartbeat_seconds: float = 20
32
+ max_body_bytes: int = 2 * 1024 * 1024
33
+ shutdown_timeout: float = 15
34
+ allowed_origins: tuple[str, ...] = ()
35
+ telemetry_enabled: bool = True
36
+
37
+ def __post_init__(self) -> None:
38
+ """Reject unusable credentials, URLs, and unbounded transport settings."""
39
+ if not self.api_key.strip():
40
+ raise ValueError("api_key is required")
41
+ for value, schemes in [
42
+ (self.api_url, ("http", "https")),
43
+ (self.runner_url, ("ws", "wss")),
44
+ (self.client_url, ("ws", "wss")),
45
+ ]:
46
+ parsed = urlsplit(value)
47
+ if parsed.scheme not in schemes or not parsed.hostname or parsed.username:
48
+ raise ValueError("Invalid Intelligence endpoint URL")
49
+ if not self.base_path.startswith("/"):
50
+ raise ValueError("base_path must start with /")
51
+ if (
52
+ min(
53
+ self.request_timeout,
54
+ self.ack_timeout,
55
+ self.max_delivery_attempts,
56
+ self.lock_ttl_seconds,
57
+ self.lock_heartbeat_seconds,
58
+ self.max_body_bytes,
59
+ self.shutdown_timeout,
60
+ )
61
+ <= 0
62
+ ):
63
+ raise ValueError("Transport limits must be positive")
64
+ if self.lock_heartbeat_seconds >= self.lock_ttl_seconds:
65
+ raise ValueError("Heartbeat must precede lock expiry")
66
+
67
+
68
+ class RuntimeErrorResponse(Exception):
69
+ """A sanitized HTTP failure safe to return to a runtime client."""
70
+
71
+ def __init__(self, status: int, message: str) -> None:
72
+ super().__init__(message)
73
+ self.status = status
74
+
75
+
76
+ class PlatformError(RuntimeErrorResponse):
77
+ """Intelligence returned a non-success status or invalid response."""
@@ -0,0 +1,67 @@
1
+ """Authenticated Intelligence HTTP transport."""
2
+
3
+ from typing import Any
4
+ from urllib.parse import quote
5
+
6
+ import httpx
7
+
8
+ from copilotkit_intelligence import Intelligence, IntelligenceError
9
+
10
+ from .models import Json, PlatformError, RuntimeConfig
11
+
12
+
13
+ def segment(value: str) -> str:
14
+ """Encode an opaque identifier as one URL path segment."""
15
+ return quote(value, safe="")
16
+
17
+
18
+ class Platform:
19
+ """Use one pooled client with no automatic non-idempotent HTTP retries."""
20
+
21
+ def __init__(
22
+ self,
23
+ config: RuntimeConfig,
24
+ client: httpx.AsyncClient,
25
+ intelligence: Intelligence | None = None,
26
+ ) -> None:
27
+ self.config = config
28
+ self.client = client
29
+ self.intelligence = intelligence or Intelligence(
30
+ api_key=config.api_key,
31
+ api_url=config.api_url,
32
+ runner_url=config.runner_url,
33
+ client_url=config.client_url,
34
+ request_timeout=config.request_timeout,
35
+ http_client=client,
36
+ )
37
+
38
+ async def request(
39
+ self,
40
+ method: str,
41
+ path: str,
42
+ body: Json | None = None,
43
+ query: Json | None = None,
44
+ headers: dict[str, str] | None = None,
45
+ ) -> Any:
46
+ """Call Intelligence, retaining status but never exposing upstream bodies."""
47
+ try:
48
+ return await self.intelligence._request(method, path, body, query, headers)
49
+ except IntelligenceError as error:
50
+ raise PlatformError(error.status, str(error)) from error
51
+
52
+ async def get_or_create_thread(self, body: Json) -> None:
53
+ """Read before creating and resolve a concurrent create through a scoped read."""
54
+ path = "/api/threads/" + segment(body["threadId"])
55
+ query = {"userId": body["userId"]}
56
+ try:
57
+ await self.request("GET", path, query=query)
58
+ return
59
+ except PlatformError as error:
60
+ if error.status != 404:
61
+ raise
62
+ try:
63
+ await self.request("POST", "/api/threads", body)
64
+ except PlatformError as error:
65
+ if error.status != 409:
66
+ raise
67
+ await self.request("GET", path, query=query)
File without changes