optexity 0.1.2__py3-none-any.whl → 0.1.4__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.
Files changed (77) hide show
  1. optexity/cli.py +1 -1
  2. optexity/examples/__init__.py +0 -0
  3. optexity/examples/add_example.py +88 -0
  4. optexity/examples/download_pdf_url.py +29 -0
  5. optexity/examples/extract_price_stockanalysis.py +44 -0
  6. optexity/examples/file_upload.py +59 -0
  7. optexity/examples/i94.py +126 -0
  8. optexity/examples/i94_travel_history.py +126 -0
  9. optexity/examples/peachstate_medicaid.py +201 -0
  10. optexity/examples/supabase_login.py +75 -0
  11. optexity/inference/__init__.py +0 -0
  12. optexity/inference/agents/__init__.py +0 -0
  13. optexity/inference/agents/error_handler/__init__.py +0 -0
  14. optexity/inference/agents/error_handler/error_handler.py +39 -0
  15. optexity/inference/agents/error_handler/prompt.py +60 -0
  16. optexity/inference/agents/index_prediction/__init__.py +0 -0
  17. optexity/inference/agents/index_prediction/action_prediction_locator_axtree.py +45 -0
  18. optexity/inference/agents/index_prediction/prompt.py +14 -0
  19. optexity/inference/agents/select_value_prediction/__init__.py +0 -0
  20. optexity/inference/agents/select_value_prediction/prompt.py +20 -0
  21. optexity/inference/agents/select_value_prediction/select_value_prediction.py +39 -0
  22. optexity/inference/agents/two_fa_extraction/__init__.py +0 -0
  23. optexity/inference/agents/two_fa_extraction/prompt.py +23 -0
  24. optexity/inference/agents/two_fa_extraction/two_fa_extraction.py +47 -0
  25. optexity/inference/child_process.py +251 -0
  26. optexity/inference/core/__init__.py +0 -0
  27. optexity/inference/core/interaction/__init__.py +0 -0
  28. optexity/inference/core/interaction/handle_agentic_task.py +79 -0
  29. optexity/inference/core/interaction/handle_check.py +57 -0
  30. optexity/inference/core/interaction/handle_click.py +79 -0
  31. optexity/inference/core/interaction/handle_command.py +261 -0
  32. optexity/inference/core/interaction/handle_input.py +76 -0
  33. optexity/inference/core/interaction/handle_keypress.py +16 -0
  34. optexity/inference/core/interaction/handle_select.py +109 -0
  35. optexity/inference/core/interaction/handle_select_utils.py +132 -0
  36. optexity/inference/core/interaction/handle_upload.py +59 -0
  37. optexity/inference/core/interaction/utils.py +81 -0
  38. optexity/inference/core/logging.py +406 -0
  39. optexity/inference/core/run_assertion.py +55 -0
  40. optexity/inference/core/run_automation.py +463 -0
  41. optexity/inference/core/run_extraction.py +240 -0
  42. optexity/inference/core/run_interaction.py +254 -0
  43. optexity/inference/core/run_python_script.py +20 -0
  44. optexity/inference/core/run_two_fa.py +120 -0
  45. optexity/inference/core/two_factor_auth/__init__.py +0 -0
  46. optexity/inference/infra/__init__.py +0 -0
  47. optexity/inference/infra/browser.py +455 -0
  48. optexity/inference/infra/browser_extension.py +20 -0
  49. optexity/inference/models/__init__.py +22 -0
  50. optexity/inference/models/gemini.py +113 -0
  51. optexity/inference/models/human.py +20 -0
  52. optexity/inference/models/llm_model.py +210 -0
  53. optexity/inference/run_local.py +200 -0
  54. optexity/schema/__init__.py +0 -0
  55. optexity/schema/actions/__init__.py +0 -0
  56. optexity/schema/actions/assertion_action.py +66 -0
  57. optexity/schema/actions/extraction_action.py +143 -0
  58. optexity/schema/actions/interaction_action.py +330 -0
  59. optexity/schema/actions/misc_action.py +18 -0
  60. optexity/schema/actions/prompts.py +27 -0
  61. optexity/schema/actions/two_fa_action.py +24 -0
  62. optexity/schema/automation.py +432 -0
  63. optexity/schema/callback.py +16 -0
  64. optexity/schema/inference.py +87 -0
  65. optexity/schema/memory.py +100 -0
  66. optexity/schema/task.py +212 -0
  67. optexity/schema/token_usage.py +48 -0
  68. optexity/utils/__init__.py +0 -0
  69. optexity/utils/settings.py +54 -0
  70. optexity/utils/utils.py +76 -0
  71. {optexity-0.1.2.dist-info → optexity-0.1.4.dist-info}/METADATA +20 -36
  72. optexity-0.1.4.dist-info/RECORD +80 -0
  73. optexity-0.1.2.dist-info/RECORD +0 -11
  74. {optexity-0.1.2.dist-info → optexity-0.1.4.dist-info}/WHEEL +0 -0
  75. {optexity-0.1.2.dist-info → optexity-0.1.4.dist-info}/entry_points.txt +0 -0
  76. {optexity-0.1.2.dist-info → optexity-0.1.4.dist-info}/licenses/LICENSE +0 -0
  77. {optexity-0.1.2.dist-info → optexity-0.1.4.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,212 @@
1
+ import base64
2
+ import json
3
+ import string
4
+ import uuid
5
+ from datetime import datetime
6
+ from io import BytesIO
7
+ from pathlib import Path
8
+ from typing import Literal, Optional
9
+
10
+ from PIL import Image
11
+ from pydantic import BaseModel, Field, computed_field, model_validator
12
+
13
+ from optexity.schema.automation import Automation, SecureParameter
14
+ from optexity.schema.memory import ForLoopStatus
15
+ from optexity.schema.token_usage import TokenUsage
16
+
17
+ BASE62 = string.digits + string.ascii_lowercase + string.ascii_uppercase
18
+
19
+
20
+ def uuid_str_to_base62(uuid_str: str) -> str:
21
+ n = uuid.UUID(uuid_str).int
22
+ out = []
23
+ while n:
24
+ n, r = divmod(n, 62)
25
+ out.append(BASE62[r])
26
+ return "".join(reversed(out))
27
+
28
+
29
+ class CallbackUrl(BaseModel):
30
+ url: str
31
+ api_key: str | None = None
32
+ username: str | None = None
33
+ password: str | None = None
34
+
35
+ @model_validator(mode="after")
36
+ def validate_callback_url(self):
37
+
38
+ if self.api_key is not None and (
39
+ self.username is not None or self.password is not None
40
+ ):
41
+ raise ValueError(
42
+ "api_key and username/password cannot be used together. Please provide only one of them."
43
+ )
44
+
45
+ return self
46
+
47
+
48
+ class Task(BaseModel):
49
+ task_id: str
50
+ user_id: str
51
+ recording_id: str
52
+ endpoint_name: str
53
+ automation: Automation
54
+ input_parameters: dict[str, list[str | int | float | bool]]
55
+ secure_parameters: dict[str, list[SecureParameter]]
56
+ unique_parameter_names: list[str]
57
+ unique_parameters: dict[str, list[str]] | None = None
58
+ created_at: datetime
59
+ allocated_at: Optional[datetime] = None
60
+ started_at: Optional[datetime] = None
61
+ completed_at: Optional[datetime] = None
62
+ error: Optional[str] = None
63
+ status: Literal["queued", "allocated", "running", "success", "failed", "cancelled"]
64
+ is_cloud: bool = False
65
+ save_directory: Path = Field(default=Path("/tmp/optexity"))
66
+ use_proxy: bool = False
67
+
68
+ dedup_key: str = Field(default_factory=lambda: str(uuid.uuid4()))
69
+ retry_count: int = 0
70
+ max_retries: int = 1
71
+ api_key: str
72
+ callback_url: CallbackUrl | None = None
73
+
74
+ class Config:
75
+ json_encoders = {datetime: lambda v: v.isoformat() if v is not None else None}
76
+
77
+ @computed_field
78
+ @property
79
+ def task_directory(self) -> Path:
80
+ return self.save_directory / str(self.task_id)
81
+
82
+ @computed_field
83
+ @property
84
+ def logs_directory(self) -> Path:
85
+ return self.task_directory / "logs"
86
+
87
+ @computed_field
88
+ @property
89
+ def downloads_directory(self) -> Path:
90
+ return self.task_directory / "downloads"
91
+
92
+ @computed_field
93
+ @property
94
+ def log_file_path(self) -> Path:
95
+ return self.logs_directory / "optexity.log"
96
+
97
+ @model_validator(mode="after")
98
+ def validate_unique_parameters(self):
99
+ ## TODO: we do not do dedup using secure parameters yet, need to add support for that
100
+ if len(self.unique_parameter_names) > 0:
101
+ self.unique_parameters = {
102
+ unique_parameter_name: self.input_parameters[unique_parameter_name]
103
+ for unique_parameter_name in self.unique_parameter_names
104
+ }
105
+ self.dedup_key = json.dumps(self.unique_parameters, sort_keys=True)
106
+
107
+ for a, b in [
108
+ (self.automation.parameters.input_parameters, self.input_parameters),
109
+ (self.automation.parameters.secure_parameters, self.secure_parameters),
110
+ ]:
111
+ if a.keys() != b.keys():
112
+ missing_keys = a.keys() - b.keys()
113
+ extra_keys = b.keys() - a.keys()
114
+ raise ValueError(
115
+ f"Please provide exactly the same {a} as the automation. Missing keys: {missing_keys}, Extra keys: {extra_keys}"
116
+ )
117
+
118
+ return self
119
+
120
+ @model_validator(mode="after")
121
+ def set_dependent_paths(self):
122
+
123
+ self.logs_directory.mkdir(parents=True, exist_ok=True)
124
+ self.downloads_directory.mkdir(parents=True, exist_ok=True)
125
+ self.log_file_path.parent.mkdir(parents=True, exist_ok=True)
126
+
127
+ return self
128
+
129
+ def proxy_session_id(
130
+ self, proxy_provider: Literal["oxylabs", "other"] | None
131
+ ) -> str | None:
132
+ if not self.use_proxy:
133
+ return None
134
+ if proxy_provider == "oxylabs":
135
+ return uuid_str_to_base62(self.task_id)
136
+ else:
137
+ return "default"
138
+
139
+
140
+ class TaskCreateRequest(BaseModel):
141
+ task_id: str
142
+ recording_id: str
143
+ input_parameters: dict
144
+ unique_parameter_names: list[str]
145
+ created_at: datetime
146
+
147
+ @model_validator(mode="after")
148
+ def must_have_timezone(self):
149
+ if self.created_at.tzinfo is None:
150
+ raise ValueError("created_at must include timezone information")
151
+
152
+ for unique_parameter_name in self.unique_parameter_names:
153
+ if unique_parameter_name not in self.input_parameters:
154
+ raise ValueError(
155
+ f"unique_parameter_name {unique_parameter_name} not found in input_parameters"
156
+ )
157
+ return self
158
+
159
+
160
+ class TaskStartedRequest(BaseModel):
161
+ task_id: str
162
+ started_at: datetime
163
+ allocated_at: Optional[datetime] = None
164
+
165
+ @model_validator(mode="after")
166
+ def must_have_timezone(self):
167
+ if self.started_at.tzinfo is None:
168
+ raise ValueError("started_at must include timezone information")
169
+ if self.allocated_at is not None and self.allocated_at.tzinfo is None:
170
+ raise ValueError("allocated_at must include timezone information")
171
+ return self
172
+
173
+
174
+ class TaskCompleteRequest(BaseModel):
175
+ task_id: str
176
+ child_process_id: int
177
+
178
+ status: Literal["success", "failed", "cancelled"]
179
+ error: str | None
180
+ completed_at: datetime
181
+ token_usage: TokenUsage
182
+
183
+ @model_validator(mode="after")
184
+ def must_have_timezone(self):
185
+ if self.completed_at.tzinfo is None:
186
+ raise ValueError("completed_at must include timezone information")
187
+ return self
188
+
189
+
190
+ class TaskOutputDataRequest(BaseModel):
191
+ task_id: str
192
+ output_data: list[dict]
193
+ final_screenshot: str | None
194
+ for_loop_status: list[list[ForLoopStatus]] | None = None
195
+
196
+ @model_validator(mode="after")
197
+ def must_have_valid_final_screenshot(self):
198
+ if self.final_screenshot is not None and not self.is_valid_base64_image(
199
+ self.final_screenshot
200
+ ):
201
+ raise ValueError("final_screenshot must be a valid base64 encoded image")
202
+ return self
203
+
204
+ def is_valid_base64_image(self, data: str) -> bool:
205
+ try:
206
+ # Decode the base64 string
207
+ decoded = base64.b64decode(data, validate=True)
208
+ # Try to open it as an image
209
+ Image.open(BytesIO(decoded))
210
+ return True
211
+ except Exception as e:
212
+ return False
@@ -0,0 +1,48 @@
1
+ from pydantic import BaseModel
2
+
3
+
4
+ class TokenUsage(BaseModel):
5
+ input_tokens: int = 0
6
+ output_tokens: int = 0
7
+ tool_use_tokens: int = 0
8
+ thoughts_tokens: int = 0
9
+ total_tokens: int = 0
10
+ calculated_total_tokens: int = 0
11
+
12
+ input_cost: float = 0
13
+ output_cost: float = 0
14
+ tool_use_cost: float = 0
15
+ thoughts_cost: float = 0
16
+ total_cost: float = 0
17
+
18
+ def __add__(self, other: "TokenUsage") -> "TokenUsage":
19
+ return TokenUsage(
20
+ input_tokens=self.input_tokens + other.input_tokens,
21
+ output_tokens=self.output_tokens + other.output_tokens,
22
+ total_tokens=self.total_tokens + other.total_tokens,
23
+ tool_use_tokens=self.tool_use_tokens + other.tool_use_tokens,
24
+ thoughts_tokens=self.thoughts_tokens + other.thoughts_tokens,
25
+ calculated_total_tokens=self.calculated_total_tokens
26
+ + other.calculated_total_tokens,
27
+ input_cost=self.input_cost + other.input_cost,
28
+ output_cost=self.output_cost + other.output_cost,
29
+ tool_use_cost=self.tool_use_cost + other.tool_use_cost,
30
+ thoughts_cost=self.thoughts_cost + other.thoughts_cost,
31
+ total_cost=self.total_cost + other.total_cost,
32
+ )
33
+
34
+ def __sub__(self, other: "TokenUsage") -> "TokenUsage":
35
+ return TokenUsage(
36
+ input_tokens=self.input_tokens - other.input_tokens,
37
+ output_tokens=self.output_tokens - other.output_tokens,
38
+ total_tokens=self.total_tokens - other.total_tokens,
39
+ tool_use_tokens=self.tool_use_tokens - other.tool_use_tokens,
40
+ thoughts_tokens=self.thoughts_tokens - other.thoughts_tokens,
41
+ calculated_total_tokens=self.calculated_total_tokens
42
+ - other.calculated_total_tokens,
43
+ input_cost=self.input_cost - other.input_cost,
44
+ output_cost=self.output_cost - other.output_cost,
45
+ tool_use_cost=self.tool_use_cost - other.tool_use_cost,
46
+ thoughts_cost=self.thoughts_cost - other.thoughts_cost,
47
+ total_cost=self.total_cost - other.total_cost,
48
+ )
File without changes
@@ -0,0 +1,54 @@
1
+ import logging
2
+ import os
3
+ from typing import Literal
4
+
5
+ from pydantic import model_validator
6
+ from pydantic_settings import BaseSettings
7
+
8
+ logger = logging.getLogger(__name__)
9
+
10
+ env_path = os.getenv("ENV_PATH")
11
+ if not env_path:
12
+ logger.warning("ENV_PATH is not set, using default values")
13
+
14
+
15
+ class Settings(BaseSettings):
16
+ SERVER_URL: str = "https://api.optexity.com"
17
+ HEALTH_ENDPOINT: str = "api/v1/health"
18
+ INFERENCE_ENDPOINT: str = "api/v1/inference"
19
+ ADD_EXAMPLE_ENDPOINT: str = "api/v1/add_example"
20
+ UPDATE_EXAMPLE_ENDPOINT: str = "api/v1/update_example"
21
+ START_TASK_ENDPOINT: str = "api/v1/start_task"
22
+ COMPLETE_TASK_ENDPOINT: str = "api/v1/complete_task"
23
+ SAVE_OUTPUT_DATA_ENDPOINT: str = "api/v1/save_output_data"
24
+ SAVE_DOWNLOADS_ENDPOINT: str = "api/v1/save_downloads"
25
+ SAVE_TRAJECTORY_ENDPOINT: str = "api/v1/save_trajectory"
26
+ INITIATE_CALLBACK_ENDPOINT: str = "api/v1/initiate_callback"
27
+ GET_CALLBACK_DATA_ENDPOINT: str = "api/v1/get_callback_data"
28
+ FETCH_EMAIL_MESSAGES_ENDPOINT: str = "api/v1/fetch_email_messages"
29
+ FETCH_SLACK_MESSAGES_ENDPOINT: str = "api/v1/fetch_slack_messages"
30
+
31
+ API_KEY: str
32
+
33
+ CHILD_PORT_OFFSET: int = 9000
34
+ DEPLOYMENT: Literal["dev", "prod"]
35
+ LOCAL_CALLBACK_URL: str | None = None
36
+
37
+ PROXY_URL: str | None = None
38
+ PROXY_USERNAME: str | None = None
39
+ PROXY_PASSWORD: str | None = None
40
+ PROXY_COUNTRY: str | None = None
41
+ PROXY_PROVIDER: Literal["oxylabs", "brightdata", "other"] | None = None
42
+
43
+ @model_validator(mode="after")
44
+ def validate_local_callback_url(self):
45
+ if self.DEPLOYMENT == "prod" and self.LOCAL_CALLBACK_URL is not None:
46
+ raise ValueError("LOCAL_CALLBACK_URL is not allowed in prod mode")
47
+ return self
48
+
49
+ class Config:
50
+ env_file = env_path if env_path else None
51
+ extra = "allow"
52
+
53
+
54
+ settings = Settings()
@@ -0,0 +1,76 @@
1
+ import base64
2
+ import logging
3
+ import os
4
+ from pathlib import Path
5
+ from typing import List, Optional
6
+
7
+ import aiofiles
8
+ import pyotp
9
+ from async_lru import alru_cache
10
+ from onepassword import Client as OnePasswordClient
11
+ from pydantic import create_model
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+ _onepassword_client = None
16
+
17
+
18
+ async def get_onepassword_client():
19
+ global _onepassword_client
20
+ if _onepassword_client is None:
21
+ _onepassword_client = await OnePasswordClient.authenticate(
22
+ auth=os.getenv("OP_SERVICE_ACCOUNT_TOKEN"),
23
+ integration_name="Optexity 1Password Integration",
24
+ integration_version="v1.0.0",
25
+ )
26
+ return _onepassword_client
27
+
28
+
29
+ def build_model(schema: dict, model_name="AutoModel"):
30
+ fields = {}
31
+ for key, value in schema.items():
32
+ if isinstance(value, str): # primitive type
33
+ py_type = eval(value) # e.g., "str" -> str
34
+ fields[key] = (Optional[py_type], None)
35
+ elif isinstance(value, dict): # nested object
36
+ sub_model = build_model(value, model_name=f"{model_name}_{key}")
37
+ fields[key] = (Optional[sub_model], None)
38
+ elif isinstance(value, list): # list of objects or primitives
39
+ if len(value) > 0 and isinstance(value[0], dict):
40
+ sub_model = build_model(value[0], model_name=f"{model_name}_{key}")
41
+ fields[key] = (Optional[List[sub_model]], None)
42
+ else: # list of primitives
43
+ py_type = eval(value[0])
44
+ fields[key] = (Optional[List[py_type]], None)
45
+ return create_model(model_name, **fields)
46
+
47
+
48
+ def save_screenshot(screenshot: str, path: str):
49
+ with open(path, "wb") as f:
50
+ f.write(base64.b64decode(screenshot))
51
+
52
+
53
+ async def save_and_clear_downloaded_files(content: bytes | str, filename: Path):
54
+ if isinstance(content, bytes):
55
+ async with aiofiles.open(filename, "wb") as f:
56
+ await f.write(content)
57
+ elif isinstance(content, str):
58
+ async with aiofiles.open(filename, "w") as f:
59
+ await f.write(content)
60
+ else:
61
+ logger.error(f"Unsupported content type: {type(content)}")
62
+
63
+
64
+ def get_totp_code(totp_secret: str, digits: int = 6):
65
+ totp = pyotp.TOTP(totp_secret, digits=digits)
66
+ return totp.now()
67
+
68
+
69
+ @alru_cache(maxsize=1000)
70
+ async def get_onepassword_value(vault_name: str, item_name: str, field_name: str):
71
+ client = await get_onepassword_client()
72
+ str_value = await client.secrets.resolve(
73
+ f"op://{vault_name}/{item_name}/{field_name}"
74
+ )
75
+
76
+ return str_value
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: optexity
3
- Version: 0.1.2
3
+ Version: 0.1.4
4
4
  Summary: Optexity is a platform for building and running browser and computer agents.
5
5
  Author-email: Optexity <support@optexity.com>
6
6
  Requires-Python: >=3.11
@@ -50,30 +50,19 @@ Once logged in, navigate to the **API Keys** section in your dashboard and creat
50
50
 
51
51
  Install the **Optexity Recorder** extension from the [Chrome Web Store](https://chromewebstore.google.com/detail/optexity-recorder/pbaganbicadeoacahamnbgohafchgakp). This extension captures your browser interactions and converts them into automation workflows.
52
52
 
53
- ## Installation
54
-
55
53
  ### Prerequisites
56
54
 
57
55
  - Python 3.11+
58
- - Node.js 18+ (included with Conda option)
59
56
  - Git
60
57
 
61
- ### Step 1: Clone the Repository
62
-
63
- ```bash
64
- git clone git@github.com:Optexity/optexity.git
65
- cd optexity
66
- ./update_submodule.sh
67
- ```
68
-
69
- ### Step 2: Create and Activate a Python Environment
58
+ ## Create and Activate a Python Environment (Optional)
70
59
 
71
60
  Choose **one** of the options below.
72
61
 
73
62
  #### Option A – Conda (includes Python 3.11 and Node.js)
74
63
 
75
64
  ```bash
76
- conda create -n optexity python=3.11 nodejs
65
+ conda create -n optexity python=3.11
77
66
  conda activate optexity
78
67
  ```
79
68
 
@@ -86,32 +75,29 @@ python3 -m venv .venv
86
75
  source .venv/bin/activate
87
76
  ```
88
77
 
89
- > If you pick `venv`, ensure Node.js 18+ is already available on your machine before continuing.
78
+ ## Installation
90
79
 
91
- ### Step 3: Install Dependencies
80
+ ### Quick Installation (from PyPI)
92
81
 
93
- Run everything from the repository root:
82
+ Install Optexity directly from PyPI:
94
83
 
95
84
  ```bash
96
- pip install -e "external/browser-use"
97
- pip install -e .
98
- playwright install --with-deps chromium chrome
99
- patchright install chromium chrome
100
- pre-commit install --install-hooks
101
- pre-commit install --hook-type pre-push
85
+ pip install optexity
102
86
  ```
87
+ **OR**
103
88
 
104
- ### Step 4: Configure Your Environment
89
+ ### Installation from Source
105
90
 
106
- Optexity reads configuration from a standard `.env` file via the `ENV_PATH` environment variable.
91
+ If you want to clone and edit from source:
107
92
 
108
- Create a `.env` file in the repo root:
109
93
 
110
94
  ```bash
111
- touch .env
95
+ git clone git@github.com:Optexity/optexity.git
96
+ cd optexity
97
+ pip install -e .
112
98
  ```
113
99
 
114
- Add the required values:
100
+ ## Set required environment variables:
115
101
 
116
102
  ```bash
117
103
  API_KEY=YOUR_OPTEXITY_API_KEY # API key used for authenticated requests
@@ -121,14 +107,14 @@ DEPLOYMENT=dev # or "prod" in production
121
107
 
122
108
  You can get your free Google Gemini API key from the [Google AI Studio Console](https://aistudio.google.com).
123
109
 
124
- Then export `ENV_PATH` when running processes that rely on these settings:
110
+ ## Install required browsers:
111
+
112
+ Install playwright and patchright browsers:
125
113
 
126
114
  ```bash
127
- export ENV_PATH=.env
115
+ optexity install-browsers
128
116
  ```
129
117
 
130
- > If `ENV_PATH` is not set, the inference server will try to start with defaults and log a warning. For normal usage you should always point `ENV_PATH` at a real `.env` file.
131
-
132
118
  ## Recording Your First Automation
133
119
 
134
120
  The fastest way to create an automation is by recording your actions directly in the browser.
@@ -156,12 +142,10 @@ The fastest way to create an automation is by recording your actions directly in
156
142
 
157
143
  ### Start the Inference Server
158
144
 
159
- The primary way to run browser automations locally is via the inference child process server.
160
-
161
- From the repository root:
145
+ The primary way to run browser automations locally is via the inference server.
162
146
 
163
147
  ```bash
164
- ENV_PATH=.env python optexity/inference/child_process.py --port 9000 --child_process_id 0
148
+ optexity inference --port 9000 --child_process_id 0
165
149
  ```
166
150
 
167
151
  Key parameters:
@@ -0,0 +1,80 @@
1
+ optexity/__init__.py,sha256=dqh4tGEzruZnkvRLjPYKyc2-FVlXLx1Dj-JNy5fy7U8,459
2
+ optexity/cli.py,sha256=2g_p2Qh7jzFFG5T0aTDiZ7Celh-KycEMJ873whiXFXE,2237
3
+ optexity/exceptions.py,sha256=j4QxbcnAl5RmEJPJ0MWZ0iM38HvW-r8xmxtDxZ1ceSY,269
4
+ optexity/onepassword_integration.py,sha256=_1sQ8sRGVdDnA7384FXiXYRVntPB-ZQAu8W7ICX7_VQ,1047
5
+ optexity/test.py,sha256=pMSZwwA8tj6jAfFUJ3OUHGnTPriqkv4eDGGHqdAdrsA,2797
6
+ optexity/examples/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ optexity/examples/add_example.py,sha256=jVPd2pQ9lnmdwsVsld52CkRafYcF60SrQyDU3QFKTwY,2474
8
+ optexity/examples/download_pdf_url.py,sha256=mB1Kp0UC4AuHeIiyxMt5tlNK5urNPUosHjmUvV67qdM,829
9
+ optexity/examples/extract_price_stockanalysis.py,sha256=oUMAXW0TKFjJO6KCDIsThaMwNNC_Zx5_ZfkuYTo9xmE,1520
10
+ optexity/examples/file_upload.py,sha256=Ep9wxjZFjlcWVufkhLt_RufZMbC8BJ8amASFO7uKGCk,2030
11
+ optexity/examples/i94.py,sha256=QB-Vo6jB03wOovsNh6_TsdxvdJf3MbnxVeUlEoVtUhA,4534
12
+ optexity/examples/i94_travel_history.py,sha256=PbU-xg3xVoEgRPaZQfC5JPNcHA6ClTu8X7650TK1_dc,4573
13
+ optexity/examples/peachstate_medicaid.py,sha256=0PQN3SI5NGw0m95ODm-bHYgF0xwpA83_9xflnN8P4mM,8290
14
+ optexity/examples/supabase_login.py,sha256=_j5VZi0HkqpWl0xguMoHc3gfkf3FiJWnQPs8D_QARN4,2349
15
+ optexity/inference/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ optexity/inference/child_process.py,sha256=0-HoM9yUtYf7BzfCeKS_uUO4NfrdAESryuHaKYRwEoY,8098
17
+ optexity/inference/run_local.py,sha256=P-ghDcNhHESuG7Q6Qp6xdl6r0g2lAyDkIhKsyaLBcPs,6743
18
+ optexity/inference/agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
+ optexity/inference/agents/error_handler/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
+ optexity/inference/agents/error_handler/error_handler.py,sha256=95T19gFgdvOcD1lVbEDmuB9-D5LB_08xAjSc2ezyaCs,1111
21
+ optexity/inference/agents/error_handler/prompt.py,sha256=911fxUvQzG2OhjstGSB0ioDOeZopmuHCfPVOY4cZSbM,4333
22
+ optexity/inference/agents/index_prediction/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
23
+ optexity/inference/agents/index_prediction/action_prediction_locator_axtree.py,sha256=KJdBss76h92iYpiwdwBUhsfhtGeVnhsGMokdJvGsjj4,1280
24
+ optexity/inference/agents/index_prediction/prompt.py,sha256=51nMQExOmVEVoMWr2hkYGdR9_yDMXt0m1LxhILILT2E,1005
25
+ optexity/inference/agents/select_value_prediction/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
+ optexity/inference/agents/select_value_prediction/prompt.py,sha256=r59j6P4TN-NtGjpmtTsjLxH_nsoLeukMNDE0_cVqj_4,1351
27
+ optexity/inference/agents/select_value_prediction/select_value_prediction.py,sha256=QlBdZRW_QJ1xS8b8CY25UlPHcS1obuwKxjVoZl9b30k,1167
28
+ optexity/inference/agents/two_fa_extraction/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
+ optexity/inference/agents/two_fa_extraction/prompt.py,sha256=eAqz_InZeyTnFqPMeYm-xyF7rtFWMBIF7nQW3QJnW08,1328
30
+ optexity/inference/agents/two_fa_extraction/two_fa_extraction.py,sha256=UcBo_Iyx6Kqas-fUZpJgos5R-t2hQ2PZUFjtHmO9Rh0,1444
31
+ optexity/inference/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
+ optexity/inference/core/logging.py,sha256=Zq2KL6XWlPIgsJjprxv-BLsnP5MAAKS2ciNMNkQrfBU,13870
33
+ optexity/inference/core/run_assertion.py,sha256=8ydAkSA2E0VajwKZlY2z4Xxxyzo49UsFIZ7ej_l0Cy8,2224
34
+ optexity/inference/core/run_automation.py,sha256=aXsEj3M7BN_VlpDZgZdScsQHB7jfukCAKGvyBSjUMjA,16708
35
+ optexity/inference/core/run_extraction.py,sha256=TaUfFCcKxuMEJELDhcYMjpbyxgRrdVMHNIX6pjo7l5U,7576
36
+ optexity/inference/core/run_interaction.py,sha256=Rs6Sa4cqTpR1jNNPh2IRYfj4sKcFgtWbjTaQN-wRICs,9248
37
+ optexity/inference/core/run_python_script.py,sha256=WjnCmckZz7YmoLTGBLZeFWhhS1s_x0-kgyKYTM17JHI,547
38
+ optexity/inference/core/run_two_fa.py,sha256=m1lxPefJHtXqMYBB0oONxd5f7XX8AI5eUkjjjs5y0Z0,4010
39
+ optexity/inference/core/interaction/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
+ optexity/inference/core/interaction/handle_agentic_task.py,sha256=MSURLDM-2Hw37sipa3lqUBh1NNFrGmx2DPGJsBGYTDg,2617
41
+ optexity/inference/core/interaction/handle_check.py,sha256=_LEA5V6h4x8fozAvPsGrFUZUaO0uU34z2R9VzGIOdio,1489
42
+ optexity/inference/core/interaction/handle_click.py,sha256=IhdYjj-oNGoJInN9XK6ppqW6JQgCNm7t2COymv5T9O8,2249
43
+ optexity/inference/core/interaction/handle_command.py,sha256=a0Eqs5eDJ4bPttqMh4r_IAYJzpXcH9bvUS_9CG8MySA,8350
44
+ optexity/inference/core/interaction/handle_input.py,sha256=UGALiQLUgjgg5Z-vj4lEoEs4_GXCirUBgONUulKs0oU,2256
45
+ optexity/inference/core/interaction/handle_keypress.py,sha256=Ig-U7qoMQ1GIaxeS2TnSTe4N3Jj64WcVc1rwl7Z-0So,466
46
+ optexity/inference/core/interaction/handle_select.py,sha256=1nTm-hyaG4xDnItdulW1--b0zj20FdJq7qks5X-aNKU,3236
47
+ optexity/inference/core/interaction/handle_select_utils.py,sha256=gJnIvBNPFwIkFjYiaVSB-91k95leahrSnlq8fgDcWbQ,4114
48
+ optexity/inference/core/interaction/handle_upload.py,sha256=cIe9lcgA8_jT1KMGcImfqq_PEEVY-Fy5YZjrX2GA8As,1818
49
+ optexity/inference/core/interaction/utils.py,sha256=iWKfn7cF-8duQoMvGfmGV05oOuQEyKPgOdMJe_Hk4KM,2745
50
+ optexity/inference/core/two_factor_auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
51
+ optexity/inference/infra/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
52
+ optexity/inference/infra/browser.py,sha256=GpECOdxhpe5AbwU2FnRmR7jevKUiHHEZCq7PgpMI8t0,15955
53
+ optexity/inference/infra/browser_extension.py,sha256=Ur5_8DrHcgRkD9uulDsVaaj01z1WcsvqHxHok4p4RoM,589
54
+ optexity/inference/models/__init__.py,sha256=f66ea3I8ibNrkn4Uf_wYIn-2eoP-ReXds03LgaopOfA,667
55
+ optexity/inference/models/gemini.py,sha256=ToncY6Ft4kOgIm6qREBVsScT8FG-JCrdWsBxYOgU0is,4100
56
+ optexity/inference/models/human.py,sha256=K2X6Ohg7xeTWDYkJY6lOAwS9T3nX7YST-cvd8nL1Ydw,394
57
+ optexity/inference/models/llm_model.py,sha256=nZvcrQs4XDI07ckFUf6o-TzvyqW-I4WIbos7WEo4hz8,7211
58
+ optexity/schema/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
+ optexity/schema/automation.py,sha256=by9pcgCpG1yDEowBQGeVa30vQ3hO-GCtTiJdcSf4RKY,16121
60
+ optexity/schema/callback.py,sha256=MlN41A6oKG7QX01_w0tsxyAFKWnoCVsu_mjpWzPMYuE,519
61
+ optexity/schema/inference.py,sha256=8mP49IRU-cRxbsC4NnoGZhd5isvdocCuMVspPBOQV9o,2864
62
+ optexity/schema/memory.py,sha256=e3AMDAivCF_KnKbeDugqVLib8UN_6dr3ksUCiWaeIGM,3072
63
+ optexity/schema/task.py,sha256=qv41fXKSVhxVtS5zrS9ihv35ZVZAXlbcTFO2hVrjBlc,6794
64
+ optexity/schema/token_usage.py,sha256=iwZjUqTrNhrEBMeeZNMWqD4qs2toKDczRVoDTOLLNso,2114
65
+ optexity/schema/actions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
66
+ optexity/schema/actions/assertion_action.py,sha256=lcD6h7phacrEoB5j-It9qP9Ym3TKb1bkv1aa8tqwG-Q,1991
67
+ optexity/schema/actions/extraction_action.py,sha256=-d6JaumXRZctiXNqndKE1QOWUR7fllglJ4rGuBpiVNw,4771
68
+ optexity/schema/actions/interaction_action.py,sha256=99KuL6waCMnTB3iK6tyeatRjnIV8yhghBSLkY-_rSDo,10728
69
+ optexity/schema/actions/misc_action.py,sha256=VZvaVemTlCoUwSomA42EX74L81-ICDYNWqJAuWNtyyE,312
70
+ optexity/schema/actions/prompts.py,sha256=GZud5T2kQvQKhAXHmAnalVUP8iMcDz8be3jRp-vAInk,1772
71
+ optexity/schema/actions/two_fa_action.py,sha256=OzzTDX3fZObWJiw8hvNgr96PBcvpDh1uONPfHrPFLf8,564
72
+ optexity/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
73
+ optexity/utils/settings.py,sha256=h6StXzYslRgZf0c8k43-kOxoa77dOgDvSOvfQUi5yI8,1864
74
+ optexity/utils/utils.py,sha256=QgVeKK3jAq-TLgP_RYiCXRAOEbuypFox0RxYEjruoTA,2565
75
+ optexity-0.1.4.dist-info/licenses/LICENSE,sha256=WpSBqSAcwd68PmS3zRsfACJOz-u-UfTzftsEnzp4ZCY,1065
76
+ optexity-0.1.4.dist-info/METADATA,sha256=F4VEHUDrBUHucmeu--S6SsdsiNR93O75dBd4xp6VQyU,9878
77
+ optexity-0.1.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
78
+ optexity-0.1.4.dist-info/entry_points.txt,sha256=hcn77ooRr6a_N8fo0vij3Fpo6waqc9ijpaScQ7Kj35k,47
79
+ optexity-0.1.4.dist-info/top_level.txt,sha256=OZEtBX8IabC8EnBrNW98z7NzdGQsjFhHleSthhjjEMM,9
80
+ optexity-0.1.4.dist-info/RECORD,,
@@ -1,11 +0,0 @@
1
- optexity/__init__.py,sha256=dqh4tGEzruZnkvRLjPYKyc2-FVlXLx1Dj-JNy5fy7U8,459
2
- optexity/cli.py,sha256=bpHwMWGGJVS3TG2uUl2nSJkf916D-kCw_mxzAe_-XeI,2238
3
- optexity/exceptions.py,sha256=j4QxbcnAl5RmEJPJ0MWZ0iM38HvW-r8xmxtDxZ1ceSY,269
4
- optexity/onepassword_integration.py,sha256=_1sQ8sRGVdDnA7384FXiXYRVntPB-ZQAu8W7ICX7_VQ,1047
5
- optexity/test.py,sha256=pMSZwwA8tj6jAfFUJ3OUHGnTPriqkv4eDGGHqdAdrsA,2797
6
- optexity-0.1.2.dist-info/licenses/LICENSE,sha256=WpSBqSAcwd68PmS3zRsfACJOz-u-UfTzftsEnzp4ZCY,1065
7
- optexity-0.1.2.dist-info/METADATA,sha256=hVH-kaFUYJHPOIF5-PVJGA3x8YMUNCjGYpW3J23dXmk,10613
8
- optexity-0.1.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
9
- optexity-0.1.2.dist-info/entry_points.txt,sha256=hcn77ooRr6a_N8fo0vij3Fpo6waqc9ijpaScQ7Kj35k,47
10
- optexity-0.1.2.dist-info/top_level.txt,sha256=OZEtBX8IabC8EnBrNW98z7NzdGQsjFhHleSthhjjEMM,9
11
- optexity-0.1.2.dist-info/RECORD,,