RELEASED v 4.0.
This commit is contained in:
parent
a98bc941d2
commit
160766be2a
2 changed files with 86 additions and 4 deletions
|
|
@ -1390,7 +1390,77 @@ class ChatObjects:
|
|||
result = template
|
||||
for placeholderName, value in placeholders.items():
|
||||
pattern = f"{{{{KEY:{placeholderName}}}}}"
|
||||
result = result.replace(pattern, str(value))
|
||||
|
||||
# Check if placeholder is in an array context like ["{{KEY:...}}"]
|
||||
# If value is a JSON array/dict, we should replace the entire ["{{KEY:...}}"] with the array
|
||||
arrayPattern = f'["{pattern}"]'
|
||||
if arrayPattern in result:
|
||||
# Check if value is a JSON array/dict
|
||||
isArrayValue = False
|
||||
arrayValue = None
|
||||
|
||||
if isinstance(value, (list, dict)):
|
||||
isArrayValue = True
|
||||
arrayValue = json.dumps(value)
|
||||
elif isinstance(value, str):
|
||||
try:
|
||||
parsed = json.loads(value)
|
||||
if isinstance(parsed, (list, dict)):
|
||||
isArrayValue = True
|
||||
arrayValue = value # Already valid JSON string
|
||||
except (json.JSONDecodeError, ValueError):
|
||||
pass
|
||||
|
||||
if isArrayValue:
|
||||
# Replace ["{{KEY:...}}"] with the array value
|
||||
result = result.replace(arrayPattern, arrayValue)
|
||||
continue # Skip the regular replacement below
|
||||
|
||||
# Regular replacement - check if in quoted context
|
||||
patternStart = result.find(pattern)
|
||||
isQuoted = False
|
||||
if patternStart > 0:
|
||||
charBefore = result[patternStart - 1] if patternStart > 0 else None
|
||||
patternEnd = patternStart + len(pattern)
|
||||
charAfter = result[patternEnd] if patternEnd < len(result) else None
|
||||
if charBefore == '"' and charAfter == '"':
|
||||
isQuoted = True
|
||||
|
||||
# Handle different value types
|
||||
if isinstance(value, (list, dict)):
|
||||
# Python list/dict - convert to JSON
|
||||
replacement = json.dumps(value)
|
||||
elif isinstance(value, str):
|
||||
# String value - check if it's a JSON string representing list/dict
|
||||
try:
|
||||
parsed = json.loads(value)
|
||||
if isinstance(parsed, (list, dict)):
|
||||
# It's a JSON string of a list/dict
|
||||
if isQuoted:
|
||||
# In quoted context, escape the JSON string
|
||||
escaped = json.dumps(value)
|
||||
replacement = escaped[1:-1] # Remove outer quotes
|
||||
else:
|
||||
# In unquoted context, use JSON directly
|
||||
replacement = value
|
||||
else:
|
||||
# It's a JSON string of a primitive
|
||||
if isQuoted:
|
||||
escaped = json.dumps(value)
|
||||
replacement = escaped[1:-1]
|
||||
else:
|
||||
replacement = value
|
||||
except (json.JSONDecodeError, ValueError):
|
||||
# Not valid JSON - treat as plain string
|
||||
if isQuoted:
|
||||
escaped = json.dumps(value)
|
||||
replacement = escaped[1:-1]
|
||||
else:
|
||||
replacement = value
|
||||
else:
|
||||
# Numbers, booleans, None - convert to string
|
||||
replacement = str(value)
|
||||
result = result.replace(pattern, replacement)
|
||||
return result
|
||||
|
||||
def _parseScheduleToCron(self, schedule: str) -> Dict[str, Any]:
|
||||
|
|
@ -1429,7 +1499,19 @@ class ChatObjects:
|
|||
template = automation.get("template", "")
|
||||
placeholders = automation.get("placeholders", {})
|
||||
planJson = self._replacePlaceholders(template, placeholders)
|
||||
plan = json.loads(planJson)
|
||||
try:
|
||||
plan = json.loads(planJson)
|
||||
except json.JSONDecodeError as e:
|
||||
logger.error(f"Failed to parse plan JSON after placeholder replacement: {str(e)}")
|
||||
logger.error(f"Template: {template[:500]}...")
|
||||
logger.error(f"Placeholders: {placeholders}")
|
||||
logger.error(f"Generated planJson (first 1000 chars): {planJson[:1000]}")
|
||||
logger.error(f"Error position: line {e.lineno}, column {e.colno}, char {e.pos}")
|
||||
if e.pos:
|
||||
start = max(0, e.pos - 100)
|
||||
end = min(len(planJson), e.pos + 100)
|
||||
logger.error(f"Context around error: ...{planJson[start:end]}...")
|
||||
raise ValueError(f"Invalid JSON after placeholder replacement: {str(e)}")
|
||||
executionLog["messages"].append("Template placeholders replaced successfully")
|
||||
|
||||
# 3. Get user who created automation
|
||||
|
|
|
|||
|
|
@ -175,7 +175,7 @@ class MethodAi(MethodBase):
|
|||
|
||||
Parameters:
|
||||
- prompt (str, required): Natural language research instruction.
|
||||
- list(url) (list, optional): Specific URLs to crawl, if needed.
|
||||
- urlList (list, optional): Specific URLs to crawl, if needed.
|
||||
- country (str, optional): Two-digit country code (lowercase, e.g., ch, us, de).
|
||||
- language (str, optional): Language code (lowercase, e.g., de, en, fr).
|
||||
- researchDepth (str, optional): Research depth - fast, general, or deep. Default: general.
|
||||
|
|
@ -199,7 +199,7 @@ class MethodAi(MethodBase):
|
|||
# Call webcrawl service - service handles all AI intention analysis and processing
|
||||
result = await self.services.web.performWebResearch(
|
||||
prompt=prompt,
|
||||
urls=parameters.get("list(url)", []),
|
||||
urls=parameters.get("urlList", []),
|
||||
country=parameters.get("country"),
|
||||
language=parameters.get("language"),
|
||||
researchDepth=parameters.get("researchDepth", "general"),
|
||||
|
|
|
|||
Loading…
Reference in a new issue