generate description for cached action (#3603)

This commit is contained in:
Shuchang Zheng
2025-10-02 18:53:08 -07:00
committed by GitHub
parent dd235e6ce4
commit 1cfa23ae38
4 changed files with 110 additions and 5 deletions

View File

@@ -268,6 +268,55 @@ class SkyvernPage:
timeout=timeout,
)
async def _update_action_reasoning(
self,
action_id: str,
organization_id: str,
action_type: ActionType,
intention: str = "",
text: str | None = None,
select_option: SelectOption | None = None,
file_url: str | None = None,
data_extraction_goal: str | None = None,
data_extraction_schema: dict[str, Any] | list | str | None = None,
) -> str:
"""Generate user-facing reasoning for an action using the secondary LLM."""
reasoning = f"Auto-generated action for {action_type.value}"
try:
context = skyvern_context.current()
if not context or not context.organization_id:
return f"Auto-generated action for {action_type.value}"
# Build the prompt with available context
prompt = prompt_engine.load_prompt(
template="generate-action-reasoning",
action_type=action_type.value,
intention=intention,
text=text,
select_option=select_option.value if select_option else None,
file_url=file_url,
data_extraction_goal=data_extraction_goal,
data_extraction_schema=data_extraction_schema,
)
# Call secondary LLM to generate reasoning
json_response = await app.SECONDARY_LLM_API_HANDLER(
prompt=prompt,
prompt_name="generate-action-reasoning",
organization_id=context.organization_id,
)
reasoning = json_response.get("reasoning", f"Auto-generated action for {action_type.value}")
except Exception:
LOG.warning("Failed to generate action reasoning, using fallback", action_type=action_type)
await app.DATABASE.update_action_reasoning(
organization_id=organization_id,
action_id=action_id,
reasoning=reasoning,
)
return reasoning
async def _create_action_after_execution(
self,
action_type: ActionType,
@@ -312,14 +361,17 @@ class SkyvernPage:
step_order=0, # Will be updated by the system if needed
action_order=context.action_order, # Will be updated by the system if needed
intention=intention,
reasoning=f"Auto-generated action for {action_type.value}",
text=text,
option=select_option,
file_url=file_url,
response=response,
created_by="script",
)
data_extraction_goal = None
data_extraction_schema = None
if action_type == ActionType.EXTRACT:
data_extraction_goal = kwargs.get("prompt")
data_extraction_schema = kwargs.get("schema")
action = ExtractAction(
element_id="",
action_type=action_type,
@@ -331,15 +383,29 @@ class SkyvernPage:
step_order=0,
action_order=context.action_order,
intention=intention,
reasoning=f"Auto-generated action for {action_type.value}",
data_extraction_goal=kwargs.get("prompt"),
data_extraction_schema=kwargs.get("schema"),
data_extraction_goal=data_extraction_goal,
data_extraction_schema=data_extraction_schema,
option=select_option,
response=response,
created_by="script",
)
created_action = await app.DATABASE.create_action(action)
# Generate user-facing reasoning using secondary LLM
asyncio.create_task(
self._update_action_reasoning(
action_id=str(created_action.action_id),
organization_id=str(context.organization_id),
action_type=action_type,
intention=intention,
text=text,
select_option=select_option,
file_url=file_url,
data_extraction_goal=data_extraction_goal,
data_extraction_schema=data_extraction_schema,
)
)
context.action_order += 1
return created_action

View File

@@ -0,0 +1,20 @@
Generating a user-facing description for an browser action to help users understand what the action is doing and why.
Action Information:
- Action Type: {{ action_type }}
{% if intention %}- Intention: {{ intention }}{% endif %}
{% if text %}- Text/Value: {{ text }}{% endif %}
{% if select_option %}- Selected Option: {{ select_option }}{% endif %}
{% if file_url %}- File URL: {{ file_url }}{% endif %}
{% if data_extraction_goal %}- Data Extraction Goal: {{ data_extraction_goal }}{% endif %}
{% if data_extraction_schema %}- Data Extraction Schema: {{ data_extraction_schema }}{% endif %}
MAKE SURE YOU OUTPUT VALID JSON. No text before or after JSON, no trailing commas, no comments (//), no unnecessary quotes, etc.
Respond with the following JSON format:
```
{
"reasoning": str // A clear, user-friendly explanation (one sentence, 20 words max) of what this action is doing. Use present tense like "Clicking the submit button" or "Entering the email address". Focus on the action and its purpose.
}
```

View File

@@ -2673,6 +2673,25 @@ class AgentDB:
await session.refresh(new_action)
return Action.model_validate(new_action)
async def update_action_reasoning(
self,
organization_id: str,
action_id: str,
reasoning: str,
) -> Action:
async with self.Session() as session:
action = (
await session.scalars(
select(ActionModel).filter_by(action_id=action_id).filter_by(organization_id=organization_id)
)
).first()
if action:
action.reasoning = reasoning
await session.commit()
await session.refresh(action)
return Action.model_validate(action)
raise NotFoundError(f"Action {action_id}")
async def retrieve_action_plan(self, task: Task) -> list[Action]:
async with self.Session() as session:
subquery = (

View File

@@ -525,7 +525,7 @@ class WorkflowCreateYAMLRequest(BaseModel):
status: WorkflowStatus = WorkflowStatus.published
run_with: str | None = None
ai_fallback: bool = False
cache_key: str | None = "default"
cache_key: str | None = None
run_sequentially: bool = False
sequential_key: str | None = None