Skip to content

Commit 934f437

Browse files
bokelleyclaude
andauthored
fix: handle all authorization types in get_properties_by_agent (#100)
Resolves #99 - get_properties_by_agent() now handles all AdCP v2 authorization types: - inline_properties: Properties defined directly on the agent - property_ids: Filter top-level properties by property_id - property_tags: Filter top-level properties by tags - publisher_properties: Cross-domain property selectors Also fixes AuthorizationContext to use "property_id" field per AdCP v2 schema instead of the incorrect "id" field. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 1975ca9 commit 934f437

File tree

2 files changed

+328
-35
lines changed

2 files changed

+328
-35
lines changed

src/adcp/adagents.py

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -478,12 +478,19 @@ def get_all_tags(adagents_data: dict[str, Any]) -> set[str]:
478478
def get_properties_by_agent(adagents_data: dict[str, Any], agent_url: str) -> list[dict[str, Any]]:
479479
"""Get all properties authorized for a specific agent.
480480
481+
Handles all authorization types per the AdCP specification:
482+
- inline_properties: Properties defined directly in the agent's properties array
483+
- property_ids: Filter top-level properties by property_id
484+
- property_tags: Filter top-level properties by tags
485+
- publisher_properties: References properties from other publisher domains
486+
(returns the selector objects, not resolved properties)
487+
481488
Args:
482489
adagents_data: Parsed adagents.json data
483490
agent_url: URL of the agent to filter by
484491
485492
Returns:
486-
List of properties for the specified agent (empty if agent not found or no properties)
493+
List of properties for the specified agent (empty if agent not found)
487494
488495
Raises:
489496
AdagentsValidationError: If adagents_data is malformed
@@ -495,6 +502,11 @@ def get_properties_by_agent(adagents_data: dict[str, Any], agent_url: str) -> li
495502
if not isinstance(authorized_agents, list):
496503
raise AdagentsValidationError("adagents.json must have 'authorized_agents' array")
497504

505+
# Get top-level properties for reference-based authorization types
506+
top_level_properties = adagents_data.get("properties", [])
507+
if not isinstance(top_level_properties, list):
508+
top_level_properties = []
509+
498510
# Normalize the agent URL for comparison
499511
normalized_agent_url = normalize_url(agent_url)
500512

@@ -510,12 +522,44 @@ def get_properties_by_agent(adagents_data: dict[str, Any], agent_url: str) -> li
510522
if normalize_url(agent_url_from_json) != normalized_agent_url:
511523
continue
512524

513-
# Found the agent - return their properties
514-
properties = agent.get("properties", [])
515-
if not isinstance(properties, list):
516-
return []
517-
518-
return [p for p in properties if isinstance(p, dict)]
525+
# Found the agent - determine authorization type
526+
authorization_type = agent.get("authorization_type", "")
527+
528+
# Handle inline_properties (properties array directly on agent)
529+
if authorization_type == "inline_properties" or "properties" in agent:
530+
properties = agent.get("properties", [])
531+
if not isinstance(properties, list):
532+
return []
533+
return [p for p in properties if isinstance(p, dict)]
534+
535+
# Handle property_ids (filter top-level properties by property_id)
536+
if authorization_type == "property_ids":
537+
authorized_ids = set(agent.get("property_ids", []))
538+
return [
539+
p
540+
for p in top_level_properties
541+
if isinstance(p, dict) and p.get("property_id") in authorized_ids
542+
]
543+
544+
# Handle property_tags (filter top-level properties by tags)
545+
if authorization_type == "property_tags":
546+
authorized_tags = set(agent.get("property_tags", []))
547+
return [
548+
p
549+
for p in top_level_properties
550+
if isinstance(p, dict) and set(p.get("tags", [])) & authorized_tags
551+
]
552+
553+
# Handle publisher_properties (cross-domain references)
554+
# Returns the selector objects; caller must resolve against other domains
555+
if authorization_type == "publisher_properties":
556+
publisher_props = agent.get("publisher_properties", [])
557+
if not isinstance(publisher_props, list):
558+
return []
559+
return [p for p in publisher_props if isinstance(p, dict)]
560+
561+
# No recognized authorization type - return empty
562+
return []
519563

520564
return []
521565

@@ -544,8 +588,8 @@ def __init__(self, properties: list[dict[str, Any]]):
544588
if not isinstance(prop, dict):
545589
continue
546590

547-
# Extract property ID
548-
prop_id = prop.get("id")
591+
# Extract property ID (per AdCP v2 schema, the field is "property_id")
592+
prop_id = prop.get("property_id")
549593
if prop_id and isinstance(prop_id, str):
550594
self.property_ids.append(prop_id)
551595

0 commit comments

Comments
 (0)