orchestrata_ultimate.agents.volks.ux.volk
Reference › orchestrata_ultimate › agents › volks › ux › volk
UXVolk (alias U:Ux, role UX Designer) produces UI design artifacts when a project has a user interface (specification 013). It extends BaseAgent (base) and is imported by the kernel pipeline; UserExperienceAgent is an alias subclass.
What it receives: a ux_design packet from the Project Manager (volk) with the requirements, task summary, project name, scope data and a has_ui flag. What it produces: a packet for the Architect (U:Ar).
process routes to _handle_ux_design, which reads has_ui. Without a UI, _passthrough forwards the request directly to the Architect unchanged in substance, with subject implement. With a UI, _design_ui calls the LLM to produce the design artifacts (workflows, component hierarchy, wireframes, design tokens and accessibility notes) and _build_design_packet sends the result to U:Ar with subject ux_complete, in a ux_design payload field next to the original requirements. The Architect accepts both subjects.
At a glance
| Source | src/orchestrata_ultimate/agents/volks/ux/volk.py |
| Lines of code | 239 |
| Classes | 2 |
| Functions | 0 |
| Imports (internal) | orchestrata_ultimate.agents.volks.base, orchestrata_ultimate.core.base.traces, orchestrata_ultimate.core.graph_directives, orchestrata_ultimate.core.packet |
| Imported by | orchestrata_ultimate.kernel.pipeline |
| Tests that import it | tests/agents/test_ux_volk.py, tests/agents/volks/ux/test_ux_handoff.py, tests/agents/volks/ux/test_volk.py, tests/generated_agents/test_volks_ux_volk_generated.py, tests/generated_recovery/test_agents_volks_ux_volk.py |
Class diagram
Dependency diagram
API
Classes
UXVolk (pydantic)
Bases: BaseAgent · Decorators: traces(spec='013', story='US-001', reqs=['REQ-013-001', 'REQ-013-002']) · Line 79
UX Designer volk — produces UI design artifacts.
| Attribute | Type | Default |
|---|---|---|
alias |
str |
Field(default='U:Ux') |
role |
str |
'UX Designer' |
| Method | Signature | Summary |
|---|---|---|
__init__ |
__init__(****kwargs) |
|
process |
async process(packet: CXPPacket) -> CXPPacket | None |
Route packet to appropriate handler. |
_handle_ux_design |
async _handle_ux_design(packet: CXPPacket) -> CXPPacket |
Produce UI design or passthrough if not needed. |
_passthrough |
_passthrough(packet: CXPPacket) -> CXPPacket |
No UI needed — forward directly to Architect. |
_design_ui |
async _design_ui(packet: CXPPacket) -> CXPPacket |
Call LLM to produce UI design artifacts. |
_build_design_packet |
_build_design_packet(packet: CXPPacket, requirements: str) -> CXPPacket |
Build CXP packet forwarding UX design to Architect. |
UserExperienceAgent (pydantic)
Bases: UXVolk · Line 236
Agent alias for UXVolk.
Source
# mypy: ignore-errors
"""U:Ux — UX Designer volk for UI design artifacts."""
from pydantic import Field
from orchestrata_ultimate.agents.volks.base import BaseAgent
from orchestrata_ultimate.core.base.traces import traces
from orchestrata_ultimate.core.graph_directives import extract_graph_context
from orchestrata_ultimate.core.packet import CXPPacket, WorkStatus
UX_SYSTEM_PROMPT = """\
You are U:Ux, the UX Designer — a senior interaction designer specializing \
in producing actionable UI design artifacts for developer implementation.
YOUR MISSION: Given project requirements that include a UI, produce a \
complete design specification that a frontend developer can implement \
without guessing layout, components, interactions, or visual style.
DESIGN METHODOLOGY (based on user-centered design research):
1. MAP USER WORKFLOWS: For each user story, trace the screen flow \
(entry -> steps -> decision points -> exit). Identify data shown \
and collected at each step.
2. BUILD COMPONENT HIERARCHY: Decompose each screen into reusable \
components (page -> layout -> section -> widget). Identify shared \
components (buttons, forms, modals, tables).
3. DRAW WIREFRAMES: ASCII layout for each key screen showing header, \
nav, main content (with data source annotations), sidebar, footer. \
Note responsive breakpoints.
4. DEFINE DESIGN TOKENS: Colors (primary, secondary, accent, bg, text, \
error), typography (font, sizes h1-h6/body/caption), spacing scale \
(4/8/16/24/32px), border-radius, shadows.
5. SPECIFY ACCESSIBILITY: WCAG 2.1 AA, keyboard nav, ARIA labels, \
contrast ratios (4.5:1 minimum), focus indicators.
HANDOFF: The UX_DESIGN block below is handed to U:Ar (the Architect) \
and embedded into the Architect prompt, so keep every section label intact.
Output EXACTLY in this format:
UX_DESIGN:
WORKFLOWS:
- name: <workflow name>
screens: [<screen1>, <screen2>]
transitions: [{from: <screen>, to: <screen>, trigger: <action>}]
COMPONENTS:
- name: <ComponentName>
type: page | layout | widget
props: [{name: str, type: str, required: bool}]
children: [<child components>]
WIREFRAMES:
### <ScreenName>
(ASCII wireframe with data source annotations)
DESIGN_TOKENS:
- colors: {primary: "#...", secondary: "#...", accent: "#...", \
background: "#...", text: "#...", error: "#..."}
- typography: {font: "...", sizes: {h1: "...", body: "..."}}
- spacing: [4, 8, 16, 24, 32]
ACCESSIBILITY:
- WCAG level: AA
- keyboard_nav: required
- aria_labels: required
- contrast_ratio: 4.5:1 minimum
- focus_indicators: visible
"""
@traces(
spec="013",
story="US-001",
reqs=[
"REQ-013-001", # UXVolk alias is "U:Ux"
"REQ-013-002", # UXVolk role is "UX Designer"
],
)
class UXVolk(BaseAgent):
"""UX Designer volk — produces UI design artifacts."""
alias: str = Field(default="U:Ux")
role: str = "UX Designer"
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.escalation_target = "U:Ar"
self.ux_design = ""
self.task_summary = ""
@traces(
spec="013",
story="US-001",
reqs=[
"REQ-013-003", # routes CXP packets with subject "ux_design"
"REQ-013-004",
"REQ-013-030", # returns None for any subject other than "ux_design"
],
)
async def process(self, packet: CXPPacket) -> CXPPacket | None:
"""Route packet to appropriate handler."""
self._graph_context = extract_graph_context(packet.payload)
if packet.subject == "ux_design":
return await self._handle_ux_design(packet)
return None
@traces(
spec="013",
story="US-002",
reqs=[
"REQ-013-005", # calls _passthrough when has_ui is False or absent
"REQ-013-015", # calls _design_ui when has_ui is True
],
)
async def _handle_ux_design(self, packet: CXPPacket) -> CXPPacket:
"""Produce UI design or passthrough if not needed."""
has_ui = packet.payload.get("has_ui", False)
self.current_thread = packet.thread_id
self.task_summary = packet.payload.get("task_summary", "Implement as specified")
if not has_ui:
return self._passthrough(packet)
return await self._design_ui(packet)
@traces(
spec="013",
story="US-002",
reqs=[
"REQ-013-006", # constructs a CXP addressed to U:Ar with subject "implement"
"REQ-013-007", # sets WorkStatus.PENDING on the outbound CXP packet
"REQ-013-008", # forwards requirements from the inbound payload unchanged
"REQ-013-009", # forwards original_intent from the inbound payload unchanged
"REQ-013-010", # forwards task_summary from the inbound payload unchanged
"REQ-013-011", # forwards project_name from the inbound payload unchanged
"REQ-013-012", # forwards prolog_facts from the inbound payload unchanged
"REQ-013-013", # forwards scope_data from the inbound payload unchanged
"REQ-013-014", # does not inject any UX-specific keys when has_ui is False
],
)
def _passthrough(self, packet: CXPPacket) -> CXPPacket:
"""No UI needed — forward directly to Architect."""
self.status = WorkStatus.RESOLVED
self.summary = "No UI — passthrough to Architect"
print(" [U:Ux] No UI required — passing through", flush=True)
return CXPPacket(
from_agent="U:Ux",
to_agent="U:Ar",
thread_id=packet.thread_id,
subject="implement",
payload={
"requirements": packet.payload.get("requirements", ""),
"original_intent": packet.payload.get("original_intent", ""),
"task_summary": self.task_summary,
"project_name": packet.payload.get("project_name"),
"prolog_facts": packet.payload.get("prolog_facts", []),
"scope_data": packet.payload.get("scope_data", {}),
},
work_status=WorkStatus.PENDING,
)
@traces(
spec="013",
story="US-003",
reqs=[
"REQ-013-016", # calls call_llm with UX_SYSTEM_PROMPT
"REQ-013-017", # calls call_llm with graph_context
"REQ-013-018", # UX_SYSTEM_PROMPT contains step 1: MAP USER WORKFLOWS
"REQ-013-019", # UX_SYSTEM_PROMPT contains step 2: BUILD COMPONENT HIERARCHY
"REQ-013-020", # UX_SYSTEM_PROMPT contains step 3: DRAW WIREFRAMES
"REQ-013-021", # UX_SYSTEM_PROMPT contains step 4: DEFINE DESIGN TOKENS
"REQ-013-022", # UX_SYSTEM_PROMPT contains step 5: SPECIFY ACCESSIBILITY
"REQ-013-023", # stores the LLM output in a ux_design field on the outbound payload
"REQ-013-024", # LLM output begins with "UX_DESIGN:"
"REQ-013-025", # LLM output contains "WORKFLOWS:" section
"REQ-013-026", # LLM output contains "COMPONENTS:" section
"REQ-013-027", # LLM output contains "WIREFRAMES:" section
"REQ-013-028", # LLM output contains "DESIGN_TOKENS:" section
"REQ-013-029", # LLM output contains "ACCESSIBILITY:" section
],
)
async def _design_ui(self, packet: CXPPacket) -> CXPPacket:
"""Call LLM to produce UI design artifacts."""
self.status = WorkStatus.IN_PROGRESS
self.summary = "Designing UI"
requirements = packet.payload.get("requirements", "")
print(f" [U:Ux] Designing UI for: {self.task_summary}", flush=True)
prompt = (
f"Requirements:\n{requirements}\n\n"
f"Task: {self.task_summary}\n\n"
"Produce a complete UX design specification."
)
response = await self._call_llm(
UX_SYSTEM_PROMPT, prompt, temperature=0.5, graph_context=self._graph_context
)
self.ux_design = response
self.output_artifacts.append(f"=== UX DESIGN ===\n{response}")
print(" [U:Ux] UI design complete — forwarding to Architect", flush=True)
self.status = WorkStatus.RESOLVED
self.summary = "UI design complete"
return self._build_design_packet(packet, requirements)
@traces(
spec="013",
story="US-005",
reqs=[
"REQ-013-030", # constructs a CXP addressed to U:Ar with subject "ux_complete" containing the ux_design field plus all preserved payload context fields
],
)
def _build_design_packet(self, packet: CXPPacket, requirements: str) -> CXPPacket:
"""Build CXP packet forwarding UX design to Architect."""
return CXPPacket(
from_agent="U:Ux",
to_agent="U:Ar",
thread_id=packet.thread_id,
# REQ-013-030: the UX-design handoff subject is "ux_complete" (the
# no-UI passthrough uses "implement" per REQ-013-006). Architect
# accepts both.
subject="ux_complete",
payload={
"requirements": requirements,
"original_intent": packet.payload.get("original_intent", ""),
"task_summary": self.task_summary,
"project_name": packet.payload.get("project_name"),
"prolog_facts": packet.payload.get("prolog_facts", []),
"scope_data": packet.payload.get("scope_data", {}),
"ux_design": self.ux_design,
},
work_status=WorkStatus.PENDING,
)
# Class alias for orchestrata-ultimate naming
class UserExperienceAgent(UXVolk):
"""Agent alias for UXVolk."""
pass