Chat round (explain on selection, page starters, reactions, streamed notes, thinking), negatives on node fixed values and combines, Pack builder quality fixes from 31 real-model eval rounds, and small-model support (scoped tools, checked tool arguments on local servers, two-phase steps, fixed prefix shown in Test connection).
90 lines
2.9 KiB
Python
90 lines
2.9 KiB
Python
"""Surface gating for $var token.
|
|
|
|
Combine, derivation, and assembler surfaces support $var reads.
|
|
Wildcard and fixed_values surfaces are binding PRODUCERS, not consumers
|
|
— $var reads in those surfaces warn + render literal in lenient mode,
|
|
raise VarOutOfSurfaceError in strict mode.
|
|
"""
|
|
import random
|
|
|
|
import pytest
|
|
|
|
from engine.syntax import resolve_text
|
|
from engine.syntax.types import VarOutOfSurfaceError
|
|
|
|
|
|
class _FakeCtx:
|
|
"""Minimal ResolveContext-shaped object for surface gating tests."""
|
|
|
|
def __init__(self, surface, strict=False, vars_=None):
|
|
self.surface = surface
|
|
self.strict = strict
|
|
self.developer_mode = False
|
|
self.max_ref_depth = 8
|
|
self.warnings = []
|
|
self._vars = vars_ or {}
|
|
self.rng = random.Random(0)
|
|
|
|
def get_var(self, name):
|
|
return self._vars.get(name)
|
|
|
|
def get_module(self, uuid):
|
|
return None
|
|
|
|
|
|
def test_var_resolves_on_combine_surface():
|
|
ctx = _FakeCtx("combine", vars_={"name": "world"})
|
|
assert resolve_text("hello $name", ctx) == "hello world"
|
|
|
|
|
|
def test_var_resolves_on_derivation_surface():
|
|
ctx = _FakeCtx("derivation", vars_={"name": "world"})
|
|
assert resolve_text("hello $name", ctx) == "hello world"
|
|
|
|
|
|
def test_var_resolves_on_assembler_surface():
|
|
ctx = _FakeCtx("assembler", vars_={"name": "world"})
|
|
assert resolve_text("hello $name", ctx) == "hello world"
|
|
|
|
|
|
def test_var_warns_on_wildcard_surface_lenient():
|
|
"""Wildcard surface: lenient strategy renders $name literal +
|
|
pushes a var_out_of_surface warning."""
|
|
ctx = _FakeCtx("wildcard", strict=False, vars_={"name": "world"})
|
|
result = resolve_text("hello $name", ctx)
|
|
assert result == "hello $name"
|
|
assert any(w.get("type") == "var_out_of_surface" for w in ctx.warnings)
|
|
|
|
|
|
def test_var_warns_on_fixed_values_surface_lenient():
|
|
ctx = _FakeCtx("fixed_values", strict=False, vars_={"name": "world"})
|
|
result = resolve_text("hello $name", ctx)
|
|
assert result == "hello $name"
|
|
assert any(w.get("type") == "var_out_of_surface" for w in ctx.warnings)
|
|
|
|
|
|
def test_var_raises_on_wildcard_surface_strict():
|
|
ctx = _FakeCtx("wildcard", strict=True)
|
|
with pytest.raises(VarOutOfSurfaceError):
|
|
resolve_text("hello $name", ctx)
|
|
|
|
|
|
def test_var_raises_on_fixed_values_surface_strict():
|
|
ctx = _FakeCtx("fixed_values", strict=True)
|
|
with pytest.raises(VarOutOfSurfaceError):
|
|
resolve_text("hello $name", ctx)
|
|
|
|
|
|
def test_internal_dunder_var_never_warns():
|
|
"""__-prefixed vars are engine bookkeeping; never warn even on
|
|
surfaces that disallow VAR."""
|
|
ctx = _FakeCtx("wildcard", strict=False)
|
|
result = resolve_text("$__wp_internal__", ctx)
|
|
assert result == ""
|
|
assert not any(w.get("type") == "var_out_of_surface" for w in ctx.warnings)
|
|
|
|
|
|
def test_out_of_surface_var_keeps_its_accessor():
|
|
ctx = _FakeCtx("wildcard", vars_={"c": "red"})
|
|
assert resolve_text("$c.0 and $c.neg", ctx) == "$c.0 and $c.neg"
|