variable-parser.js 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. /**
  2. * 统一解析结点入参:将 action 中的变量引用({var}、{{var}})用 variableContext 解析为实际值,
  3. * 再传给各 action 的 parse/execute,避免各结点脚本重复写解析逻辑。
  4. */
  5. const setParser = require('./actions/set-parser.js')
  6. const resolveValue = setParser.resolveValue
  7. const replaceVariablesInString = setParser.replaceVariablesInString
  8. /** 视为入参的字段(会被解析);outVars/variable 为输出,不在此解析。inVars 由各结点按需解析(因部分结点将 inVars 某项作为输出变量名)。 */
  9. const INPUT_KEYS = [
  10. 'value', 'target', 'template', 'area', 'savePath', 'condition', 'delay', 'interval',
  11. 'items', 'screenshot', 'region', 'method', 'clear', 'timeout', 'retry',
  12. 'min', 'max', 'avatar1', 'avatar2', 'friendAvatar', 'avatar', 'path', 'filePath',
  13. 'inputDataString', 'textVariable', 'senderVariable', 'appendMode',
  14. 'summaryPrompt', 'historyPrompt', 'model', 'prompt', 'systemPrompt',
  15. 'regionArea', 'saveDir', 'url', 'filename',
  16. ]
  17. /**
  18. * 解析单值:先对字符串做 {{var}} 替换,再对整体做 {var} 引用解析
  19. */
  20. function resolveInputValue(val, variableContext) {
  21. if (variableContext == null) return val
  22. if (typeof val === 'string') {
  23. const replaced = replaceVariablesInString(val, variableContext)
  24. return resolveValue(replaced, variableContext)
  25. }
  26. if (Array.isArray(val)) return val.map(item => resolveInputValue(item, variableContext))
  27. if (typeof val === 'object' && val !== null) {
  28. const out = {}
  29. for (const k in val) out[k] = resolveInputValue(val[k], variableContext)
  30. return out
  31. }
  32. return val
  33. }
  34. /**
  35. * 解析整条 action 的入参,返回新对象(不修改原 action)
  36. * @param {object} action - 原始或已 parse 的 action
  37. * @param {object} variableContext - 变量表
  38. * @returns {object} 入参解析后的 action 副本
  39. */
  40. function resolveActionInputs(action, variableContext) {
  41. if (!action || typeof action !== 'object') return action
  42. if (!variableContext || typeof variableContext !== 'object') return Object.assign({}, action)
  43. const resolved = Object.assign({}, action)
  44. for (const key of INPUT_KEYS) {
  45. if (key in resolved && resolved[key] !== undefined && resolved[key] !== null) {
  46. resolved[key] = resolveInputValue(resolved[key], variableContext)
  47. }
  48. }
  49. if (resolved.condition && typeof resolved.condition === 'object' && !Array.isArray(resolved.condition)) {
  50. const c = resolved.condition
  51. if (c.interval != null) resolved.condition = Object.assign({}, c, { interval: resolveInputValue(c.interval, variableContext) })
  52. if (c.repeat != null) resolved.condition = Object.assign({}, resolved.condition, { repeat: resolveInputValue(c.repeat, variableContext) })
  53. }
  54. return resolved
  55. }
  56. module.exports = {
  57. resolveActionInputs,
  58. resolveInputValue,
  59. }