@o-lang/olang 1.2.31 → 1.2.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@o-lang/olang",
3
- "version": "1.2.31",
3
+ "version": "1.2.33",
4
4
  "author": "Olalekan Ogundipe <info@olang.cloud>",
5
5
  "description": "O-Lang: A governance language for user-directed, rule-enforced agent workflows",
6
6
  "main": "./src/runtime/index.js",
@@ -690,15 +690,38 @@ class RuntimeAPI {
690
690
  abs: a => Math.abs(a)
691
691
  };
692
692
 
693
- evaluateMath(expr) {
693
+ evaluateMath(expr) {
694
+ // ✅ Handle quoted string literals with interpolation: "{var}" → interpolated string
695
+ if (typeof expr === 'string') {
696
+ const trimmed = expr.trim();
697
+
698
+ // Check if it's a quoted string (single or double quotes)
699
+ if ((trimmed.startsWith('"') && trimmed.endsWith('"')) ||
700
+ (trimmed.startsWith("'") && trimmed.endsWith("'"))) {
701
+ // Extract the inner content
702
+ let inner = trimmed.slice(1, -1);
703
+
704
+ // Perform interpolation: replace {var} with context values
705
+ inner = inner.replace(/\{([^\}]+)\}/g, (_, path) => {
706
+ const value = this.getNested(this.context, path.trim());
707
+ return value !== undefined ? String(value) : `{${path}}`;
708
+ });
709
+
710
+ return inner;
711
+ }
712
+ }
713
+
714
+ // ── Original math evaluation logic (unchanged) ──────────────────────────
694
715
  expr = expr.replace(/\{([^\}]+)\}/g, (_, path) => {
695
716
  const value = this.getNested(this.context, path.trim());
696
717
  if (typeof value === 'string') return `"${value.replace(/"/g, '\\"')}"`;
697
718
  return value !== undefined ? value : 0;
698
719
  });
720
+
699
721
  const funcNames = Object.keys(this.mathFunctions);
700
722
  const safeFunc = {};
701
723
  funcNames.forEach(fn => safeFunc[fn] = this.mathFunctions[fn]);
724
+
702
725
  try {
703
726
  const f = new Function(...funcNames, `return ${expr};`);
704
727
  return f(...funcNames.map(fn => safeFunc[fn]));
@@ -1235,9 +1258,14 @@ const forbiddenPatterns = [
1235
1258
  throw new Error(errorMessage);
1236
1259
  };
1237
1260
 
1238
- switch (stepType) {
1261
+ switch (stepType) {
1239
1262
  case 'calculate': {
1240
- const result = this.evaluateMath(step.expression || step.actionRaw);
1263
+ // Interpolate variables in the expression before evaluation
1264
+ let expr = step.expression || step.actionRaw;
1265
+ if (typeof expr === 'string' && expr.includes('{')) {
1266
+ expr = this._safeInterpolate(expr, this.context, 'calculate step');
1267
+ }
1268
+ const result = this.evaluateMath(expr);
1241
1269
  if (step.saveAs) this.context[step.saveAs] = result;
1242
1270
  break;
1243
1271
  }