orkaia 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,19 @@
1
+ # Python
2
+ __pycache__/
3
+ *.pyc
4
+ *.pyo
5
+ .venv/
6
+ venv/
7
+ *.egg-info/
8
+ .env
9
+
10
+ # Node
11
+ node_modules/
12
+ .next/
13
+ .env.local
14
+ .env*.local
15
+
16
+ # OS
17
+ .DS_Store
18
+ *.log
19
+ .vercel
orkaia-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,95 @@
1
+ Metadata-Version: 2.4
2
+ Name: orkaia
3
+ Version: 0.1.0
4
+ Summary: Governance and audit SDK for AI agents
5
+ Project-URL: Homepage, https://orka.ia.br
6
+ Project-URL: Documentation, https://orka.ia.br/docs
7
+ Project-URL: Repository, https://github.com/orka-runtime/orka-sdk
8
+ License: MIT
9
+ Keywords: agents,ai,audit,compliance,eu-ai-act,governance
10
+ Requires-Python: >=3.10
11
+ Requires-Dist: httpx>=0.27.0
12
+ Description-Content-Type: text/markdown
13
+
14
+ # orka-sdk
15
+
16
+ Governance and audit SDK for AI agents. Add policy enforcement, immutable audit trails, and trust scoring to any agent with one decorator.
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ pip install orka-sdk
22
+ ```
23
+
24
+ ## Quickstart
25
+
26
+ ```python
27
+ import orka
28
+
29
+ # Initialize once at startup (get your API key at orka.ia.br)
30
+ orka.init(api_key="orka_your_key_here")
31
+
32
+ # Wrap any agent function
33
+ @orka.guard(agent_id="your-agent-uuid", task_type="summarize")
34
+ def summarize(text: str) -> str:
35
+ return openai_client.chat(text)
36
+
37
+ # Works with async too
38
+ @orka.guard(agent_id="your-agent-uuid", task_type="financial_transfer", risk="HIGH")
39
+ async def transfer_funds(amount: float, to_account: str) -> dict:
40
+ return await payment_api.transfer(amount, to_account)
41
+ ```
42
+
43
+ That's it. Every call now:
44
+ - ✅ Checks your X-Shield policies before executing
45
+ - ✅ Logs to X-Ledger with immutable hash chain
46
+ - ✅ Updates the agent's trust score
47
+ - ✅ Blocks execution if policy denies it (raises `OrkaPolicyBlocked`)
48
+
49
+ ## Handle policy blocks
50
+
51
+ ```python
52
+ from orka import OrkaPolicyBlocked
53
+
54
+ try:
55
+ result = transfer_funds(10000, "acc_123")
56
+ except OrkaPolicyBlocked as e:
57
+ print(f"Blocked: {e.reason}")
58
+ print(f"Policy: {e.policy_name}")
59
+ ```
60
+
61
+ ## Works with LangChain, CrewAI, any framework
62
+
63
+ ```python
64
+ from langchain.agents import AgentExecutor
65
+ import orka
66
+
67
+ orka.init(api_key="orka_...")
68
+
69
+ @orka.guard(agent_id="langchain-agent-uuid", task_type="web_search")
70
+ def run_agent(query: str) -> str:
71
+ return agent_executor.invoke({"input": query})
72
+ ```
73
+
74
+ ## Never breaks your production code
75
+
76
+ If Orka is unreachable, your agent continues running. Governance failures are silent — your users never see Orka errors.
77
+
78
+ ## Risk levels
79
+
80
+ ```python
81
+ @orka.guard(agent_id="...", task_type="...", risk="HIGH")
82
+ # EU AI Act risk classification: UNACCEPTABLE | HIGH | LIMITED | MINIMAL | NONE
83
+ ```
84
+
85
+ ## Environment variables
86
+
87
+ ```bash
88
+ ORKA_API_KEY=orka_your_key
89
+ ORKA_BASE_URL=https://orka-backend.onrender.com/api/v1 # optional
90
+ ```
91
+
92
+ ```python
93
+ import os, orka
94
+ orka.init(api_key=os.environ["ORKA_API_KEY"])
95
+ ```
orkaia-0.1.0/README.md ADDED
@@ -0,0 +1,82 @@
1
+ # orka-sdk
2
+
3
+ Governance and audit SDK for AI agents. Add policy enforcement, immutable audit trails, and trust scoring to any agent with one decorator.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install orka-sdk
9
+ ```
10
+
11
+ ## Quickstart
12
+
13
+ ```python
14
+ import orka
15
+
16
+ # Initialize once at startup (get your API key at orka.ia.br)
17
+ orka.init(api_key="orka_your_key_here")
18
+
19
+ # Wrap any agent function
20
+ @orka.guard(agent_id="your-agent-uuid", task_type="summarize")
21
+ def summarize(text: str) -> str:
22
+ return openai_client.chat(text)
23
+
24
+ # Works with async too
25
+ @orka.guard(agent_id="your-agent-uuid", task_type="financial_transfer", risk="HIGH")
26
+ async def transfer_funds(amount: float, to_account: str) -> dict:
27
+ return await payment_api.transfer(amount, to_account)
28
+ ```
29
+
30
+ That's it. Every call now:
31
+ - ✅ Checks your X-Shield policies before executing
32
+ - ✅ Logs to X-Ledger with immutable hash chain
33
+ - ✅ Updates the agent's trust score
34
+ - ✅ Blocks execution if policy denies it (raises `OrkaPolicyBlocked`)
35
+
36
+ ## Handle policy blocks
37
+
38
+ ```python
39
+ from orka import OrkaPolicyBlocked
40
+
41
+ try:
42
+ result = transfer_funds(10000, "acc_123")
43
+ except OrkaPolicyBlocked as e:
44
+ print(f"Blocked: {e.reason}")
45
+ print(f"Policy: {e.policy_name}")
46
+ ```
47
+
48
+ ## Works with LangChain, CrewAI, any framework
49
+
50
+ ```python
51
+ from langchain.agents import AgentExecutor
52
+ import orka
53
+
54
+ orka.init(api_key="orka_...")
55
+
56
+ @orka.guard(agent_id="langchain-agent-uuid", task_type="web_search")
57
+ def run_agent(query: str) -> str:
58
+ return agent_executor.invoke({"input": query})
59
+ ```
60
+
61
+ ## Never breaks your production code
62
+
63
+ If Orka is unreachable, your agent continues running. Governance failures are silent — your users never see Orka errors.
64
+
65
+ ## Risk levels
66
+
67
+ ```python
68
+ @orka.guard(agent_id="...", task_type="...", risk="HIGH")
69
+ # EU AI Act risk classification: UNACCEPTABLE | HIGH | LIMITED | MINIMAL | NONE
70
+ ```
71
+
72
+ ## Environment variables
73
+
74
+ ```bash
75
+ ORKA_API_KEY=orka_your_key
76
+ ORKA_BASE_URL=https://orka-backend.onrender.com/api/v1 # optional
77
+ ```
78
+
79
+ ```python
80
+ import os, orka
81
+ orka.init(api_key=os.environ["ORKA_API_KEY"])
82
+ ```
@@ -0,0 +1,25 @@
1
+ from .client import OrkaClient
2
+ from .decorators import guard
3
+ from .exceptions import OrkaAuthError, OrkaConnectionError, OrkaPolicyBlocked
4
+
5
+ _client: OrkaClient | None = None
6
+
7
+
8
+ def init(api_key: str, base_url: str = "https://orka-backend.onrender.com/api/v1") -> OrkaClient:
9
+ """Initialize the Orka SDK. Call once at startup.
10
+
11
+ Args:
12
+ api_key: Your Orka API key (from dashboard → API Keys)
13
+ base_url: Orka backend URL (default: production)
14
+
15
+ Example:
16
+ import orka
17
+ orka.init(api_key="orka_your_key_here")
18
+ """
19
+ global _client
20
+ _client = OrkaClient(api_key=api_key, base_url=base_url)
21
+ return _client
22
+
23
+
24
+ __all__ = ["init", "guard", "OrkaClient", "OrkaPolicyBlocked", "OrkaAuthError", "OrkaConnectionError"]
25
+ __version__ = "0.1.0"
@@ -0,0 +1,91 @@
1
+ import asyncio
2
+ import time
3
+ import uuid
4
+ from typing import Any
5
+
6
+ import httpx
7
+
8
+ from .exceptions import OrkaAuthError, OrkaConnectionError, OrkaPolicyBlocked
9
+
10
+
11
+ class OrkaClient:
12
+ def __init__(self, api_key: str, base_url: str = "https://orka-backend.onrender.com/api/v1"):
13
+ self.api_key = api_key
14
+ self.base_url = base_url.rstrip("/")
15
+ self._headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
16
+
17
+ def _sync_request(self, method: str, path: str, **kwargs) -> dict:
18
+ try:
19
+ with httpx.Client(timeout=10) as client:
20
+ r = client.request(method, f"{self.base_url}{path}", headers=self._headers, **kwargs)
21
+ if r.status_code == 401:
22
+ raise OrkaAuthError("Invalid API key")
23
+ if r.status_code == 403:
24
+ data = r.json()
25
+ raise OrkaPolicyBlocked(
26
+ reason=data.get("reason", "Policy denied"),
27
+ policy_name=data.get("policy_name"),
28
+ )
29
+ r.raise_for_status()
30
+ return r.json() if r.content else {}
31
+ except httpx.ConnectError as e:
32
+ raise OrkaConnectionError(f"Cannot reach Orka at {self.base_url}") from e
33
+
34
+ async def _async_request(self, method: str, path: str, **kwargs) -> dict:
35
+ try:
36
+ async with httpx.AsyncClient(timeout=10) as client:
37
+ r = await client.request(method, f"{self.base_url}{path}", headers=self._headers, **kwargs)
38
+ if r.status_code == 401:
39
+ raise OrkaAuthError("Invalid API key")
40
+ if r.status_code == 403:
41
+ data = r.json()
42
+ raise OrkaPolicyBlocked(
43
+ reason=data.get("reason", "Policy denied"),
44
+ policy_name=data.get("policy_name"),
45
+ )
46
+ r.raise_for_status()
47
+ return r.json() if r.content else {}
48
+ except httpx.ConnectError as e:
49
+ raise OrkaConnectionError(f"Cannot reach Orka at {self.base_url}") from e
50
+
51
+ def check_policy(self, agent_id: str, task_type: str, payload: dict) -> dict:
52
+ return self._sync_request("POST", "/xshield/check", json={
53
+ "agent_id": agent_id,
54
+ "task_type": task_type,
55
+ "payload": payload,
56
+ })
57
+
58
+ async def check_policy_async(self, agent_id: str, task_type: str, payload: dict) -> dict:
59
+ return await self._async_request("POST", "/xshield/check", json={
60
+ "agent_id": agent_id,
61
+ "task_type": task_type,
62
+ "payload": payload,
63
+ })
64
+
65
+ def log_execution(self, agent_id: str, task_type: str, status: str,
66
+ input_payload: dict, output_payload: Any = None,
67
+ error: str | None = None, duration_ms: int = 0) -> dict:
68
+ return self._sync_request("POST", "/executions", json={
69
+ "requesting_agent_id": agent_id,
70
+ "executing_agent_target": agent_id,
71
+ "task_type": task_type,
72
+ "task_payload": input_payload,
73
+ "status": status,
74
+ "output_payload": output_payload,
75
+ "error": error,
76
+ "duration_ms": duration_ms,
77
+ })
78
+
79
+ async def log_execution_async(self, agent_id: str, task_type: str, status: str,
80
+ input_payload: dict, output_payload: Any = None,
81
+ error: str | None = None, duration_ms: int = 0) -> dict:
82
+ return await self._async_request("POST", "/executions", json={
83
+ "requesting_agent_id": agent_id,
84
+ "executing_agent_target": agent_id,
85
+ "task_type": task_type,
86
+ "task_payload": input_payload,
87
+ "status": status,
88
+ "output_payload": output_payload,
89
+ "error": error,
90
+ "duration_ms": duration_ms,
91
+ })
@@ -0,0 +1,123 @@
1
+ import asyncio
2
+ import functools
3
+ import time
4
+ from typing import Any, Callable, Literal
5
+
6
+ from .exceptions import OrkaPolicyBlocked
7
+
8
+ RiskLevel = Literal["UNACCEPTABLE", "HIGH", "LIMITED", "MINIMAL", "NONE"]
9
+
10
+
11
+ def guard(
12
+ agent_id: str,
13
+ task_type: str,
14
+ risk: RiskLevel = "MINIMAL",
15
+ block_on_policy: bool = True,
16
+ ):
17
+ """
18
+ Decorator that wraps any function with Orka governance.
19
+
20
+ - Checks X-Shield policies before execution
21
+ - Logs result to X-Ledger after execution
22
+ - Updates trust score automatically
23
+
24
+ Usage:
25
+ @orka.guard(agent_id="uuid", task_type="summarize")
26
+ def my_agent(text: str) -> str:
27
+ return llm.call(text)
28
+
29
+ @orka.guard(agent_id="uuid", task_type="transfer", risk="HIGH")
30
+ async def transfer_funds(amount: float) -> dict:
31
+ ...
32
+ """
33
+ from . import _client
34
+
35
+ def decorator(fn: Callable) -> Callable:
36
+ if asyncio.iscoroutinefunction(fn):
37
+ @functools.wraps(fn)
38
+ async def async_wrapper(*args, **kwargs):
39
+ if _client is None:
40
+ return await fn(*args, **kwargs)
41
+
42
+ input_payload = {"args": list(args), "kwargs": kwargs}
43
+ start = time.monotonic()
44
+
45
+ try:
46
+ await _client.check_policy_async(agent_id, task_type, input_payload)
47
+ except OrkaPolicyBlocked:
48
+ if block_on_policy:
49
+ raise
50
+ except Exception:
51
+ pass # never block execution due to Orka connectivity issues
52
+
53
+ error = None
54
+ output = None
55
+ status = "COMPLETED"
56
+ try:
57
+ output = await fn(*args, **kwargs)
58
+ return output
59
+ except Exception as e:
60
+ error = str(e)
61
+ status = "FAILED"
62
+ raise
63
+ finally:
64
+ duration_ms = int((time.monotonic() - start) * 1000)
65
+ try:
66
+ await _client.log_execution_async(
67
+ agent_id=agent_id,
68
+ task_type=task_type,
69
+ status=status,
70
+ input_payload=input_payload,
71
+ output_payload=str(output) if output is not None else None,
72
+ error=error,
73
+ duration_ms=duration_ms,
74
+ )
75
+ except Exception:
76
+ pass # never break production code due to Orka
77
+
78
+ return async_wrapper
79
+ else:
80
+ @functools.wraps(fn)
81
+ def sync_wrapper(*args, **kwargs):
82
+ if _client is None:
83
+ return fn(*args, **kwargs)
84
+
85
+ input_payload = {"args": list(args), "kwargs": kwargs}
86
+ start = time.monotonic()
87
+
88
+ try:
89
+ _client.check_policy(agent_id, task_type, input_payload)
90
+ except OrkaPolicyBlocked:
91
+ if block_on_policy:
92
+ raise
93
+ except Exception:
94
+ pass
95
+
96
+ error = None
97
+ output = None
98
+ status = "COMPLETED"
99
+ try:
100
+ output = fn(*args, **kwargs)
101
+ return output
102
+ except Exception as e:
103
+ error = str(e)
104
+ status = "FAILED"
105
+ raise
106
+ finally:
107
+ duration_ms = int((time.monotonic() - start) * 1000)
108
+ try:
109
+ _client.log_execution(
110
+ agent_id=agent_id,
111
+ task_type=task_type,
112
+ status=status,
113
+ input_payload=input_payload,
114
+ output_payload=str(output) if output is not None else None,
115
+ error=error,
116
+ duration_ms=duration_ms,
117
+ )
118
+ except Exception:
119
+ pass
120
+
121
+ return sync_wrapper
122
+
123
+ return decorator
@@ -0,0 +1,14 @@
1
+ class OrkaError(Exception):
2
+ pass
3
+
4
+ class OrkaPolicyBlocked(OrkaError):
5
+ def __init__(self, reason: str, policy_name: str | None = None):
6
+ self.reason = reason
7
+ self.policy_name = policy_name
8
+ super().__init__(f"Blocked by policy: {reason}")
9
+
10
+ class OrkaAuthError(OrkaError):
11
+ pass
12
+
13
+ class OrkaConnectionError(OrkaError):
14
+ pass
@@ -0,0 +1,23 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "orkaia"
7
+ version = "0.1.0"
8
+ description = "Governance and audit SDK for AI agents"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = { text = "MIT" }
12
+ keywords = ["ai", "agents", "governance", "compliance", "audit", "eu-ai-act"]
13
+ dependencies = [
14
+ "httpx>=0.27.0",
15
+ ]
16
+
17
+ [tool.hatch.build.targets.wheel]
18
+ packages = ["orka"]
19
+
20
+ [project.urls]
21
+ Homepage = "https://orka.ia.br"
22
+ Documentation = "https://orka.ia.br/docs"
23
+ Repository = "https://github.com/orka-runtime/orka-sdk"