semantio 0.0.2__py3-none-any.whl → 0.0.3__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.
- semantio/agent.py +28 -28
- semantio/cli/main.py +6 -6
- {semantio-0.0.2.dist-info → semantio-0.0.3.dist-info}/METADATA +1 -1
- {semantio-0.0.2.dist-info → semantio-0.0.3.dist-info}/RECORD +8 -10
- semantio/llm/llama.py +0 -0
- semantio/tools/web_browser.py +0 -153
- {semantio-0.0.2.dist-info → semantio-0.0.3.dist-info}/LICENSE +0 -0
- {semantio-0.0.2.dist-info → semantio-0.0.3.dist-info}/WHEEL +0 -0
- {semantio-0.0.2.dist-info → semantio-0.0.3.dist-info}/entry_points.txt +0 -0
- {semantio-0.0.2.dist-info → semantio-0.0.3.dist-info}/top_level.txt +0 -0
semantio/agent.py
CHANGED
@@ -21,24 +21,24 @@ import os
|
|
21
21
|
logging.basicConfig(level=logging.INFO)
|
22
22
|
logger = logging.getLogger(__name__)
|
23
23
|
|
24
|
-
class
|
24
|
+
class Agent(BaseModel):
|
25
25
|
# -*- Agent settings
|
26
|
-
name: Optional[str] = Field(None, description="Name of the
|
27
|
-
description: Optional[str] = Field(None, description="Description of the
|
28
|
-
instructions: Optional[List[str]] = Field(None, description="List of instructions for the
|
26
|
+
name: Optional[str] = Field(None, description="Name of the agent.")
|
27
|
+
description: Optional[str] = Field(None, description="Description of the agent's role.")
|
28
|
+
instructions: Optional[List[str]] = Field(None, description="List of instructions for the agent.")
|
29
29
|
model: Optional[str] = Field(None, description="This one is not in the use.")
|
30
30
|
show_tool_calls: bool = Field(False, description="Whether to show tool calls in the response.")
|
31
31
|
markdown: bool = Field(False, description="Whether to format the response in markdown.")
|
32
|
-
tools: Optional[List[BaseTool]] = Field(None, description="List of tools available to the
|
33
|
-
user_name: Optional[str] = Field("User", description="Name of the user interacting with the
|
34
|
-
emoji: Optional[str] = Field(":robot:", description="Emoji to represent the
|
32
|
+
tools: Optional[List[BaseTool]] = Field(None, description="List of tools available to the agent.")
|
33
|
+
user_name: Optional[str] = Field("User", description="Name of the user interacting with the agent.")
|
34
|
+
emoji: Optional[str] = Field(":robot:", description="Emoji to represent the agent in the CLI.")
|
35
35
|
rag: Optional[RAG] = Field(None, description="RAG instance for context retrieval.")
|
36
36
|
knowledge_base: Optional[Any] = Field(None, description="Knowledge base for domain-specific information.")
|
37
37
|
llm: Optional[str] = Field(None, description="The LLM provider to use (e.g., 'groq', 'openai', 'anthropic').")
|
38
38
|
llm_model: Optional[str] = Field(None, description="The specific model to use for the LLM provider.")
|
39
39
|
llm_instance: Optional[BaseLLM] = Field(None, description="The LLM instance to use.")
|
40
40
|
json_output: bool = Field(False, description="Whether to format the response as JSON.")
|
41
|
-
api: bool = Field(False, description="Whether to generate an API for the
|
41
|
+
api: bool = Field(False, description="Whether to generate an API for the agent.")
|
42
42
|
api_config: Optional[Dict] = Field(
|
43
43
|
None,
|
44
44
|
description="Configuration for the API (e.g., host, port, authentication).",
|
@@ -46,7 +46,7 @@ class Assistant(BaseModel):
|
|
46
46
|
api_generator: Optional[Any] = Field(None, description="The API generator instance.")
|
47
47
|
expected_output: Optional[Union[str, Dict]] = Field(None, description="The expected format or structure of the output.")
|
48
48
|
semantic_model: Optional[Any] = Field(None, description="SentenceTransformer model for semantic matching.")
|
49
|
-
team: Optional[List['
|
49
|
+
team: Optional[List['Agent']] = Field(None, description="List of assistants in the team.")
|
50
50
|
auto_tool: bool = Field(False, description="Whether to automatically detect and call tools.")
|
51
51
|
|
52
52
|
# Allow arbitrary types
|
@@ -125,7 +125,7 @@ class Assistant(BaseModel):
|
|
125
125
|
try:
|
126
126
|
# Import the module
|
127
127
|
module_name = file.stem
|
128
|
-
module = importlib.import_module(f"
|
128
|
+
module = importlib.import_module(f"semantio.tools.{module_name}")
|
129
129
|
|
130
130
|
# Find all classes that inherit from BaseTool
|
131
131
|
for name, obj in module.__dict__.items():
|
@@ -197,7 +197,7 @@ class Assistant(BaseModel):
|
|
197
197
|
model_to_use = self.llm_model or default_model
|
198
198
|
|
199
199
|
# Dynamically import and initialize the LLM class
|
200
|
-
module_name = f"
|
200
|
+
module_name = f"semantio.llm.{llm_provider}"
|
201
201
|
llm_module = importlib.import_module(module_name)
|
202
202
|
llm_class = getattr(llm_module, llm_class_name)
|
203
203
|
self.llm_instance = llm_class(model=model_to_use, api_key=api_key)
|
@@ -214,10 +214,10 @@ class Assistant(BaseModel):
|
|
214
214
|
stream: bool = False,
|
215
215
|
markdown: bool = False,
|
216
216
|
tools: Optional[List[BaseTool]] = None,
|
217
|
-
team: Optional[List['
|
217
|
+
team: Optional[List['Agent']] = None,
|
218
218
|
**kwargs,
|
219
219
|
) -> Union[str, Dict]: # Add return type hint
|
220
|
-
"""Print the
|
220
|
+
"""Print the agent's response to the console and return it."""
|
221
221
|
|
222
222
|
if stream:
|
223
223
|
# Handle streaming response
|
@@ -234,14 +234,14 @@ class Assistant(BaseModel):
|
|
234
234
|
|
235
235
|
|
236
236
|
def _stream_response(self, message: str, markdown: bool = False, **kwargs) -> Iterator[str]:
|
237
|
-
"""Stream the
|
237
|
+
"""Stream the agent's response."""
|
238
238
|
# Simulate streaming by yielding chunks of the response
|
239
239
|
response = self._generate_response(message, markdown=markdown, **kwargs)
|
240
240
|
for chunk in response.split():
|
241
241
|
yield chunk + " "
|
242
242
|
|
243
243
|
def register_tool(self, tool: BaseTool):
|
244
|
-
"""Register a tool for the
|
244
|
+
"""Register a tool for the agent."""
|
245
245
|
if self.tools is None:
|
246
246
|
self.tools = []
|
247
247
|
self.tools.append(tool)
|
@@ -256,7 +256,7 @@ class Assistant(BaseModel):
|
|
256
256
|
|
257
257
|
# Create a prompt for the LLM
|
258
258
|
prompt = f"""
|
259
|
-
You are an AI
|
259
|
+
You are an AI agent that helps users by selecting the most appropriate tool to answer their query. Below is a list of available tools and their functionalities:
|
260
260
|
|
261
261
|
{self._get_tool_descriptions()}
|
262
262
|
|
@@ -290,7 +290,7 @@ class Assistant(BaseModel):
|
|
290
290
|
"""
|
291
291
|
# Create a prompt for the LLM to analyze the query and select tools
|
292
292
|
prompt = f"""
|
293
|
-
You are an AI
|
293
|
+
You are an AI agent that helps analyze user queries and select the most appropriate tools.
|
294
294
|
Below is a list of available tools and their functionalities:
|
295
295
|
|
296
296
|
{self._get_tool_descriptions()}
|
@@ -324,8 +324,8 @@ class Assistant(BaseModel):
|
|
324
324
|
return []
|
325
325
|
|
326
326
|
|
327
|
-
def _generate_response(self, message: str, markdown: bool = False, tools: Optional[List[BaseTool]] = None, team: Optional[List['
|
328
|
-
"""Generate the
|
327
|
+
def _generate_response(self, message: str, markdown: bool = False, tools: Optional[List[BaseTool]] = None, team: Optional[List['Agent']] = None, **kwargs) -> str:
|
328
|
+
"""Generate the agent's response, including tool execution and context retrieval."""
|
329
329
|
# Use the specified tools or team if provided
|
330
330
|
if tools is not None:
|
331
331
|
self.tools = tools
|
@@ -435,12 +435,12 @@ class Assistant(BaseModel):
|
|
435
435
|
# Combine all responses into a single string
|
436
436
|
return "\n\n".join(responses)
|
437
437
|
|
438
|
-
def _generate_team_response(self, message: str, team: List['
|
438
|
+
def _generate_team_response(self, message: str, team: List['Agent'], markdown: bool = False, **kwargs) -> str:
|
439
439
|
"""Generate a response using a team of assistants."""
|
440
440
|
responses = []
|
441
|
-
for
|
442
|
-
response =
|
443
|
-
responses.append(f"**{
|
441
|
+
for agent in team:
|
442
|
+
response = agent.print_response(message, markdown=markdown, **kwargs)
|
443
|
+
responses.append(f"**{agent.name}:**\n\n{response}")
|
444
444
|
return "\n\n".join(responses)
|
445
445
|
|
446
446
|
def _build_prompt(self, message: str, context: Optional[List[Dict]]) -> str:
|
@@ -578,7 +578,7 @@ class Assistant(BaseModel):
|
|
578
578
|
exit_on: Optional[List[str]] = None,
|
579
579
|
**kwargs,
|
580
580
|
):
|
581
|
-
"""Run the
|
581
|
+
"""Run the agent in a CLI app."""
|
582
582
|
from rich.prompt import Prompt
|
583
583
|
|
584
584
|
if message:
|
@@ -593,15 +593,15 @@ class Assistant(BaseModel):
|
|
593
593
|
self.print_response(message=message, **kwargs)
|
594
594
|
|
595
595
|
def _generate_api(self):
|
596
|
-
"""Generate an API for the
|
596
|
+
"""Generate an API for the agent if api=True."""
|
597
597
|
from .api.api_generator import APIGenerator
|
598
598
|
self.api_generator = APIGenerator(self)
|
599
|
-
print(f"API generated for
|
599
|
+
print(f"API generated for agent '{self.name}'. Use `.run_api()` to start the API server.")
|
600
600
|
|
601
601
|
def run_api(self):
|
602
|
-
"""Run the API server for the
|
602
|
+
"""Run the API server for the agent."""
|
603
603
|
if not hasattr(self, 'api_generator'):
|
604
|
-
raise ValueError("API is not enabled for this
|
604
|
+
raise ValueError("API is not enabled for this agent. Set `api=True` when initializing the agent.")
|
605
605
|
|
606
606
|
# Get API configuration
|
607
607
|
host = self.api_config.get("host", "0.0.0.0") if self.api_config else "0.0.0.0"
|
semantio/cli/main.py
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import argparse
|
2
2
|
import warnings
|
3
|
-
from
|
4
|
-
from
|
3
|
+
from semantio.agent import Agent
|
4
|
+
from semantio.llm import get_llm
|
5
5
|
from urllib3.exceptions import NotOpenSSLWarning
|
6
6
|
|
7
7
|
# Suppress the NotOpenSSLWarning
|
@@ -9,7 +9,7 @@ warnings.filterwarnings("ignore", category=NotOpenSSLWarning)
|
|
9
9
|
|
10
10
|
def main():
|
11
11
|
parser = argparse.ArgumentParser(description="opAi CLI")
|
12
|
-
parser.add_argument("--message", type=str, required=True, help="Message to send to the
|
12
|
+
parser.add_argument("--message", type=str, required=True, help="Message to send to the agent")
|
13
13
|
parser.add_argument("--provider", type=str, required=True, help="LLM provider (e.g., groq, openai)")
|
14
14
|
parser.add_argument("--api-key", type=str, required=True, help="API key for the LLM provider")
|
15
15
|
parser.add_argument("--model", type=str, default=None, help="Model name (e.g., mixtral-8x7b-32768)")
|
@@ -22,9 +22,9 @@ def main():
|
|
22
22
|
|
23
23
|
llm = get_llm(provider=args.provider, **llm_config)
|
24
24
|
|
25
|
-
# Create an
|
26
|
-
|
27
|
-
|
25
|
+
# Create an agent
|
26
|
+
agent = Agent(model=args.provider, llm=llm)
|
27
|
+
agent.print_response(args.message)
|
28
28
|
|
29
29
|
|
30
30
|
if __name__ == "__main__":
|
@@ -1,12 +1,12 @@
|
|
1
1
|
semantio/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
semantio/agent.py,sha256=
|
2
|
+
semantio/agent.py,sha256=plQ4D76cnJ1FaGlEuKDeA53aW_hMDvt5sbmUuTHqvFQ,30143
|
3
3
|
semantio/memory.py,sha256=eNAwyAokppHzMcIyFgOw2hT2wnLQBd9GL4T5eallNV4,281
|
4
4
|
semantio/rag.py,sha256=ROy3Pa1NURcDs6qQZ8IMoa5Xlzt6I-msEq0C1p8UgB0,472
|
5
5
|
semantio/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
6
6
|
semantio/api/api_generator.py,sha256=Q-USITEpluRESEaQuOmF7m1vhLKYU9P8eGlQppKT9J4,829
|
7
7
|
semantio/api/fastapi_app.py,sha256=DyTgKJKikMe2G6wWmyzo1rBLXQFi8UWWUMY3UGH4f24,2128
|
8
8
|
semantio/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
9
|
-
semantio/cli/main.py,sha256=
|
9
|
+
semantio/cli/main.py,sha256=jUvSfehbHWALwracEgBopMIVMraSV9QmDUFfgGcxnP0,1091
|
10
10
|
semantio/knowledge_base/__init__.py,sha256=mvp0GFiGSjcxlkaDulAwKOCL9s6gsKTqhPKXF9N3n1g,172
|
11
11
|
semantio/knowledge_base/document_loader.py,sha256=nix0yZJ-JJoDbhLkpg5bKDMvNrwykmknI7MRIn0N81k,1910
|
12
12
|
semantio/knowledge_base/retriever.py,sha256=XpdzKS1UCncJImVMtG67VXMC7lp2eRzKnShjvktsFMM,1271
|
@@ -17,7 +17,6 @@ semantio/llm/base_llm.py,sha256=VFl_2S4kqYDuCTWIfWMbKU5aNbVqOCG33E4APOSHF90,668
|
|
17
17
|
semantio/llm/deepseek.py,sha256=oxX-Uw0_lY2sstYs5KGBGFB_hAZUbZomPADdib1mY2M,1100
|
18
18
|
semantio/llm/gemini.py,sha256=er3zv1jOvWQBGbPuv4fS4pR_c_abHyhroe-rkXupOO4,1959
|
19
19
|
semantio/llm/groq.py,sha256=1AH30paKzDIQjBjWPQPN44QwFHsIOVwI-a587-cDIVc,4285
|
20
|
-
semantio/llm/llama.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
21
20
|
semantio/llm/mistral.py,sha256=NpvaB1cE6-jMEBdT0mTf6Ca4Qq2LS8QivDKI6AgdRjE,1061
|
22
21
|
semantio/llm/openai.py,sha256=I3ab-d_zFxm-TDhYk6t1PzDtElPJEEQ2eSiARBNIGi4,5174
|
23
22
|
semantio/storage/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -28,16 +27,15 @@ semantio/tools/base_tool.py,sha256=xBNSa_8a8WmA4BGRLG2dE7wj9GnBcZo7-P2SyD86GvY,5
|
|
28
27
|
semantio/tools/crypto.py,sha256=mut1ztvpPcUUP3b563dh_FmKtP68KmNis3Qm8WENj8w,5559
|
29
28
|
semantio/tools/duckduckgo.py,sha256=6mGn0js0cIsVxQlAgB8AYNLP05H8WmJKnSVosiO9iH0,5034
|
30
29
|
semantio/tools/stocks.py,sha256=BVuK61O9OmWQjj0YdiCJY6TzpiFJ_An1UJB2RkDfX2k,5393
|
31
|
-
semantio/tools/web_browser.py,sha256=LMwPFTHNTtqCp8MEHVlJJUSJa91vM7MZWIL5RDQKF4U,4980
|
32
30
|
semantio/utils/__init__.py,sha256=Lx4X4iJpRhZzRmpQb80XXh5Ve8ZMOkadWAxXSmHpO_8,244
|
33
31
|
semantio/utils/config.py,sha256=ZTwUTqxjW3-w94zoU7GzivWyJe0JJGvBfuB4RUOuEs8,1198
|
34
32
|
semantio/utils/date_utils.py,sha256=x3oqRGv6ee_KCJ0LvCqqZh_FSgS6YGOHBwZQS4TJetY,1471
|
35
33
|
semantio/utils/file_utils.py,sha256=b_cMuJINEGk9ikNuNHSn9lsmICWwvtnCDZ03ndH_S2I,1779
|
36
34
|
semantio/utils/logger.py,sha256=TmGbP8BRjLMWjXi2GWzZ0RIXt70x9qX3FuIqghCNlwM,510
|
37
35
|
semantio/utils/validation_utils.py,sha256=iwoxEb4Q5ILqV6tbesMjPWPCCoL3AmPLejGUy6q8YvQ,1284
|
38
|
-
semantio-0.0.
|
39
|
-
semantio-0.0.
|
40
|
-
semantio-0.0.
|
41
|
-
semantio-0.0.
|
42
|
-
semantio-0.0.
|
43
|
-
semantio-0.0.
|
36
|
+
semantio-0.0.3.dist-info/LICENSE,sha256=teQbWD2Zlcl1_Fo29o2tNbs6G26hbCQiUzds5fQGYlY,1063
|
37
|
+
semantio-0.0.3.dist-info/METADATA,sha256=M5Q-waTknpyWrD_HV9G76jMKgPHPrBBwM5Hl8we4ulo,6800
|
38
|
+
semantio-0.0.3.dist-info/WHEEL,sha256=ewwEueio1C2XeHTvT17n8dZUJgOvyCWCt0WVNLClP9o,92
|
39
|
+
semantio-0.0.3.dist-info/entry_points.txt,sha256=zbPgevSLwcLpdRHqI_atE8EOt8lK2vRF1AoDflDTo18,53
|
40
|
+
semantio-0.0.3.dist-info/top_level.txt,sha256=Yte_6mb-bh-I_lQwMjk1GijZkxPoX4Zmp3kBftC1ZlA,9
|
41
|
+
semantio-0.0.3.dist-info/RECORD,,
|
semantio/llm/llama.py
DELETED
File without changes
|
semantio/tools/web_browser.py
DELETED
@@ -1,153 +0,0 @@
|
|
1
|
-
from typing import Dict, Any, Optional, List
|
2
|
-
from playwright.async_api import async_playwright
|
3
|
-
import asyncio
|
4
|
-
import logging
|
5
|
-
|
6
|
-
logger = logging.getLogger(__name__)
|
7
|
-
|
8
|
-
class WebBrowserTool:
|
9
|
-
"""
|
10
|
-
A tool for performing browser automation tasks using Playwright.
|
11
|
-
"""
|
12
|
-
|
13
|
-
def __init__(self, headless: bool = True):
|
14
|
-
"""
|
15
|
-
Initialize the WebBrowserTool.
|
16
|
-
|
17
|
-
Args:
|
18
|
-
headless (bool): Whether to run the browser in headless mode (default: True).
|
19
|
-
"""
|
20
|
-
self.headless = headless
|
21
|
-
self.browser = None
|
22
|
-
self.context = None
|
23
|
-
self.page = None
|
24
|
-
|
25
|
-
async def start(self):
|
26
|
-
"""
|
27
|
-
Start the browser and create a new context and page.
|
28
|
-
"""
|
29
|
-
self.playwright = await async_playwright().start()
|
30
|
-
self.browser = await self.playwright.chromium.launch(headless=self.headless)
|
31
|
-
self.context = await self.browser.new_context()
|
32
|
-
self.page = await self.context.new_page()
|
33
|
-
logger.info("Browser started successfully.")
|
34
|
-
|
35
|
-
async def close(self):
|
36
|
-
"""
|
37
|
-
Close the browser and cleanup resources.
|
38
|
-
"""
|
39
|
-
if self.browser:
|
40
|
-
await self.browser.close()
|
41
|
-
await self.playwright.stop()
|
42
|
-
logger.info("Browser closed successfully.")
|
43
|
-
|
44
|
-
async def navigate(self, url: str) -> str:
|
45
|
-
"""
|
46
|
-
Navigate to a specific URL.
|
47
|
-
|
48
|
-
Args:
|
49
|
-
url (str): The URL to navigate to.
|
50
|
-
|
51
|
-
Returns:
|
52
|
-
str: The page title after navigation.
|
53
|
-
"""
|
54
|
-
if not self.page:
|
55
|
-
raise RuntimeError("Browser is not started. Call start() first.")
|
56
|
-
|
57
|
-
await self.page.goto(url)
|
58
|
-
title = await self.page.title()
|
59
|
-
logger.info(f"Navigated to {url}. Page title: {title}")
|
60
|
-
return title
|
61
|
-
|
62
|
-
async def fill_form(self, fields: Dict[str, str]) -> str:
|
63
|
-
"""
|
64
|
-
Fill a form with the provided fields.
|
65
|
-
|
66
|
-
Args:
|
67
|
-
fields (Dict[str, str]): A dictionary of field names and values to fill.
|
68
|
-
|
69
|
-
Returns:
|
70
|
-
str: A success message.
|
71
|
-
"""
|
72
|
-
if not self.page:
|
73
|
-
raise RuntimeError("Browser is not started. Call start() first.")
|
74
|
-
|
75
|
-
for field, value in fields.items():
|
76
|
-
await self.page.fill(f'input[name="{field}"]', value)
|
77
|
-
logger.info(f"Filled field '{field}' with value '{value}'.")
|
78
|
-
|
79
|
-
return "Form filled successfully."
|
80
|
-
|
81
|
-
async def click(self, selector: str) -> str:
|
82
|
-
"""
|
83
|
-
Click an element on the page.
|
84
|
-
|
85
|
-
Args:
|
86
|
-
selector (str): The CSS selector of the element to click.
|
87
|
-
|
88
|
-
Returns:
|
89
|
-
str: A success message.
|
90
|
-
"""
|
91
|
-
if not self.page:
|
92
|
-
raise RuntimeError("Browser is not started. Call start() first.")
|
93
|
-
|
94
|
-
await self.page.click(selector)
|
95
|
-
logger.info(f"Clicked element with selector '{selector}'.")
|
96
|
-
return f"Clicked element: {selector}"
|
97
|
-
|
98
|
-
async def scrape(self, selector: str) -> List[Dict[str, str]]:
|
99
|
-
"""
|
100
|
-
Scrape data from the page.
|
101
|
-
|
102
|
-
Args:
|
103
|
-
selector (str): The CSS selector of the elements to scrape.
|
104
|
-
|
105
|
-
Returns:
|
106
|
-
List[Dict[str, str]]: A list of dictionaries containing the scraped data.
|
107
|
-
"""
|
108
|
-
if not self.page:
|
109
|
-
raise RuntimeError("Browser is not started. Call start() first.")
|
110
|
-
|
111
|
-
elements = await self.page.query_selector_all(selector)
|
112
|
-
scraped_data = []
|
113
|
-
for element in elements:
|
114
|
-
text = await element.inner_text()
|
115
|
-
scraped_data.append({"text": text.strip()})
|
116
|
-
logger.info(f"Scraped text: {text.strip()}")
|
117
|
-
|
118
|
-
return scraped_data
|
119
|
-
|
120
|
-
async def execute_step(self, step: Dict[str, Any]) -> str:
|
121
|
-
"""
|
122
|
-
Execute a browser automation step.
|
123
|
-
|
124
|
-
Args:
|
125
|
-
step (Dict[str, Any]): A dictionary containing the step details.
|
126
|
-
- "action": The action to perform (e.g., "navigate", "fill_form", "click", "scrape").
|
127
|
-
- "details": The details required for the action (e.g., URL, form fields, selector).
|
128
|
-
- "website": The website to perform the action on (optional).
|
129
|
-
|
130
|
-
Returns:
|
131
|
-
str: The result of the step execution.
|
132
|
-
"""
|
133
|
-
action = step.get("action")
|
134
|
-
details = step.get("details")
|
135
|
-
website = step.get("website", "https://www.google.com")
|
136
|
-
|
137
|
-
if not self.page:
|
138
|
-
await self.start()
|
139
|
-
|
140
|
-
try:
|
141
|
-
if action == "navigate":
|
142
|
-
return await self.navigate(details)
|
143
|
-
elif action == "fill_form":
|
144
|
-
return await self.fill_form(details)
|
145
|
-
elif action == "click":
|
146
|
-
return await self.click(details)
|
147
|
-
elif action == "scrape":
|
148
|
-
return str(await self.scrape(details))
|
149
|
-
else:
|
150
|
-
return f"Unknown action: {action}"
|
151
|
-
except Exception as e:
|
152
|
-
logger.error(f"Error executing step: {e}")
|
153
|
-
return f"Error executing step: {e}"
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|