openliate 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,55 @@
1
+ # Dependencies
2
+ node_modules/
3
+ .pnp
4
+ .pnp.js
5
+
6
+ # Environment variables
7
+ .env
8
+ .env.local
9
+ .env.development.local
10
+ .env.test.local
11
+ .env.production.local
12
+ .npmrc
13
+
14
+ # Build outputs
15
+ dist/
16
+ bin/
17
+ pkg/
18
+ build/
19
+ out/
20
+ *.exe
21
+ *.wasm
22
+ *.tsbuildinfo
23
+
24
+ # Runtime Agent Sessions & State
25
+ sessions/
26
+ .openliate/
27
+
28
+ # Python artifacts
29
+ __pycache__/
30
+ *.py[cod]
31
+ *$py.class
32
+ *.egg-info/
33
+ .pytest_cache/
34
+
35
+ # Fern docs local cache
36
+ .fern/
37
+
38
+ # Logs
39
+ npm-debug.log*
40
+ yarn-debug.log*
41
+ yarn-error.log*
42
+ bun.lockb
43
+ pnpm-debug.log*
44
+
45
+ # OS Files
46
+ .DS_Store
47
+ Thumbs.db
48
+ .neon
49
+
50
+ # Scratch & Local Probing Scripts
51
+ scripts/test-*
52
+ scripts/probe-*
53
+ scripts/inspect-*
54
+ scripts/create-*
55
+ *.local.*
@@ -0,0 +1,81 @@
1
+ Metadata-Version: 2.5
2
+ Name: openliate
3
+ Version: 0.1.0
4
+ Summary: Open Source Backend Layer for AI Agents — Built for Sovereign AI Agents From India to the World
5
+ Project-URL: Homepage, https://openliate.tech
6
+ Project-URL: Repository, https://github.com/openliate/openliate
7
+ Project-URL: Documentation, https://docs.openliate.tech
8
+ Project-URL: Issues, https://github.com/openliate/openliate/issues
9
+ Author-email: OpenLiate <vinod@openliate.tech>, Vinod Hatti <gitdevinod@gmail.com>
10
+ License: MIT
11
+ Keywords: agent,aum,autonomous-agents,liate,mcp,om,sarvamai,sovereign-ai
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Requires-Python: >=3.9
22
+ Requires-Dist: httpx>=0.24.0
23
+ Description-Content-Type: text/markdown
24
+
25
+ # OpenLiate — Python SDK
26
+
27
+ ### Sovereign AI Agents in 5 Lines: Class is an Agent.
28
+ `L[LM] · I[ntegration] · A[gent] · T[ools] · E[nvironment]`
29
+
30
+ ---
31
+
32
+ ## Installation
33
+
34
+ ```bash
35
+ pip install openliate
36
+ ```
37
+
38
+ ---
39
+
40
+ ## Quickstart (`agent.py`)
41
+
42
+ ```python
43
+ from openliate import liate
44
+
45
+ class HelloAgent(liate):
46
+ L = "sarvam/sarvam-105b"
47
+ I = {"memory": "sessions/hello-agent"}
48
+ A = {"name": "hello_agent", "intent": "Autonomous Assistant"}
49
+ T = ["fetch"]
50
+ E = {"SARVAM_API_KEY": "$SARVAM_API_KEY"}
51
+
52
+ agent = HelloAgent()
53
+
54
+ # 1. Inspect declarative AUM manifest
55
+ print(agent.to_manifest())
56
+
57
+ # 2. Run agent via OpenLiate engine
58
+ result = agent.run("Namaste world!")
59
+ print(result.response)
60
+ ```
61
+
62
+ ---
63
+
64
+ ## Architecture: AUM & OM
65
+
66
+ Every agent declares the 5 orthogonal layers according to the **Agent Unified Manifest (AUM)** standard:
67
+
68
+ - **`L` (Model):** Sovereign LLM provider and model (e.g., Sarvam 105B).
69
+ - **`I` (Integration):** Memory retention, Postgres, and knowledge repositories.
70
+ - **`A` (Agent / Harness):** Agent name, intent, and reasoning loop.
71
+ - **`T` (Tools):** Anthropic Model Context Protocol (MCP) and custom tools.
72
+ - **`E` (Environment):** Secrets and guardrails.
73
+
74
+ Execution is powered by the **Orchestration Module (OM)** connecting locally or to deployed cloud endpoints.
75
+
76
+ ---
77
+
78
+ ## License
79
+
80
+ MIT © [OpenLiate](https://openliate.tech)
81
+
@@ -0,0 +1,57 @@
1
+ # OpenLiate — Python SDK
2
+
3
+ ### Sovereign AI Agents in 5 Lines: Class is an Agent.
4
+ `L[LM] · I[ntegration] · A[gent] · T[ools] · E[nvironment]`
5
+
6
+ ---
7
+
8
+ ## Installation
9
+
10
+ ```bash
11
+ pip install openliate
12
+ ```
13
+
14
+ ---
15
+
16
+ ## Quickstart (`agent.py`)
17
+
18
+ ```python
19
+ from openliate import liate
20
+
21
+ class HelloAgent(liate):
22
+ L = "sarvam/sarvam-105b"
23
+ I = {"memory": "sessions/hello-agent"}
24
+ A = {"name": "hello_agent", "intent": "Autonomous Assistant"}
25
+ T = ["fetch"]
26
+ E = {"SARVAM_API_KEY": "$SARVAM_API_KEY"}
27
+
28
+ agent = HelloAgent()
29
+
30
+ # 1. Inspect declarative AUM manifest
31
+ print(agent.to_manifest())
32
+
33
+ # 2. Run agent via OpenLiate engine
34
+ result = agent.run("Namaste world!")
35
+ print(result.response)
36
+ ```
37
+
38
+ ---
39
+
40
+ ## Architecture: AUM & OM
41
+
42
+ Every agent declares the 5 orthogonal layers according to the **Agent Unified Manifest (AUM)** standard:
43
+
44
+ - **`L` (Model):** Sovereign LLM provider and model (e.g., Sarvam 105B).
45
+ - **`I` (Integration):** Memory retention, Postgres, and knowledge repositories.
46
+ - **`A` (Agent / Harness):** Agent name, intent, and reasoning loop.
47
+ - **`T` (Tools):** Anthropic Model Context Protocol (MCP) and custom tools.
48
+ - **`E` (Environment):** Secrets and guardrails.
49
+
50
+ Execution is powered by the **Orchestration Module (OM)** connecting locally or to deployed cloud endpoints.
51
+
52
+ ---
53
+
54
+ ## License
55
+
56
+ MIT © [OpenLiate](https://openliate.tech)
57
+
@@ -0,0 +1,40 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "openliate"
7
+ version = "0.1.0"
8
+ description = "Open Source Backend Layer for AI Agents — Built for Sovereign AI Agents From India to the World"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = { text = "MIT" }
12
+ authors = [
13
+ { name = "OpenLiate", email = "vinod@openliate.tech" },
14
+ { name = "Vinod Hatti", email = "gitdevinod@gmail.com" }
15
+ ]
16
+ keywords = ["liate", "agent", "autonomous-agents", "sovereign-ai", "mcp", "sarvamai", "aum", "om"]
17
+ classifiers = [
18
+ "Development Status :: 4 - Beta",
19
+ "Intended Audience :: Developers",
20
+ "License :: OSI Approved :: MIT License",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.9",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ "Topic :: Software Development :: Libraries :: Python Modules",
27
+ ]
28
+ dependencies = [
29
+ "httpx>=0.24.0",
30
+ ]
31
+
32
+ [project.urls]
33
+ Homepage = "https://openliate.tech"
34
+ Repository = "https://github.com/openliate/openliate"
35
+ Documentation = "https://docs.openliate.tech"
36
+ Issues = "https://github.com/openliate/openliate/issues"
37
+
38
+ [tool.hatch.build.targets.wheel]
39
+ packages = ["src/openliate"]
40
+
@@ -0,0 +1,10 @@
1
+ """
2
+ OpenLiate Python SDK — Built for Sovereign AI Agents From India to the World
3
+ Class is an Agent: 1 Class = 5 Properties (L · I · A · T · E)
4
+ """
5
+ from .om import liate
6
+ from .client import LapiClient, AgentRunResult
7
+
8
+ __version__ = "0.1.0"
9
+ __all__ = ["liate", "LapiClient", "AgentRunResult"]
10
+
@@ -0,0 +1,127 @@
1
+ """
2
+ OpenLiate Python LAPI Client
3
+ Connects to OpenLiate Orchestration Module (OM) via standard LAPI /run protocol.
4
+ """
5
+ from dataclasses import dataclass, field
6
+ from typing import Any, Dict, List, Optional
7
+ import json
8
+ import urllib.request
9
+ import urllib.error
10
+ import time
11
+
12
+ @dataclass
13
+ class AgentRunResult:
14
+ """
15
+ Standard OpenLiate execution response object.
16
+ """
17
+ response: str
18
+ steps: List[Dict[str, Any]] = field(default_factory=list)
19
+ execution_time_ms: float = 0.0
20
+ session_id: Optional[str] = None
21
+ agent: Optional[str] = None
22
+ raw: Dict[str, Any] = field(default_factory=dict)
23
+
24
+ def __str__(self) -> str:
25
+ return self.response
26
+
27
+ class LapiClient:
28
+ """
29
+ HTTP client for communicating with OpenLiate LAPI endpoint.
30
+ Supports both standard library urllib (zero dependencies) and httpx (async).
31
+ """
32
+ def __init__(self, endpoint: str = "http://localhost:7071"):
33
+ self.endpoint = endpoint.rstrip("/")
34
+
35
+ def run(self, manifest: Dict[str, Any], prompt: str, session_id: Optional[str] = None) -> AgentRunResult:
36
+ """
37
+ Synchronous run via standard urllib.
38
+ """
39
+ url = f"{self.endpoint}/run"
40
+ payload = {
41
+ "manifest": manifest,
42
+ "prompt": prompt
43
+ }
44
+ if session_id:
45
+ payload["sessionId"] = session_id
46
+
47
+ data = json.dumps(payload).encode("utf-8")
48
+ req = urllib.request.Request(
49
+ url,
50
+ data=data,
51
+ headers={"Content-Type": "application/json"}
52
+ )
53
+
54
+ start_time = time.time()
55
+ try:
56
+ with urllib.request.urlopen(req, timeout=120) as resp:
57
+ status = resp.status
58
+ body = json.loads(resp.read().decode("utf-8"))
59
+ except urllib.error.HTTPError as e:
60
+ err_body = e.read().decode("utf-8")
61
+ try:
62
+ err_json = json.loads(err_body)
63
+ err_msg = err_json.get("error", err_body)
64
+ except Exception:
65
+ err_msg = err_body
66
+ raise RuntimeError(f"[OpenLiate LAPI Error HTTP {e.code}]: {err_msg}") from e
67
+ except urllib.error.URLError as e:
68
+ raise ConnectionError(
69
+ f"[OpenLiate Connection Error]: Unable to reach LAPI engine at {self.endpoint}. "
70
+ f"Ensure the OpenLiate engine is running (e.g. `openliate serve` or deployed URL)."
71
+ ) from e
72
+
73
+ duration_ms = (time.time() - start_time) * 1000.0
74
+
75
+ return AgentRunResult(
76
+ response=body.get("text", body.get("response", body.get("output", ""))),
77
+ steps=body.get("steps", []),
78
+ execution_time_ms=body.get("latencyMs", body.get("executionTimeMs", duration_ms)),
79
+ session_id=body.get("sessionId", session_id),
80
+ agent=body.get("agent", manifest.get("A", {}).get("name", "agent")),
81
+ raw=body
82
+ )
83
+
84
+ async def arun(self, manifest: Dict[str, Any], prompt: str, session_id: Optional[str] = None) -> AgentRunResult:
85
+ """
86
+ Asynchronous run via httpx.
87
+ """
88
+ try:
89
+ import httpx
90
+ except ImportError:
91
+ raise ImportError(
92
+ "httpx is required for asynchronous arun(). Install with: pip install httpx"
93
+ )
94
+
95
+ url = f"{self.endpoint}/run"
96
+ payload = {
97
+ "manifest": manifest,
98
+ "prompt": prompt
99
+ }
100
+ if session_id:
101
+ payload["sessionId"] = session_id
102
+
103
+ start_time = time.time()
104
+ async with httpx.AsyncClient(timeout=120.0) as client:
105
+ try:
106
+ resp = await client.post(url, json=payload)
107
+ resp.raise_for_status()
108
+ body = resp.json()
109
+ except httpx.HTTPStatusError as e:
110
+ raise RuntimeError(f"[OpenLiate LAPI Error HTTP {e.response.status_code}]: {e.response.text}") from e
111
+ except httpx.RequestError as e:
112
+ raise ConnectionError(
113
+ f"[OpenLiate Connection Error]: Unable to reach LAPI engine at {self.endpoint}. "
114
+ f"Ensure OpenLiate is running (`openliate serve` or cloud endpoint)."
115
+ ) from e
116
+
117
+ duration_ms = (time.time() - start_time) * 1000.0
118
+
119
+ return AgentRunResult(
120
+ response=body.get("text", body.get("response", body.get("output", ""))),
121
+ steps=body.get("steps", []),
122
+ execution_time_ms=body.get("latencyMs", body.get("executionTimeMs", duration_ms)),
123
+ session_id=body.get("sessionId", session_id),
124
+ agent=body.get("agent", manifest.get("A", {}).get("name", "agent")),
125
+ raw=body
126
+ )
127
+
@@ -0,0 +1,102 @@
1
+ """
2
+ Core Engine: OM (Orchestration Module)
3
+ Matches AUM (Agent Unified Manifest) specification across 5 orthogonal layers:
4
+ L[LM] · I[ntegration] · A[gent] · T[ools] · E[nvironment]
5
+ """
6
+ from typing import Any, Dict, List, Optional, Union
7
+ import os
8
+ from .client import LapiClient, AgentRunResult
9
+
10
+ class liate:
11
+ """
12
+ OM (Orchestration Module) — Python OOP Base Class for AI Agents.
13
+ Supports pure LIATE authoring across 3 styles:
14
+ 1. Shorthand: L · I · A · T · E
15
+ 2. Full Name: LLM · Integration · Agent · Tools · Environment
16
+ 3. Lowercase: llm · integration · agent · tools · environment
17
+
18
+ Example:
19
+ ```python
20
+ from openliate import liate
21
+
22
+ class HelloAgent(liate):
23
+ LLM = "sarvam/sarvam-105b"
24
+ Integration = {"memory": "sessions/hello-agent"}
25
+ Agent = {"name": "hello_agent"}
26
+ Tools = ["fetch"]
27
+ Environment = {"SARVAM_API_KEY": "$SARVAM_API_KEY"}
28
+
29
+ agent = HelloAgent()
30
+ result = agent.run("Namaste world!")
31
+ print(result)
32
+ ```
33
+ """
34
+ # 1. Shorthand
35
+ L: Optional[Union[str, Dict[str, Any]]] = None
36
+ I: Optional[Dict[str, Any]] = None
37
+ A: Optional[Union[str, Dict[str, Any]]] = None
38
+ T: Optional[List[Any]] = None
39
+ E: Optional[Dict[str, str]] = None
40
+
41
+ # 2. Full Name
42
+ LLM: Optional[Union[str, Dict[str, Any]]] = None
43
+ Integration: Optional[Dict[str, Any]] = None
44
+ Agent: Optional[Union[str, Dict[str, Any]]] = None
45
+ Tools: Optional[List[Any]] = None
46
+ Environment: Optional[Dict[str, str]] = None
47
+
48
+ # 3. Lowercase
49
+ llm: Optional[Union[str, Dict[str, Any]]] = None
50
+ integration: Optional[Dict[str, Any]] = None
51
+ agent: Optional[Union[str, Dict[str, Any]]] = None
52
+ tools: Optional[List[Any]] = None
53
+ environment: Optional[Dict[str, str]] = None
54
+
55
+ def __init__(self, endpoint: Optional[str] = None):
56
+ self._endpoint = endpoint or os.environ.get("OPENLIATE_ENDPOINT", "http://localhost:7071")
57
+ self._client = LapiClient(endpoint=self._endpoint)
58
+
59
+ def to_manifest(self) -> Dict[str, Any]:
60
+ """
61
+ Exports the declarative AUM (Agent Unified Manifest) dictionary.
62
+ """
63
+ l_val = self.L if self.L is not None else (self.LLM if self.LLM is not None else self.llm)
64
+ i_val = self.I if self.I is not None else (self.Integration if self.Integration is not None else self.integration)
65
+ a_val = self.A if self.A is not None else (self.Agent if self.Agent is not None else self.agent)
66
+ t_val = self.T if self.T is not None else (self.Tools if self.Tools is not None else self.tools)
67
+ e_val = self.E if self.E is not None else (self.Environment if self.Environment is not None else self.environment)
68
+
69
+ if not l_val:
70
+ raise ValueError(
71
+ f"[OpenLiate Error]: Missing required Layer [L] (LLM) in class '{self.__class__.__name__}'. "
72
+ f"Declare 'L', 'LLM', or 'llm' on your class. "
73
+ f"OpenLiate never hardcodes or falls back to silent model defaults."
74
+ )
75
+
76
+ name = self.__class__.__name__
77
+ agent_a = a_val or {"name": name}
78
+ if isinstance(agent_a, str):
79
+ agent_a = {"name": agent_a}
80
+
81
+ return {
82
+ "L": l_val,
83
+ "I": i_val or {},
84
+ "A": agent_a,
85
+ "T": t_val or [],
86
+ "E": e_val or {}
87
+ }
88
+
89
+ def run(self, prompt: str, session_id: Optional[str] = None) -> AgentRunResult:
90
+ """
91
+ Executes the agent via OpenLiate LAPI.
92
+ """
93
+ manifest = self.to_manifest()
94
+ return self._client.run(manifest=manifest, prompt=prompt, session_id=session_id)
95
+
96
+ async def arun(self, prompt: str, session_id: Optional[str] = None) -> AgentRunResult:
97
+ """
98
+ Asynchronously executes the agent via OpenLiate LAPI.
99
+ """
100
+ manifest = self.to_manifest()
101
+ return await self._client.arun(manifest=manifest, prompt=prompt, session_id=session_id)
102
+
@@ -0,0 +1,81 @@
1
+ import unittest
2
+ import sys
3
+ import os
4
+
5
+ # Add src to sys.path
6
+ sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "../src")))
7
+
8
+ from openliate import liate, AgentRunResult
9
+
10
+ class TestOpenLiatePythonSDK(unittest.TestCase):
11
+ def test_class_is_an_agent_5_properties(self):
12
+ class GreetingAgent(liate):
13
+ L = "sarvam/sarvam-105b"
14
+ I = {"memory": "sessions/test-python"}
15
+ A = {"name": "greeting_agent", "intent": "Friendly assistant"}
16
+ T = ["fetch"]
17
+ E = {"SARVAM_API_KEY": "test_key_python"}
18
+
19
+ agent = GreetingAgent()
20
+ manifest = agent.to_manifest()
21
+
22
+ self.assertEqual(manifest["L"], "sarvam/sarvam-105b")
23
+ self.assertEqual(manifest["I"], {"memory": "sessions/test-python"})
24
+ self.assertEqual(manifest["A"]["name"], "greeting_agent")
25
+ self.assertEqual(manifest["A"]["intent"], "Friendly assistant")
26
+ self.assertEqual(manifest["T"], ["fetch"])
27
+ self.assertEqual(manifest["E"]["SARVAM_API_KEY"], "test_key_python")
28
+
29
+ def test_strict_layer_l_enforcement(self):
30
+ class IncompleteAgent(liate):
31
+ A = {"name": "no_model"}
32
+
33
+ agent = IncompleteAgent()
34
+ with self.assertRaises(ValueError) as ctx:
35
+ agent.to_manifest()
36
+ self.assertIn("Missing required Layer [L]", str(ctx.exception))
37
+
38
+ def test_full_name_liate_properties(self):
39
+ class FullNameAgent(liate):
40
+ LLM = "sarvam/sarvam-105b"
41
+ Integration = {"memory": "sessions/python-full"}
42
+ Agent = {"name": "full_python_agent"}
43
+ Tools = ["fetch"]
44
+ Environment = {"SARVAM_API_KEY": "py_key"}
45
+
46
+ agent = FullNameAgent()
47
+ manifest = agent.to_manifest()
48
+ self.assertEqual(manifest["L"], "sarvam/sarvam-105b")
49
+ self.assertEqual(manifest["I"]["memory"], "sessions/python-full")
50
+ self.assertEqual(manifest["A"]["name"], "full_python_agent")
51
+ self.assertEqual(manifest["T"], ["fetch"])
52
+
53
+ def test_lowercase_liate_properties(self):
54
+ class LowercaseAgent(liate):
55
+ llm = "sarvam/sarvam-105b"
56
+ integration = {"memory": "sessions/python-lower"}
57
+ agent = {"name": "lower_python_agent"}
58
+ tools = ["fetch"]
59
+ environment = {"SARVAM_API_KEY": "py_key"}
60
+
61
+ agent = LowercaseAgent()
62
+ manifest = agent.to_manifest()
63
+ self.assertEqual(manifest["L"], "sarvam/sarvam-105b")
64
+ self.assertEqual(manifest["I"]["memory"], "sessions/python-lower")
65
+ self.assertEqual(manifest["A"]["name"], "lower_python_agent")
66
+ self.assertEqual(manifest["T"], ["fetch"])
67
+
68
+ def test_agent_run_result_dataclass(self):
69
+ res = AgentRunResult(
70
+ response="Hello world",
71
+ steps=[{"thought": "test"}],
72
+ execution_time_ms=12.5,
73
+ session_id="session-123"
74
+ )
75
+ self.assertEqual(str(res), "Hello world")
76
+ self.assertEqual(res.execution_time_ms, 12.5)
77
+ self.assertEqual(res.session_id, "session-123")
78
+
79
+ if __name__ == "__main__":
80
+ unittest.main()
81
+