-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtask_generator.py
More file actions
141 lines (116 loc) · 4.49 KB
/
Copy pathtask_generator.py
File metadata and controls
141 lines (116 loc) · 4.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
"""
Task Generator - LLM-powered task refinement for browser automation.
Converts vague user inputs into structured, numbered task steps using Gemini.
"""
import asyncio
from typing import Optional
from google import genai
from google.genai import types
async def generate_task(
user_input: str,
api_key: str,
model: Optional[str] = None,
verbose: bool = False
) -> str:
"""
Convert vague user input into structured numbered task steps.
Args:
user_input: The user's original task description
api_key: Google API key for Gemini
model: Gemini model name (defaults to gemini-3-flash-preview)
verbose: Print generation progress
Returns:
str: Refined task with numbered steps, or original input if generation fails
"""
# Default model
if not model:
model = "gemini-3-flash-preview"
# Validate API key
if not api_key:
if verbose:
print("Warning: No API key provided for task generation")
return user_input
# System prompt for task refinement
prompt = f"""You are a task planning assistant for a browser automation agent.
Available browser actions:
- Navigate to a URL (must be explicit, e.g., https://example.com)
- Take snapshot to see page elements
- Click on elements by index
- Type text into input fields
- Save current page as PDF
- Go back to previous page
- Wait for specified seconds
Convert the user's request into a numbered list of clear, specific steps (3-10 steps).
Requirements:
1. Use full URLs (https://example.com, not "search for URL")
2. Include snapshot steps after navigation to see elements
3. Be explicit about filenames for PDFs
4. Keep steps actionable and clear
5. Output ONLY the numbered list, no extra commentary
USER TASK: {user_input}
OUTPUT (numbered steps only):"""
try:
if verbose:
print(f"Generating structured task with {model}...")
# Initialize client
client = genai.Client(api_key=api_key)
# Generate with timeout
response = await asyncio.wait_for(
asyncio.to_thread(
client.models.generate_content,
model=model,
contents=[types.Content(
role="user",
parts=[types.Part.from_text(text=prompt)]
)],
config=types.GenerateContentConfig(
temperature=0.3, # Low temperature for consistent output
max_output_tokens=500
)
),
timeout=10.0 # 10 second timeout
)
# Extract text from response
if not response.candidates:
if verbose:
print("Warning: No response from LLM, using original input")
return user_input
refined_task = response.candidates[0].content.parts[0].text.strip()
# Validate that we got a numbered list
if not refined_task or not any(line.strip().startswith(('1.', '1)', '1 ')) for line in refined_task.split('\n')[:3]):
if verbose:
print("Warning: Response not in numbered format, using original input")
return user_input
return refined_task
except asyncio.TimeoutError:
if verbose:
print("Warning: Task generation timed out, retrying once...")
# Retry once
try:
response = await asyncio.wait_for(
asyncio.to_thread(
client.models.generate_content,
model=model,
contents=[types.Content(
role="user",
parts=[types.Part.from_text(text=prompt)]
)],
config=types.GenerateContentConfig(
temperature=0.3,
max_output_tokens=500
)
),
timeout=10.0
)
if response.candidates:
refined_task = response.candidates[0].content.parts[0].text.strip()
if refined_task and any(line.strip().startswith(('1.', '1)', '1 ')) for line in refined_task.split('\n')[:3]):
return refined_task
except Exception as retry_error:
if verbose:
print(f"Warning: Retry failed ({retry_error}), using original input")
return user_input
except Exception as e:
if verbose:
print(f"Warning: Task generation failed ({e}), using original input")
return user_input