203 lines
7.6 KiB
Python
203 lines
7.6 KiB
Python
"""
|
|
React Mode Prompt Generation
|
|
Handles prompt templates for react mode action handling.
|
|
"""
|
|
|
|
from typing import Any, List
|
|
from modules.datamodels.datamodelChat import PromptBundle, PromptPlaceholder
|
|
from modules.workflows.processing.shared.placeholderFactory import (
|
|
extractUserPrompt,
|
|
extractUserLanguage,
|
|
extractAvailableMethods,
|
|
extractAvailableDocumentsSummary,
|
|
extractAvailableDocumentsIndex,
|
|
extractAvailableConnectionsIndex,
|
|
extractPreviousActionResults,
|
|
extractLearningsAndImprovements,
|
|
extractLatestRefinementFeedback,
|
|
extractWorkflowHistory,
|
|
)
|
|
from modules.workflows.processing.shared.methodDiscovery import methods, getActionParameterList
|
|
|
|
def generateReactPlanSelectionPrompt(services, context: Any) -> PromptBundle:
|
|
"""Define placeholders first, then the template; return PromptBundle."""
|
|
placeholders: List[PromptPlaceholder] = [
|
|
PromptPlaceholder(label="USER_PROMPT", content=extractUserPrompt(context), summaryAllowed=False),
|
|
PromptPlaceholder(label="AVAILABLE_DOCUMENTS_SUMMARY", content=extractAvailableDocumentsSummary(services, context), summaryAllowed=True),
|
|
PromptPlaceholder(label="AVAILABLE_METHODS", content=extractAvailableMethods(services), summaryAllowed=False),
|
|
]
|
|
|
|
template = """Select one action to advance the task.
|
|
|
|
OBJECTIVE:
|
|
{{KEY:USER_PROMPT}}
|
|
|
|
AVAILABLE_DOCUMENTS_SUMMARY:
|
|
{{KEY:AVAILABLE_DOCUMENTS_SUMMARY}}
|
|
|
|
AVAILABLE_METHODS:
|
|
{{KEY:AVAILABLE_METHODS}}
|
|
|
|
REPLY: Return only a JSON object with the selected action:
|
|
{{
|
|
"action": "method.action_name"
|
|
}}
|
|
|
|
RULES:
|
|
1. Use EXACT action names from AVAILABLE_METHODS
|
|
2. Return ONLY JSON - no other text
|
|
3. Do NOT use markdown code blocks
|
|
4. Do NOT add explanations
|
|
"""
|
|
|
|
return PromptBundle(prompt=template, placeholders=placeholders)
|
|
|
|
def generateReactParametersPrompt(services, context: Any, compoundActionName: str) -> PromptBundle:
|
|
"""Define placeholders first, then the template; return PromptBundle."""
|
|
# derive method/action and parameter list
|
|
methodName, actionName = (compoundActionName.split('.', 1) if '.' in compoundActionName else (compoundActionName, ''))
|
|
actionParameterList = getActionParameterList(methodName, actionName, methods)
|
|
|
|
# determine action objective if available, else fall back to user prompt
|
|
actionObjective = None
|
|
if hasattr(context, 'action_objective') and context.action_objective:
|
|
actionObjective = context.action_objective
|
|
elif hasattr(context, 'task_step') and context.task_step and getattr(context.task_step, 'objective', None):
|
|
actionObjective = context.task_step.objective
|
|
else:
|
|
actionObjective = extractUserPrompt(context)
|
|
|
|
placeholders: List[PromptPlaceholder] = [
|
|
PromptPlaceholder(label="ACTION_OBJECTIVE", content=actionObjective, summaryAllowed=False),
|
|
PromptPlaceholder(label="ACTION_PARAMETER_LIST", content=actionParameterList, summaryAllowed=False),
|
|
PromptPlaceholder(label="AVAILABLE_DOCUMENTS_INDEX", content=extractAvailableDocumentsIndex(services, context), summaryAllowed=True),
|
|
PromptPlaceholder(label="AVAILABLE_CONNECTIONS_INDEX", content=extractAvailableConnectionsIndex(services), summaryAllowed=False),
|
|
PromptPlaceholder(label="USER_PROMPT", content=extractUserPrompt(context), summaryAllowed=False),
|
|
PromptPlaceholder(label="USER_LANGUAGE", content=extractUserLanguage(services), summaryAllowed=False),
|
|
PromptPlaceholder(label="PREVIOUS_ACTION_RESULTS", content=extractPreviousActionResults(context), summaryAllowed=True),
|
|
PromptPlaceholder(label="LEARNINGS_AND_IMPROVEMENTS", content=extractLearningsAndImprovements(context), summaryAllowed=True),
|
|
PromptPlaceholder(label="LATEST_REFINEMENT_FEEDBACK", content=extractLatestRefinementFeedback(context), summaryAllowed=True),
|
|
PromptPlaceholder(label="WORKFLOW_HISTORY", content=extractWorkflowHistory(services, context), summaryAllowed=True),
|
|
PromptPlaceholder(label="SELECTED_ACTION", content=compoundActionName, summaryAllowed=False),
|
|
]
|
|
|
|
template = """Generate parameters for this action.
|
|
|
|
## Return ONLY a JSON RESPONSEOBJECT without comments.
|
|
|
|
ACTION_OBJECTIVE (the objective for this action to fulfill):
|
|
{{KEY:ACTION_OBJECTIVE}}
|
|
|
|
SELECTED_ACTION:
|
|
{{KEY:SELECTED_ACTION}}
|
|
|
|
JSON RESPONSEOBJECT:
|
|
{{
|
|
"schema": "parameters_v1",
|
|
"parameters": {{
|
|
"paramName": "value"
|
|
}}
|
|
}}
|
|
|
|
EXAMPLE of the result format to deliver:
|
|
{{
|
|
"schema": "parameters_v1",
|
|
"parameters": {{
|
|
"aiPrompt": "...",
|
|
"resultType": "docx",
|
|
"processingMode": "detailed"
|
|
}}
|
|
}}
|
|
|
|
## RULES:
|
|
1. Use ONLY parameter names from ACTION_PARAMETER_LIST
|
|
2. For connectionReference, use an EXACT label from AVAILABLE_CONNECTIONS_INDEX (do NOT invent labels)
|
|
3. Use exact document references from AVAILABLE_DOCUMENTS_INDEX for documentList parameters (do NOT invent names like "doc1"): pick specific docItem references; to include all from a list, use its docList reference
|
|
4. Learn from PREVIOUS_ACTION_RESULTS and LEARNINGS_AND_IMPROVEMENTS to avoid repeating mistakes
|
|
5. Consider LATEST_REFINEMENT_FEEDBACK when generating parameters
|
|
6. Use the ACTION_OBJECTIVE to understand the specific goal for this action
|
|
7. Generate parameters that align with the USER_LANGUAGE when applicable
|
|
|
|
## ACTION_PARAMETER_LIST:
|
|
|
|
{{KEY:ACTION_PARAMETER_LIST}}
|
|
|
|
|
|
## AVAILABLE_DOCUMENTS_INDEX:
|
|
|
|
(Use these references in parameter "documentList" if given; to include all docs from a list, pass its docList reference)
|
|
{{KEY:AVAILABLE_DOCUMENTS_INDEX}}
|
|
|
|
|
|
## AVAILABLE_CONNECTIONS_INDEX:
|
|
|
|
{{KEY:AVAILABLE_CONNECTIONS_INDEX}}
|
|
(Use an EXACT label here for parameter "connectionReference")
|
|
|
|
|
|
## Example how to assign references from AVAILABLE_DOCUMENTS_INDEX and AVAILABLE_CONNECTIONS_INDEX:
|
|
|
|
{{
|
|
"schema": "parameters_v1",
|
|
"parameters": {{
|
|
"documentList": ["docList:msg_47a7a578-e8f2-4ba8-ac66-0dbff40605e0:round8_task1_action1_results", "docItem:5d8b7aee-b546-4487-b6a8-835c86f7b186:AI_Generated_Document_20251006-104256.docx"],
|
|
"connectionReference": "conn_msft_1ae8b8e5-128b-49b8-b1cb-7c632669eeae",
|
|
"aiPrompt": "...",
|
|
"resultType": "xlsx",
|
|
"processingMode": "basic"
|
|
}}
|
|
}}
|
|
|
|
## CONTEXT
|
|
|
|
USER_REQUEST (final user prompt to deliver):
|
|
{{KEY:USER_PROMPT}}
|
|
|
|
USER_LANGUAGE:
|
|
{{KEY:USER_LANGUAGE}}
|
|
|
|
PREVIOUS_ACTION_RESULTS:
|
|
{{KEY:PREVIOUS_ACTION_RESULTS}}
|
|
|
|
LEARNINGS_AND_IMPROVEMENTS:
|
|
{{KEY:LEARNINGS_AND_IMPROVEMENTS}}
|
|
|
|
LATEST_REFINEMENT_FEEDBACK:
|
|
{{KEY:LATEST_REFINEMENT_FEEDBACK}}
|
|
|
|
WORKFLOW_HISTORY:
|
|
{{KEY:WORKFLOW_HISTORY}}
|
|
"""
|
|
|
|
return PromptBundle(prompt=template, placeholders=placeholders)
|
|
|
|
def generateReactRefinementPrompt(services, context: Any, reviewContent: str) -> PromptBundle:
|
|
"""Define placeholders first, then the template; return PromptBundle."""
|
|
placeholders: List[PromptPlaceholder] = [
|
|
PromptPlaceholder(label="USER_PROMPT", content=extractUserPrompt(context), summaryAllowed=False),
|
|
PromptPlaceholder(label="REVIEW_CONTENT", content=reviewContent, summaryAllowed=True),
|
|
]
|
|
|
|
template = """Decide the next step based on the observation.
|
|
|
|
OBJECTIVE:
|
|
{{KEY:USER_PROMPT}}
|
|
|
|
OBSERVATION:
|
|
{{KEY:REVIEW_CONTENT}}
|
|
|
|
REPLY: Return only a JSON object with your decision:
|
|
{{
|
|
"decision": "continue|stop",
|
|
"reason": "brief explanation"
|
|
}}
|
|
|
|
RULES:
|
|
1. Use "continue" if objective NOT fulfilled
|
|
2. Use "stop" if objective fulfilled
|
|
3. Return ONLY JSON - no other text
|
|
4. Do NOT use markdown code blocks
|
|
5. Do NOT add explanations
|
|
"""
|
|
|
|
return PromptBundle(prompt=template, placeholders=placeholders)
|