Add friendly names system for recipes, effects, and media
- Add friendly_names table with unique constraints per actor - Create NamingService with HMAC-signed timestamp version IDs - Version IDs use base32-crockford encoding, always increase alphabetically - Name normalization: spaces/underscores to dashes, lowercase, strip special chars - Format: "my-effect 01hw3x9k" (space separator ensures uniqueness) - Integrate naming into recipe, effect, and media uploads - Resolve friendly names to CIDs during DAG execution - Update effects UI to display friendly names - Add 30 tests covering normalization, parsing, and service structure Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -158,13 +158,59 @@ def bind_inputs(
|
||||
return warnings
|
||||
|
||||
|
||||
def prepare_dag_for_execution(
|
||||
async def resolve_friendly_names_in_registry(
|
||||
registry: dict,
|
||||
actor_id: str,
|
||||
) -> dict:
|
||||
"""
|
||||
Resolve friendly names to CIDs in the registry.
|
||||
|
||||
Friendly names are identified by containing a space (e.g., "brightness 01hw3x9k")
|
||||
or by not being a valid CID format.
|
||||
"""
|
||||
from ..services.naming_service import get_naming_service
|
||||
import re
|
||||
|
||||
naming = get_naming_service()
|
||||
resolved = {"assets": {}, "effects": {}}
|
||||
|
||||
# CID patterns: IPFS CID (Qm..., bafy...) or SHA256 hash (64 hex chars)
|
||||
cid_pattern = re.compile(r'^(Qm[a-zA-Z0-9]{44}|bafy[a-zA-Z0-9]+|[a-f0-9]{64})$')
|
||||
|
||||
for asset_name, asset_info in registry.get("assets", {}).items():
|
||||
cid = asset_info.get("cid", "")
|
||||
if cid and not cid_pattern.match(cid):
|
||||
# Looks like a friendly name, resolve it
|
||||
resolved_cid = await naming.resolve(actor_id, cid, item_type="media")
|
||||
if resolved_cid:
|
||||
asset_info = dict(asset_info)
|
||||
asset_info["cid"] = resolved_cid
|
||||
asset_info["_resolved_from"] = cid
|
||||
resolved["assets"][asset_name] = asset_info
|
||||
|
||||
for effect_name, effect_info in registry.get("effects", {}).items():
|
||||
cid = effect_info.get("cid", "")
|
||||
if cid and not cid_pattern.match(cid):
|
||||
# Looks like a friendly name, resolve it
|
||||
resolved_cid = await naming.resolve(actor_id, cid, item_type="effect")
|
||||
if resolved_cid:
|
||||
effect_info = dict(effect_info)
|
||||
effect_info["cid"] = resolved_cid
|
||||
effect_info["_resolved_from"] = cid
|
||||
resolved["effects"][effect_name] = effect_info
|
||||
|
||||
return resolved
|
||||
|
||||
|
||||
async def prepare_dag_for_execution(
|
||||
recipe: Recipe,
|
||||
user_inputs: Dict[str, str],
|
||||
actor_id: str = None,
|
||||
) -> Tuple[str, List[str]]:
|
||||
"""
|
||||
Prepare a recipe DAG for execution by transforming nodes and binding inputs.
|
||||
|
||||
Resolves friendly names to CIDs if actor_id is provided.
|
||||
Returns (dag_json, warnings).
|
||||
"""
|
||||
recipe_dag = recipe.get("dag")
|
||||
@@ -177,6 +223,11 @@ def prepare_dag_for_execution(
|
||||
|
||||
# Get registry for resolving references
|
||||
registry = recipe.get("registry", {})
|
||||
|
||||
# Resolve friendly names to CIDs
|
||||
if actor_id and registry:
|
||||
registry = await resolve_friendly_names_in_registry(registry, actor_id)
|
||||
|
||||
assets = registry.get("assets", {}) if registry else {}
|
||||
effects = registry.get("effects", {}) if registry else {}
|
||||
|
||||
@@ -506,10 +557,10 @@ async def run_recipe(
|
||||
# Create run using run service
|
||||
run_service = RunService(database, get_redis_client(), get_cache_manager())
|
||||
|
||||
# Prepare DAG for execution (transform nodes, bind inputs)
|
||||
# Prepare DAG for execution (transform nodes, bind inputs, resolve friendly names)
|
||||
dag_json = None
|
||||
if recipe.get("dag"):
|
||||
dag_json, warnings = prepare_dag_for_execution(recipe, req.inputs)
|
||||
dag_json, warnings = await prepare_dag_for_execution(recipe, req.inputs, actor_id=ctx.actor_id)
|
||||
for warning in warnings:
|
||||
logger.warning(warning)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user