Skip to content

feat(core): add verified actions primitives - #967

Open
lrahmani wants to merge 6 commits into
mainfrom
feat/add-verified-actions-primitives
Open

lrahmani wants to merge 6 commits into
mainfrom
feat/add-verified-actions-primitives

Conversation

@lrahmani

@lrahmani lrahmani commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

What

Type contract for Verified Actions — the metadata that Agentverse attaches to ChatMessage to prove which tool calls an agent made while processing a user request.

Why

Multiple components need to agree on the same data shape:

  • Fayer (host) captures tool calls, validates them, and injects the metadata into outgoing ChatMessage
  • Chat UI reads the metadata to render verification badges
  • AEVS backend receives receipts keyed by reference_id and session_id

Defining the types in uagents-core makes it the single source of truth, same as cards.

What is in the module

Four action types — one per category of side effect, using inheritance from a shared base (_ToolActionBase):

Type type discriminator Specific fields
WebAction "web" url, method, status_code
LlmAction "llm" api_url, model, input_tokens, output_tokens
McpAction "mcp" server_url, tool_name
IntegrationAction "integration" integration, tool_name

ToolAction — discriminated union of the four, routed by type.

VerifiedActions — aggregate: session_id (AEVS hash-chain anchor) + ordered list of ToolAction.

Two helpers:

  • create_verified_actions_content(data) → MetadataContent — serializes for ChatMessage
  • extract_verified_actions(content) → VerifiedActions | None — deserializes, returns None if not a match or validation fails

validate_tool_action(raw_dict) → ToolAction | None — validates a single raw dict (e.g. from the VM queue) without raising.

Design decisions

  • extra="ignore" on all models for forward compatibility — old code can parse payloads from newer versions (unknown fields silently dropped)
  • Version presence check, not equality — extraction attempts parsing regardless of version; consumers compare VERIFIED_ACTIONS_VERSION against the metadata value to detect outdated agents
  • Inheritance over composition — flat wire format (action.url not action.data.url), cleaner construction, Pydantic discriminated union handles dispatch
  • IntegrationAction naming follows team agreement: integration = external service (Slack, Google Calendar), tool_name = specific callable

How it will be used

from uagents_core.contrib.protocols.chat.verified_actions import (
    WebAction, VerifiedActions, create_verified_actions_content,
)

# Fayer host builds and injects into ChatMessage
verified = VerifiedActions(
    session_id=execution_id,
    actions=[
        WebAction(
            reference_id="...",
            url="https://api.example.com/data",
            method="GET",
            status_code=200,
            status="success",
            duration_ms=120,
        ),
    ],
)
content = create_verified_actions_content(verified)

@jrriehl jrriehl left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants