Extract row expression policy

This commit is contained in:
2026-06-27 08:56:35 +02:00
parent e5822e42f8
commit 3d9dbdc95d
5 changed files with 412 additions and 222 deletions
@@ -169,6 +169,10 @@ Already isolated:
runtime location/composition pool overrides, and generator fallback pool
selection live in `row_pools.py`; `prompt_builder.py` keeps public delegate
wrappers.
- row expression text cleanup, expression intensity weighting,
character-slot/cast expression override resolution, and per-character
expression picking live in `row_expression.py`; `prompt_builder.py` keeps
public delegate wrappers.
- hardcore position/action-filter choices, selected-position normalization,
config JSON builders/parsers, focus-policy toggles, subcategory allow-list
policy, position-key detection, category filtering, and item-template/axis
+6 -5
View File
@@ -82,6 +82,7 @@ Core helper ownership:
| `subject_context.py` | Row subject-context routing for single, couple, configured-cast, group, and layout subjects, combining appearance policy, cast metadata, and generator subject pools. |
| `location_config.py` | Location/composition preset schemas, themed location packs, custom location/composition parsing, pool merge behavior, and location/composition config parsing. |
| `row_location.py` | Built-in row location/composition config application, deterministic scene/composition choice, source metadata, and legacy prompt/caption rewrites. |
| `row_expression.py` | Row expression cleanup, expression intensity weighting, character-slot/cast expression override resolution, and per-character expression selection. |
| `row_pools.py` | Row scene/expression/pose/composition pool routing, category inheritance handling, runtime location/composition pool overrides, and generator fallback pools. |
| `hardcore_position_config.py` | Hardcore position/action-filter choices, selected-position normalization, config JSON builders/parsers, focus-policy toggles, subcategory allow-list policy, position-key detection, and category/template/axis filtering. |
| `pair_options.py` | Insta/OF option schema/defaults, softcore category/outfit/pose pools, partner outfit pools, clothing-continuity labels, negatives, hardcore cast count policy, and hardcore detail-density directives. |
@@ -299,8 +300,8 @@ Edit targets:
### Expression
Expression text is selected by `_expression_pool`, then filtered by
`_expression_entries_for_intensity`.
Expression text is selected by `_expression_pool`, then filtered through
`row_expression.expression_entries_for_intensity`.
Resolution order:
@@ -315,7 +316,7 @@ Edit targets:
- General expression pools: `categories/expression_composition_pools.json`.
- Hardcore-specific expressions: usually `categories/sexual_poses.json` or named
hardcore expression pools.
- Character-level expression settings: slot config and `_cast_expression_intensity_override`.
- Character-level expression settings: slot config and `row_expression.py`.
- Formatter expression wording: `krea_formatter.py` or `caption_naturalizer.py`.
### Pose / Action
@@ -842,8 +843,8 @@ pair metadata through the core Python APIs, then verifies:
| Wrong location | `categories/location_pools.json`, category `scene_pool`, `_scene_pool`. |
| Location good but camera/location layout wrong | `_camera_scene_directive_for_context`, coworking adapter functions. |
| Repeated desk/anchor in POV foreground | Coworking direction/distance/elevation helpers. |
| Wrong expression intensity | Character slot expression settings, `_expression_entries_for_intensity`, expression pools. |
| Expression appears when disabled | `_disable_row_expression`, formatter expression extraction. |
| Wrong expression intensity | Character slot expression settings, `row_expression.py`, expression pools. |
| Expression appears when disabled | `row_expression.disable_row_expression`, formatter expression extraction. |
| Same hardcore action repeats | Hardcore filter config, `sexual_poses.json` weights, `hardcore_position_config.apply_hardcore_position_config_to_subcategory`. |
| Hardcore interaction beat falls back to penetration/oral | `sexual_poses.json` interaction subcategory, `_role_graph`, and `krea_action_context.is_foreplay_text` / `krea_action_positions.hardcore_pose_anchor`. |
| Raw hardcore prompt position is vague | `sexual_poses.json` item templates and role graph templates. |
+23 -217
View File
@@ -41,6 +41,7 @@ try:
from . import pov_policy
from . import row_normalization as row_policy
from . import row_camera as row_camera_policy
from . import row_expression as row_expression_policy
from . import row_location as row_location_policy
from . import row_pools as row_pool_policy
from . import seed_config as seed_policy
@@ -85,6 +86,7 @@ except ImportError: # Allows local smoke tests with `python -c`.
import pov_policy
import row_normalization as row_policy
import row_camera as row_camera_policy
import row_expression as row_expression_policy
import row_location as row_location_policy
import row_pools as row_pool_policy
import seed_config as seed_policy
@@ -1135,44 +1137,15 @@ def _format(template: str, context: dict[str, Any]) -> str:
def _clean_prompt_punctuation(text: str) -> str:
text = re.sub(r"\s+", " ", str(text or "")).strip()
text = re.sub(r"\s+([,.;:])", r"\1", text)
text = re.sub(r"(?:,\s*){2,}", ", ", text)
text = re.sub(r"\.\s*\.", ".", text)
text = re.sub(r":\s*\.", ".", text)
return text.strip()
return row_expression_policy.clean_prompt_punctuation(text)
def _strip_expression_text(text: str, expression: Any = "") -> str:
text = str(text or "")
if not text:
return ""
text = re.sub(r"\s*Facial expressions?:\s*[^.]*\.\s*", " ", text, flags=re.IGNORECASE)
text = re.sub(r",\s*one with [^,]+ and the other with [^,]+(?=,)", "", text, flags=re.IGNORECASE)
text = re.sub(r",\s*a lively mix of expressions from [^,]+(?=,)", "", text, flags=re.IGNORECASE)
text = re.sub(r"\s+with\s+(?:an?|the)\s+[^,]*expression(?=,)", "", text, flags=re.IGNORECASE)
expression_text = str(expression or "").strip()
if expression_text:
for part in [piece.strip() for piece in expression_text.split(";") if piece.strip()]:
escaped = re.escape(part)
text = re.sub(rf",\s*{escaped}(?=,)", "", text, flags=re.IGNORECASE)
text = re.sub(rf"\s+with\s+(?:an?|the)?\s*{escaped}", "", text, flags=re.IGNORECASE)
return _clean_prompt_punctuation(text)
return row_expression_policy.strip_expression_text(text, expression)
def _disable_row_expression(row: dict[str, Any], source: str = "disabled") -> dict[str, Any]:
previous_expression = row.get("expression", "")
row["prompt"] = _strip_expression_text(row.get("prompt", ""), previous_expression)
row["caption"] = _strip_expression_text(row.get("caption", ""), previous_expression)
row["expression"] = ""
row["shared_expression"] = ""
row["character_expressions"] = []
row["character_expression_text"] = ""
row["expression_enabled"] = False
row["expression_disabled"] = True
row["expression_intensity"] = None
row["expression_intensity_source"] = source
return row
return row_expression_policy.disable_row_expression(row, source)
def _prepend_trigger(prompt: str, trigger: str, enabled: bool) -> str:
@@ -1837,10 +1810,6 @@ def _slot_effective_figure(
return character_slot_policy.slot_effective_figure(slot, subject_type, fallback_figure)
def _mean(values: list[float]) -> float:
return sum(values) / len(values)
def _cast_expression_intensity_override(
fallback: float,
label_map: dict[str, dict[str, Any]],
@@ -1848,35 +1817,13 @@ def _cast_expression_intensity_override(
men_count: int,
expression_phase: str = "",
) -> tuple[float | None, str]:
groups: list[tuple[str, list[str]]] = [
("women", [f"Woman {chr(ord('A') + index)}" for index in range(max(0, women_count))]),
("men", [f"Man {chr(ord('A') + index)}" for index in range(max(0, men_count))]),
]
all_values: list[float] = []
matching_slots: list[dict[str, Any]] = []
for group_name, labels in groups:
values: list[float] = []
value_labels: list[str] = []
for label in labels:
slot = label_map.get(label)
if _slot_is_pov(slot):
continue
if slot:
matching_slots.append(slot)
value = _slot_expression_intensity_for_phase(slot, expression_phase)
if value is not None:
values.append(value)
value_labels.append(label)
all_values.append(value)
if values:
if len(values) == 1:
return values[0], f"character_slot:{value_labels[0]}"
return _mean(values), f"character_slots:{group_name}"
if all_values:
return _mean(all_values), "character_slots:cast"
if matching_slots and all(not _slot_expression_enabled(slot) for slot in matching_slots):
return None, "character_slots:disabled"
return fallback, "input"
return row_expression_policy.cast_expression_intensity_override(
fallback,
label_map,
women_count,
men_count,
expression_phase,
)
def _character_expression_entries(
@@ -1888,41 +1835,15 @@ def _character_expression_entries(
men_count: int,
expression_phase: str = "",
) -> list[str]:
labels = [
*[f"Woman {chr(ord('A') + index)}" for index in range(max(0, women_count))],
*[f"Man {chr(ord('A') + index)}" for index in range(max(0, men_count))],
]
expressions: list[str] = []
used: set[str] = set()
for label in labels:
slot = label_map.get(label)
if not slot:
continue
if _slot_is_pov(slot):
continue
if not _slot_expression_enabled(slot):
continue
intensity = _slot_expression_intensity_for_phase(slot, expression_phase)
if intensity is None:
intensity = fallback_intensity
entries = _compatible_entries(
_expression_entries_for_intensity(expression_pool, intensity),
women_count,
men_count,
)
if not entries:
continue
choice = ""
for _attempt in range(5):
candidate = _choose_text(rng, entries)
if candidate not in used:
choice = candidate
break
if not choice:
choice = _choose_text(rng, entries)
used.add(choice)
expressions.append(f"{label} has {choice}")
return expressions
return row_expression_policy.character_expression_entries(
rng,
expression_pool,
fallback_intensity,
label_map,
women_count,
men_count,
expression_phase,
)
def _sanitize_character_expression_text_for_action(
@@ -2521,126 +2442,11 @@ def _expression_pool(category: dict[str, Any], subcategory: dict[str, Any], item
def _expression_intensity_hint(entry: Any) -> float:
if isinstance(entry, dict):
for key in ("expression_intensity", "intensity"):
if key in entry:
return _clamped_float(entry[key], 0.5)
text = _entry_text(entry).lower()
high_terms = (
"ahegao",
"orgasm",
"climax",
"drool",
"drooling",
"tongue out",
"eyes rolled",
"fucked-out",
"cum-smeared",
"saliva",
"gagging",
"slack jaw",
"jaw slack",
"slack-jawed",
"sex-drunk",
"overwhelmed",
"strained",
"messy",
"panting",
"trembling",
"shaking",
"wide open mouth",
"raw ",
"wild ",
"dazed",
"spent",
)
if any(term in text for term in high_terms):
return 0.9
medium_terms = (
"seductive",
"teasing",
"lustful",
"aroused",
"bedroom",
"dominant",
"predatory",
"control",
"stern",
"strict",
"smirk",
"parted lips",
"open-mouthed",
"heated",
"hungry",
"inviting",
"sensual",
"fetish",
"commanding",
"flushed",
"moan",
)
if any(term in text for term in medium_terms):
return 0.62
low_terms = (
"neutral",
"quiet",
"calm",
"reserved",
"relaxed",
"candid",
"closed-mouth",
"thoughtful",
"controlled",
"focused",
"steady",
"bitten-lip",
"braced",
"held breath",
"concentrated",
"aloof",
"bored",
"tired",
"unfocused",
"contented",
"fashion",
"soft",
"sleepy",
"fresh-faced",
)
if any(term in text for term in low_terms):
return 0.25
return 0.5
return row_expression_policy.expression_intensity_hint(entry)
def _expression_entries_for_intensity(entries: list[Any], expression_intensity: float) -> list[Any]:
target = _clamped_float(expression_intensity, 0.5)
weighted: list[Any] = []
for entry in entries:
entry_intensity = _expression_intensity_hint(entry)
distance = abs(target - entry_intensity)
if distance <= 0.18:
intensity_weight = 4.0
elif distance <= 0.35:
intensity_weight = 1.4
elif distance <= 0.55:
intensity_weight = 0.35
else:
intensity_weight = 0.05
if isinstance(entry, dict):
adjusted = dict(entry)
try:
base_weight = float(adjusted.get("weight", 1.0))
except (TypeError, ValueError):
base_weight = 1.0
adjusted["weight"] = max(0.0, base_weight) * intensity_weight
weighted.append(adjusted)
else:
weighted.append({"text": _entry_text(entry), "weight": intensity_weight})
return weighted or entries
return row_expression_policy.expression_entries_for_intensity(entries, expression_intensity)
def _pose_pool(category: dict[str, Any], subcategory: dict[str, Any], item: Any, subject_type: str, poses: str) -> list[Any]:
+304
View File
@@ -0,0 +1,304 @@
from __future__ import annotations
import random
import re
from typing import Any
try:
from . import category_library as category_policy
from . import character_slot as character_slot_policy
from . import pov_policy
except ImportError: # Allows local smoke tests with top-level imports.
import category_library as category_policy
import character_slot as character_slot_policy
import pov_policy
def clean_prompt_punctuation(text: str) -> str:
text = re.sub(r"\s+", " ", str(text or "")).strip()
text = re.sub(r"\s+([,.;:])", r"\1", text)
text = re.sub(r"(?:,\s*){2,}", ", ", text)
text = re.sub(r"\.\s*\.", ".", text)
text = re.sub(r":\s*\.", ".", text)
return text.strip()
def strip_expression_text(text: str, expression: Any = "") -> str:
text = str(text or "")
if not text:
return ""
text = re.sub(r"\s*Facial expressions?:\s*[^.]*\.\s*", " ", text, flags=re.IGNORECASE)
text = re.sub(r",\s*one with [^,]+ and the other with [^,]+(?=,)", "", text, flags=re.IGNORECASE)
text = re.sub(r",\s*a lively mix of expressions from [^,]+(?=,)", "", text, flags=re.IGNORECASE)
text = re.sub(r"\s+with\s+(?:an?|the)\s+[^,]*expression(?=,)", "", text, flags=re.IGNORECASE)
expression_text = str(expression or "").strip()
if expression_text:
for part in [piece.strip() for piece in expression_text.split(";") if piece.strip()]:
escaped = re.escape(part)
text = re.sub(rf",\s*{escaped}(?=,)", "", text, flags=re.IGNORECASE)
text = re.sub(rf"\s+with\s+(?:an?|the)?\s*{escaped}", "", text, flags=re.IGNORECASE)
return clean_prompt_punctuation(text)
def disable_row_expression(row: dict[str, Any], source: str = "disabled") -> dict[str, Any]:
previous_expression = row.get("expression", "")
row["prompt"] = strip_expression_text(row.get("prompt", ""), previous_expression)
row["caption"] = strip_expression_text(row.get("caption", ""), previous_expression)
row["expression"] = ""
row["shared_expression"] = ""
row["character_expressions"] = []
row["character_expression_text"] = ""
row["expression_enabled"] = False
row["expression_disabled"] = True
row["expression_intensity"] = None
row["expression_intensity_source"] = source
return row
def _clamped_float(value: Any, default: float = 0.5, min_value: float = 0.0, max_value: float = 1.0) -> float:
try:
number = float(value)
except (TypeError, ValueError):
return default
return max(min_value, min(max_value, number))
def _entry_text(entry: Any) -> str:
return category_policy._entry_text(entry)
def expression_intensity_hint(entry: Any) -> float:
if isinstance(entry, dict):
for key in ("expression_intensity", "intensity"):
if key in entry:
return _clamped_float(entry[key], 0.5)
text = _entry_text(entry).lower()
high_terms = (
"ahegao",
"orgasm",
"climax",
"drool",
"drooling",
"tongue out",
"eyes rolled",
"fucked-out",
"cum-smeared",
"saliva",
"gagging",
"slack jaw",
"jaw slack",
"slack-jawed",
"sex-drunk",
"overwhelmed",
"strained",
"messy",
"panting",
"trembling",
"shaking",
"wide open mouth",
"raw ",
"wild ",
"dazed",
"spent",
)
if any(term in text for term in high_terms):
return 0.9
medium_terms = (
"seductive",
"teasing",
"lustful",
"aroused",
"bedroom",
"dominant",
"predatory",
"control",
"stern",
"strict",
"smirk",
"parted lips",
"open-mouthed",
"heated",
"hungry",
"inviting",
"sensual",
"fetish",
"commanding",
"flushed",
"moan",
)
if any(term in text for term in medium_terms):
return 0.62
low_terms = (
"neutral",
"quiet",
"calm",
"reserved",
"relaxed",
"candid",
"closed-mouth",
"thoughtful",
"controlled",
"focused",
"steady",
"bitten-lip",
"braced",
"held breath",
"concentrated",
"aloof",
"bored",
"tired",
"unfocused",
"contented",
"fashion",
"soft",
"sleepy",
"fresh-faced",
)
if any(term in text for term in low_terms):
return 0.25
return 0.5
def expression_entries_for_intensity(entries: list[Any], expression_intensity: float) -> list[Any]:
target = _clamped_float(expression_intensity, 0.5)
weighted: list[Any] = []
for entry in entries:
entry_intensity = expression_intensity_hint(entry)
distance = abs(target - entry_intensity)
if distance <= 0.18:
intensity_weight = 4.0
elif distance <= 0.35:
intensity_weight = 1.4
elif distance <= 0.55:
intensity_weight = 0.35
else:
intensity_weight = 0.05
if isinstance(entry, dict):
adjusted = dict(entry)
try:
base_weight = float(adjusted.get("weight", 1.0))
except (TypeError, ValueError):
base_weight = 1.0
adjusted["weight"] = max(0.0, base_weight) * intensity_weight
weighted.append(adjusted)
else:
weighted.append({"text": _entry_text(entry), "weight": intensity_weight})
return weighted or entries
def _mean(values: list[float]) -> float:
return sum(values) / len(values)
def cast_expression_intensity_override(
fallback: float,
label_map: dict[str, dict[str, Any]],
women_count: int,
men_count: int,
expression_phase: str = "",
) -> tuple[float | None, str]:
groups: list[tuple[str, list[str]]] = [
("women", [f"Woman {chr(ord('A') + index)}" for index in range(max(0, women_count))]),
("men", [f"Man {chr(ord('A') + index)}" for index in range(max(0, men_count))]),
]
all_values: list[float] = []
matching_slots: list[dict[str, Any]] = []
for group_name, labels in groups:
values: list[float] = []
value_labels: list[str] = []
for label in labels:
slot = label_map.get(label)
if pov_policy.slot_is_pov(slot):
continue
if slot:
matching_slots.append(slot)
value = character_slot_policy.slot_expression_intensity_for_phase(slot, expression_phase)
if value is not None:
values.append(value)
value_labels.append(label)
all_values.append(value)
if values:
if len(values) == 1:
return values[0], f"character_slot:{value_labels[0]}"
return _mean(values), f"character_slots:{group_name}"
if all_values:
return _mean(all_values), "character_slots:cast"
if matching_slots and all(not character_slot_policy.slot_expression_enabled(slot) for slot in matching_slots):
return None, "character_slots:disabled"
return fallback, "input"
def _weighted_choice(rng: random.Random, items: list[Any]) -> Any:
if not items:
raise ValueError("Cannot choose from an empty list")
weights: list[float] = []
for item in items:
weight = item.get("weight", 1.0) if isinstance(item, dict) else 1.0
try:
weights.append(max(0.0, float(weight)))
except (TypeError, ValueError):
weights.append(1.0)
total = sum(weights)
if total <= 0:
return items[rng.randrange(len(items))]
pick = rng.random() * total
running = 0.0
for item, weight in zip(items, weights):
running += weight
if pick <= running:
return item
return items[-1]
def _choose_text(rng: random.Random, items: list[Any]) -> str:
return _entry_text(_weighted_choice(rng, items))
def character_expression_entries(
rng: random.Random,
expression_pool: list[Any],
fallback_intensity: float,
label_map: dict[str, dict[str, Any]],
women_count: int,
men_count: int,
expression_phase: str = "",
) -> list[str]:
labels = [
*[f"Woman {chr(ord('A') + index)}" for index in range(max(0, women_count))],
*[f"Man {chr(ord('A') + index)}" for index in range(max(0, men_count))],
]
expressions: list[str] = []
used: set[str] = set()
for label in labels:
slot = label_map.get(label)
if not slot:
continue
if pov_policy.slot_is_pov(slot):
continue
if not character_slot_policy.slot_expression_enabled(slot):
continue
intensity = character_slot_policy.slot_expression_intensity_for_phase(slot, expression_phase)
if intensity is None:
intensity = fallback_intensity
entries = category_policy.compatible_entries(
expression_entries_for_intensity(expression_pool, intensity),
women_count,
men_count,
)
if not entries:
continue
choice = ""
for _attempt in range(5):
candidate = _choose_text(rng, entries)
if candidate not in used:
choice = candidate
break
if not choice:
choice = _choose_text(rng, entries)
used.add(choice)
expressions.append(f"{label} has {choice}")
return expressions
+75
View File
@@ -51,6 +51,7 @@ import pov_policy # noqa: E402
import row_normalization # noqa: E402
import route_metadata # noqa: E402
import row_camera # noqa: E402
import row_expression # noqa: E402
import row_location # noqa: E402
import row_pools # noqa: E402
import server_routes # noqa: E402
@@ -658,6 +659,79 @@ def smoke_row_location_policy() -> None:
_expect(", long archive aisle composition," in updated.get("caption", ""), "Row location policy did not rewrite caption composition")
def smoke_row_expression_policy() -> None:
entries = [
{"text": "quiet calm focus", "weight": 2.0},
{"text": "heated smirk", "weight": 3.0},
{"text": "dazed overwhelmed look", "weight": 1.0},
]
_expect(
pb._expression_entries_for_intensity(entries, 0.25) == row_expression.expression_entries_for_intensity(entries, 0.25),
"Prompt builder expression intensity wrapper should delegate to row_expression",
)
weighted = row_expression.expression_entries_for_intensity(entries, 0.25)
_expect(weighted[0]["weight"] == 8.0, "Row expression low-intensity weighting changed")
_expect(weighted[2]["weight"] == 0.05, "Row expression distant-intensity weighting changed")
row = {
"prompt": "Person with quiet focus, in room. Facial expression: quiet focus. Keep this.",
"caption": "sxcppnl7, person with quiet focus, in room",
"expression": "quiet focus",
"shared_expression": "quiet focus",
"character_expressions": ["Woman A has quiet focus"],
"character_expression_text": "Woman A has quiet focus",
}
_expect(
pb._disable_row_expression(dict(row), "test") == row_expression.disable_row_expression(dict(row), "test"),
"Prompt builder expression disable wrapper should delegate to row_expression",
)
disabled = row_expression.disable_row_expression(dict(row), "test")
_expect(disabled.get("expression_disabled") is True, "Row expression disable did not set disabled metadata")
_expect("quiet focus" not in disabled.get("prompt", ""), "Row expression disable did not strip prompt expression text")
woman_slot = character_slot.normalize_character_slot(
{
"subject_type": "woman",
"label": "A",
"expression_intensity": 0.8,
"softcore_expression_intensity": 0.2,
}
)
pov_man_slot = character_slot.normalize_character_slot(
{
"subject_type": "man",
"label": "A",
"presence_mode": "pov",
"expression_intensity": 1.0,
}
)
label_map = {"Woman A": woman_slot, "Man A": pov_man_slot}
_expect(
pb._cast_expression_intensity_override(0.5, label_map, 1, 1, "softcore")
== row_expression.cast_expression_intensity_override(0.5, label_map, 1, 1, "softcore"),
"Prompt builder cast expression override wrapper should delegate to row_expression",
)
_expect(
row_expression.cast_expression_intensity_override(0.5, label_map, 1, 1, "softcore")
== (0.2, "character_slot:Woman A"),
"Row expression cast override did not prefer visible slot phase intensity",
)
_expect(
pb._character_expression_entries(random.Random(22), entries, 0.5, label_map, 1, 1, "softcore")
== row_expression.character_expression_entries(random.Random(22), entries, 0.5, label_map, 1, 1, "softcore"),
"Prompt builder character expression wrapper should delegate to row_expression",
)
disabled_slot = character_slot.normalize_character_slot(
{"subject_type": "woman", "label": "A", "expression_enabled": False}
)
_expect(
row_expression.cast_expression_intensity_override(0.5, {"Woman A": disabled_slot}, 1, 0, "hardcore")
== (None, "character_slots:disabled"),
"Row expression cast override did not honor all-slot expression disable",
)
def smoke_category_cast_config_policy() -> None:
_expect(pb.CATEGORY_PRESETS is category_cast_config.CATEGORY_PRESETS, "Prompt builder category presets are not delegated")
_expect(pb.CAST_PRESETS is category_cast_config.CAST_PRESETS, "Prompt builder cast presets are not delegated")
@@ -3856,6 +3930,7 @@ SMOKE_CASES: list[tuple[str, Callable[[], None]]] = [
("config_route_location_theme", smoke_config_route_location_theme),
("location_config_policy", smoke_location_config_policy),
("row_location_policy", smoke_row_location_policy),
("row_expression_policy", smoke_row_expression_policy),
("category_cast_config_policy", smoke_category_cast_config_policy),
("generation_profile_config_policy", smoke_generation_profile_config_policy),
("filter_config_policy", smoke_filter_config_policy),