orgo 0.0.1__tar.gz → 0.0.3__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.
orgo-0.0.3/PKG-INFO ADDED
@@ -0,0 +1,42 @@
1
+ Metadata-Version: 2.2
2
+ Name: orgo
3
+ Version: 0.0.3
4
+ Summary: Desktop infrastructure for AI agents
5
+ Author: Orgo Team
6
+ License: MIT
7
+ Project-URL: Homepage, https://www.orgo.ai
8
+ Project-URL: Documentation, https://docs.orgo.ai
9
+ Requires-Python: >=3.7
10
+ Description-Content-Type: text/markdown
11
+ Requires-Dist: requests>=2.25.0
12
+ Requires-Dist: pillow>=8.0.0
13
+
14
+ # Orgo SDK
15
+
16
+ Desktop infrastructure for AI agents.
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ pip install orgo
22
+ ```
23
+
24
+ ## Usage
25
+
26
+ ```python
27
+ from orgo import Computer
28
+
29
+ # Create computer
30
+ computer = Computer()
31
+
32
+ # Control
33
+ computer.left_click(100, 200)
34
+ computer.type("Hello world")
35
+ computer.key("Enter")
36
+ computer.screenshot() # Returns PIL Image
37
+
38
+ # Cleanup
39
+ computer.shutdown()
40
+ ```
41
+
42
+ Full documentation: [docs.orgo.ai](https://docs.orgo.ai)
orgo-0.0.3/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Orgo SDK
2
+
3
+ Desktop infrastructure for AI agents.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install orgo
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```python
14
+ from orgo import Computer
15
+
16
+ # Create computer
17
+ computer = Computer()
18
+
19
+ # Control
20
+ computer.left_click(100, 200)
21
+ computer.type("Hello world")
22
+ computer.key("Enter")
23
+ computer.screenshot() # Returns PIL Image
24
+
25
+ # Cleanup
26
+ computer.shutdown()
27
+ ```
28
+
29
+ Full documentation: [docs.orgo.ai](https://docs.orgo.ai)
@@ -0,0 +1,23 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "orgo"
7
+ version = "0.0.3"
8
+ description = "Desktop infrastructure for AI agents"
9
+ authors = [{name = "Orgo Team"}]
10
+ license = {text = "MIT"}
11
+ readme = "README.md"
12
+ requires-python = ">=3.7"
13
+ dependencies = [
14
+ "requests>=2.25.0",
15
+ "pillow>=8.0.0",
16
+ ]
17
+
18
+ [project.urls]
19
+ "Homepage" = "https://www.orgo.ai"
20
+ "Documentation" = "https://docs.orgo.ai"
21
+
22
+ [tool.setuptools]
23
+ package-dir = {"" = "src"}
@@ -0,0 +1,5 @@
1
+ """Orgo SDK: Desktop infrastructure for AI agents"""
2
+
3
+ from .computer import Computer
4
+
5
+ __all__ = ["Computer"]
@@ -0,0 +1,7 @@
1
+ """Adapters for integrating Orgo with AI models"""
2
+
3
+ from .base import BaseAdapter
4
+ from .anthropic import AnthropicAdapter
5
+ from .openai import OpenAIAdapter
6
+
7
+ __all__ = ["BaseAdapter", "AnthropicAdapter", "OpenAIAdapter"]
@@ -0,0 +1,64 @@
1
+ """Adapter for Anthropic's Claude"""
2
+
3
+ from typing import Dict, Any, Optional
4
+ from .base import BaseAdapter
5
+
6
+ class AnthropicAdapter(BaseAdapter):
7
+ def get_tool_definition(self) -> Dict[str, Any]:
8
+ return {
9
+ "name": "computer",
10
+ "description": "Controls a virtual computer to automate tasks",
11
+ "type": "function",
12
+ "parameters": {
13
+ "type": "object",
14
+ "properties": {
15
+ "action": {
16
+ "type": "string",
17
+ "enum": ["left_click", "right_click", "double_click", "type", "key", "scroll", "screenshot"],
18
+ "description": "The action to perform on the computer"
19
+ },
20
+ "coordinate": {
21
+ "type": "array",
22
+ "items": {"type": "number"},
23
+ "description": "The x,y coordinates for click actions",
24
+ "minItems": 2,
25
+ "maxItems": 2
26
+ },
27
+ "text": {
28
+ "type": "string",
29
+ "description": "The text to type or key to press"
30
+ },
31
+ "direction": {
32
+ "type": "string",
33
+ "enum": ["up", "down", "left", "right"],
34
+ "description": "The direction to scroll"
35
+ },
36
+ "amount": {
37
+ "type": "number",
38
+ "description": "The amount to scroll"
39
+ }
40
+ },
41
+ "required": ["action"],
42
+ "additionalProperties": False
43
+ }
44
+ }
45
+
46
+ def format_result(self, tool_id: str, output: Optional[str] = None, error: Optional[str] = None) -> Dict[str, Any]:
47
+ screenshot = self.computer.get_base64()
48
+ result = {
49
+ "type": "tool_result",
50
+ "id": tool_id,
51
+ "content": {
52
+ "type": "image",
53
+ "source": {
54
+ "type": "base64",
55
+ "media_type": "image/png",
56
+ "data": screenshot
57
+ }
58
+ }
59
+ }
60
+
61
+ if error:
62
+ result["error"] = error
63
+
64
+ return result
@@ -0,0 +1,14 @@
1
+ """Base adapter for AI model integration"""
2
+
3
+ from typing import Dict, Any, Optional
4
+ from ..computer import Computer
5
+
6
+ class BaseAdapter:
7
+ def __init__(self, computer: Computer):
8
+ self.computer = computer
9
+
10
+ def get_tool_definition(self) -> Dict[str, Any]:
11
+ raise NotImplementedError("Subclasses must implement get_tool_definition()")
12
+
13
+ def format_result(self, tool_id: str, output: Optional[str] = None, error: Optional[str] = None) -> Dict[str, Any]:
14
+ raise NotImplementedError("Subclasses must implement format_result()")
@@ -0,0 +1,69 @@
1
+ """Adapter for OpenAI models"""
2
+
3
+ from typing import Dict, Any, Optional
4
+ from .base import BaseAdapter
5
+
6
+ class OpenAIAdapter(BaseAdapter):
7
+ def get_tool_definition(self) -> Dict[str, Any]:
8
+ return {
9
+ "type": "function",
10
+ "function": {
11
+ "name": "computer",
12
+ "description": "Controls a virtual computer to automate tasks",
13
+ "parameters": {
14
+ "type": "object",
15
+ "properties": {
16
+ "action": {
17
+ "type": "string",
18
+ "enum": ["click", "right_click", "double_click", "type", "key", "scroll", "screenshot"],
19
+ "description": "The action to perform on the computer"
20
+ },
21
+ "x": {
22
+ "type": "number",
23
+ "description": "The x coordinate for click actions"
24
+ },
25
+ "y": {
26
+ "type": "number",
27
+ "description": "The y coordinate for click actions"
28
+ },
29
+ "text": {
30
+ "type": "string",
31
+ "description": "The text to type or key to press"
32
+ },
33
+ "direction": {
34
+ "type": "string",
35
+ "enum": ["up", "down", "left", "right"],
36
+ "description": "The direction to scroll"
37
+ },
38
+ "amount": {
39
+ "type": "number",
40
+ "description": "The amount to scroll"
41
+ }
42
+ },
43
+ "required": ["action"],
44
+ "additionalProperties": False
45
+ }
46
+ }
47
+ }
48
+
49
+ def format_result(self, tool_id: str, output: Optional[str] = None, error: Optional[str] = None) -> Dict[str, Any]:
50
+ screenshot = self.computer.get_base64()
51
+ result = {
52
+ "tool_call_id": tool_id,
53
+ "content": [
54
+ {
55
+ "type": "image_url",
56
+ "image_url": {
57
+ "url": f"data:image/png;base64,{screenshot}"
58
+ }
59
+ }
60
+ ]
61
+ }
62
+
63
+ if error:
64
+ result["content"].insert(0, {
65
+ "type": "text",
66
+ "text": f"Error: {error}"
67
+ })
68
+
69
+ return result
@@ -0,0 +1,5 @@
1
+ """API package for Orgo SDK"""
2
+
3
+ from .client import ApiClient
4
+
5
+ __all__ = ["ApiClient"]
@@ -0,0 +1,102 @@
1
+ """API client for Orgo service"""
2
+
3
+ import requests
4
+ from typing import Dict, Any, Optional
5
+
6
+ from orgo.utils.auth import get_api_key
7
+
8
+ class ApiClient:
9
+ BASE_URL = "https://www.orgo.ai/api"
10
+
11
+ def __init__(self, api_key: Optional[str] = None):
12
+ self.api_key = get_api_key(api_key)
13
+ self.session = requests.Session()
14
+ self.session.headers.update({
15
+ "Authorization": f"Bearer {self.api_key}",
16
+ "Content-Type": "application/json",
17
+ "Accept": "application/json"
18
+ })
19
+
20
+ def _request(self, method: str, endpoint: str, data: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
21
+ url = f"{self.BASE_URL}/{endpoint}"
22
+
23
+ try:
24
+ if method.upper() == "GET":
25
+ response = self.session.get(url, params=data)
26
+ else:
27
+ response = self.session.request(method, url, json=data)
28
+
29
+ response.raise_for_status()
30
+ return response.json()
31
+ except requests.exceptions.RequestException as e:
32
+ if hasattr(e, 'response') and e.response is not None:
33
+ error_message = f"API error: {e.response.status_code}"
34
+ try:
35
+ error_data = e.response.json()
36
+ if 'error' in error_data:
37
+ error_message += f" - {error_data['error']}"
38
+ except ValueError:
39
+ pass
40
+ raise Exception(error_message) from e
41
+ raise Exception(f"Connection error: {str(e)}") from e
42
+
43
+ # Computer lifecycle methods
44
+ def create_computer(self, config: Optional[Dict[str, Any]] = None) -> Dict[str, Any]:
45
+ """Create a new project with desktop instance"""
46
+ return self._request("POST", "projects", {"config": config} if config else None)
47
+
48
+ def connect_computer(self, project_id: str) -> Dict[str, Any]:
49
+ return self._request("GET", f"computers/{project_id}")
50
+
51
+ def get_status(self, project_id: str) -> Dict[str, Any]:
52
+ return self._request("GET", f"computers/{project_id}/status")
53
+
54
+ def restart_computer(self, project_id: str) -> Dict[str, Any]:
55
+ return self._request("POST", f"computers/{project_id}/restart")
56
+
57
+ def shutdown_computer(self, project_id: str) -> Dict[str, Any]:
58
+ return self._request("POST", f"computers/{project_id}/shutdown")
59
+
60
+ # Computer control methods
61
+ def left_click(self, project_id: str, x: int, y: int) -> Dict[str, Any]:
62
+ return self._request("POST", f"computers/{project_id}/click", {
63
+ "button": "left", "x": x, "y": y
64
+ })
65
+
66
+ def right_click(self, project_id: str, x: int, y: int) -> Dict[str, Any]:
67
+ return self._request("POST", f"computers/{project_id}/click", {
68
+ "button": "right", "x": x, "y": y
69
+ })
70
+
71
+ def double_click(self, project_id: str, x: int, y: int) -> Dict[str, Any]:
72
+ return self._request("POST", f"computers/{project_id}/click", {
73
+ "button": "left", "x": x, "y": y, "double": True
74
+ })
75
+
76
+ def scroll(self, project_id: str, direction: str, amount: int) -> Dict[str, Any]:
77
+ return self._request("POST", f"computers/{project_id}/scroll", {
78
+ "direction": direction, "amount": amount
79
+ })
80
+
81
+ def type_text(self, project_id: str, text: str) -> Dict[str, Any]:
82
+ return self._request("POST", f"computers/{project_id}/type", {
83
+ "text": text
84
+ })
85
+
86
+ def key_press(self, project_id: str, key: str) -> Dict[str, Any]:
87
+ return self._request("POST", f"computers/{project_id}/key", {
88
+ "key": key
89
+ })
90
+
91
+ def get_screenshot(self, project_id: str) -> Dict[str, Any]:
92
+ return self._request("GET", f"computers/{project_id}/screenshot")
93
+
94
+ def execute_bash(self, project_id: str, command: str) -> Dict[str, Any]:
95
+ return self._request("POST", f"computers/{project_id}/bash", {
96
+ "command": command
97
+ })
98
+
99
+ def wait(self, project_id: str, seconds: float) -> Dict[str, Any]:
100
+ return self._request("POST", f"computers/{project_id}/wait", {
101
+ "seconds": seconds
102
+ })
@@ -0,0 +1,84 @@
1
+ """Computer class for interacting with Orgo virtual environments"""
2
+
3
+ import os
4
+ import io
5
+ import base64
6
+ from typing import Dict, Any
7
+ from PIL import Image
8
+
9
+ from .api.client import ApiClient
10
+
11
+ class Computer:
12
+ def __init__(self, project_id=None, api_key=None, config=None):
13
+ self.api = ApiClient(api_key or os.environ.get("ORGO_API_KEY"))
14
+
15
+ if project_id:
16
+ self.project_id = project_id
17
+ self._info = self.api.connect_computer(project_id)
18
+ else:
19
+ response = self.api.create_computer(config)
20
+ self.project_id = response.get("id")
21
+ self._info = response
22
+
23
+ if not self.project_id:
24
+ raise ValueError("Failed to initialize computer: No project ID returned")
25
+
26
+ def status(self) -> Dict[str, Any]:
27
+ """Get current computer status"""
28
+ return self.api.get_status(self.project_id)
29
+
30
+ def restart(self) -> Dict[str, Any]:
31
+ """Restart the computer"""
32
+ return self.api.restart_computer(self.project_id)
33
+
34
+ def shutdown(self) -> Dict[str, Any]:
35
+ """Terminate the computer instance"""
36
+ return self.api.shutdown_computer(self.project_id)
37
+
38
+ # Navigation methods
39
+ def left_click(self, x: int, y: int) -> Dict[str, Any]:
40
+ """Perform left mouse click at specified coordinates"""
41
+ return self.api.left_click(self.project_id, x, y)
42
+
43
+ def right_click(self, x: int, y: int) -> Dict[str, Any]:
44
+ """Perform right mouse click at specified coordinates"""
45
+ return self.api.right_click(self.project_id, x, y)
46
+
47
+ def double_click(self, x: int, y: int) -> Dict[str, Any]:
48
+ """Perform double click at specified coordinates"""
49
+ return self.api.double_click(self.project_id, x, y)
50
+
51
+ def scroll(self, direction: str = "down", amount: int = 1) -> Dict[str, Any]:
52
+ """Scroll in specified direction and amount"""
53
+ return self.api.scroll(self.project_id, direction, amount)
54
+
55
+ # Input methods
56
+ def type(self, text: str) -> Dict[str, Any]:
57
+ """Type the specified text"""
58
+ return self.api.type_text(self.project_id, text)
59
+
60
+ def key(self, key: str) -> Dict[str, Any]:
61
+ """Press a key or key combination (e.g., "Enter", "ctrl+c")"""
62
+ return self.api.key_press(self.project_id, key)
63
+
64
+ # View methods
65
+ def screenshot(self) -> Image.Image:
66
+ """Capture screenshot and return as PIL Image"""
67
+ response = self.api.get_screenshot(self.project_id)
68
+ img_data = base64.b64decode(response.get("screenshot", ""))
69
+ return Image.open(io.BytesIO(img_data))
70
+
71
+ def screenshot_base64(self) -> str:
72
+ """Capture screenshot and return as base64 string"""
73
+ response = self.api.get_screenshot(self.project_id)
74
+ return response.get("screenshot", "")
75
+
76
+ # Execution methods
77
+ def bash(self, command: str) -> str:
78
+ """Execute a bash command and return output"""
79
+ response = self.api.execute_bash(self.project_id, command)
80
+ return response.get("output", "")
81
+
82
+ def wait(self, seconds: float) -> Dict[str, Any]:
83
+ """Wait for specified number of seconds"""
84
+ return self.api.wait(self.project_id, seconds)
@@ -0,0 +1,5 @@
1
+ """Utility functions for Orgo SDK"""
2
+
3
+ from .auth import get_api_key
4
+
5
+ __all__ = ["get_api_key"]
@@ -0,0 +1,16 @@
1
+ """Authentication utilities for Orgo SDK"""
2
+
3
+ import os
4
+ from typing import Optional
5
+
6
+ def get_api_key(api_key: Optional[str] = None) -> str:
7
+ """Get the Orgo API key from parameters or environment"""
8
+ key = api_key or os.environ.get("ORGO_API_KEY")
9
+
10
+ if not key:
11
+ raise ValueError(
12
+ "API key required. Set ORGO_API_KEY environment variable or pass api_key parameter. "
13
+ "Get a key at https://www.orgo.ai/start"
14
+ )
15
+
16
+ return key
@@ -0,0 +1,42 @@
1
+ Metadata-Version: 2.2
2
+ Name: orgo
3
+ Version: 0.0.3
4
+ Summary: Desktop infrastructure for AI agents
5
+ Author: Orgo Team
6
+ License: MIT
7
+ Project-URL: Homepage, https://www.orgo.ai
8
+ Project-URL: Documentation, https://docs.orgo.ai
9
+ Requires-Python: >=3.7
10
+ Description-Content-Type: text/markdown
11
+ Requires-Dist: requests>=2.25.0
12
+ Requires-Dist: pillow>=8.0.0
13
+
14
+ # Orgo SDK
15
+
16
+ Desktop infrastructure for AI agents.
17
+
18
+ ## Install
19
+
20
+ ```bash
21
+ pip install orgo
22
+ ```
23
+
24
+ ## Usage
25
+
26
+ ```python
27
+ from orgo import Computer
28
+
29
+ # Create computer
30
+ computer = Computer()
31
+
32
+ # Control
33
+ computer.left_click(100, 200)
34
+ computer.type("Hello world")
35
+ computer.key("Enter")
36
+ computer.screenshot() # Returns PIL Image
37
+
38
+ # Cleanup
39
+ computer.shutdown()
40
+ ```
41
+
42
+ Full documentation: [docs.orgo.ai](https://docs.orgo.ai)
@@ -0,0 +1,17 @@
1
+ README.md
2
+ pyproject.toml
3
+ src/orgo/__init__.py
4
+ src/orgo/computer.py
5
+ src/orgo.egg-info/PKG-INFO
6
+ src/orgo.egg-info/SOURCES.txt
7
+ src/orgo.egg-info/dependency_links.txt
8
+ src/orgo.egg-info/requires.txt
9
+ src/orgo.egg-info/top_level.txt
10
+ src/orgo/adapters/__init__.py
11
+ src/orgo/adapters/anthropic.py
12
+ src/orgo/adapters/base.py
13
+ src/orgo/adapters/openai.py
14
+ src/orgo/api/__init__.py
15
+ src/orgo/api/client.py
16
+ src/orgo/utils/__init__.py
17
+ src/orgo/utils/auth.py
@@ -0,0 +1,2 @@
1
+ requests>=2.25.0
2
+ pillow>=8.0.0
@@ -0,0 +1 @@
1
+ orgo
orgo-0.0.1/PKG-INFO DELETED
@@ -1,6 +0,0 @@
1
- Metadata-Version: 2.2
2
- Name: orgo
3
- Version: 0.0.1
4
- Author: Your Name
5
- License: MIT
6
- Requires-Python: >=3.6
@@ -1,6 +0,0 @@
1
- Metadata-Version: 2.2
2
- Name: orgo
3
- Version: 0.0.1
4
- Author: Your Name
5
- License: MIT
6
- Requires-Python: >=3.6
@@ -1,5 +0,0 @@
1
- pyproject.toml
2
- orgo.egg-info/PKG-INFO
3
- orgo.egg-info/SOURCES.txt
4
- orgo.egg-info/dependency_links.txt
5
- orgo.egg-info/top_level.txt
@@ -1 +0,0 @@
1
-
orgo-0.0.1/pyproject.toml DELETED
@@ -1,11 +0,0 @@
1
- [build-system]
2
- requires = ["setuptools", "wheel"]
3
- build-backend = "setuptools.build_meta"
4
-
5
- [project]
6
- name = "orgo"
7
- version = "0.0.1"
8
- description = ""
9
- authors = [{name = "Your Name"}]
10
- license = {text = "MIT"}
11
- requires-python = ">=3.6"
File without changes