@o-lang/olang 1.1.1 → 1.1.3

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/runtime.js +17 -13
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@o-lang/olang",
3
- "version": "1.1.1",
3
+ "version": "1.1.3",
4
4
  "author": "Olalekan Ogundipe <info@workfily.com>",
5
5
  "description": "O-Lang: A governance language for user-directed, rule-enforced agent workflows",
6
6
  "main": "./src/index.js",
package/src/runtime.js CHANGED
@@ -343,9 +343,8 @@ class RuntimeAPI {
343
343
  }
344
344
  };
345
345
 
346
+ // ✅ CORRECTED: Strict safety WITH proper resolver chaining
346
347
  const runResolvers = async (action) => {
347
- const outputs = [];
348
-
349
348
  const mathPattern =
350
349
  /^(Add|Subtract|Multiply|Divide|Sum|Avg|Min|Max|Round|Floor|Ceil|Abs)\b/i;
351
350
 
@@ -371,13 +370,13 @@ class RuntimeAPI {
371
370
  resolversToRun = [agentResolver];
372
371
  }
373
372
 
374
- // ✅ Return the FIRST resolver that returns a non-undefined result
373
+ // ✅ CORRECTED SAFETY: Try ALL resolvers before halting
375
374
  for (let idx = 0; idx < resolversToRun.length; idx++) {
376
375
  const resolver = resolversToRun[idx];
377
- enforceResolverPolicy(resolver, step); // ✅ Use new policy enforcement
376
+ enforceResolverPolicy(resolver, step);
378
377
 
379
378
  try {
380
- let result; // ✅ ADDITION 4 — External Resolver Execution Path
379
+ let result;
381
380
 
382
381
  if (this._isExternalResolver(resolver)) {
383
382
  result = await this._callExternalResolver(
@@ -389,22 +388,27 @@ class RuntimeAPI {
389
388
  result = await resolver(action, this.context);
390
389
  }
391
390
 
392
- if (result !== undefined) {
391
+ // ✅ ACCEPT valid result immediately (non-null/non-undefined)
392
+ if (result !== undefined && result !== null) {
393
393
  this.context[`__resolver_${idx}`] = result;
394
394
  return result;
395
395
  }
396
+ // ❌ Resolver skipped this action (returned undefined/null) — continue to next resolver
397
+ // This is NORMAL resolver chaining behavior — NOT an error
396
398
 
397
- outputs.push(result);
398
- this.context[`__resolver_${idx}`] = result;
399
399
  } catch (e) {
400
- this.addWarning(`Resolver ${resolver?.resolverName || resolver?.name || idx} failed for action "${action}": ${e.message}`);
401
- outputs.push(null);
402
- this.context[`__resolver_${idx}`] = null;
400
+ // ❌ Resolver threw an error log warning but CONTINUE to next resolver
401
+ this.addWarning(`Resolver "${resolver?.resolverName || resolver?.name || idx}" threw error for action "${action}": ${e.message}`);
402
+ // Continue loop to try next resolver (don't halt yet)
403
403
  }
404
404
  }
405
405
 
406
- // If no resolver handled the action, return undefined
407
- return undefined;
406
+ // SAFETY GUARD: ALL resolvers skipped/failed HALT workflow
407
+ throw new Error(
408
+ `[O-Lang SAFETY] No resolver successfully handled action: "${action}". ` +
409
+ `Attempted resolvers: ${resolversToRun.map(r => r.resolverName || r.name || 'anonymous').join(', ')}. ` +
410
+ `Workflow execution halted to prevent unsafe data propagation.`
411
+ );
408
412
  };
409
413
 
410
414
  switch (stepType) {