# Visibility: Content Review Pipeline

:::{admonition} Why this matters
:class: important
In a content review pipeline, internal agents (drafter, fact-checker, compliance reviewer) produce intermediate outputs that are useful for the pipeline but confusing for the end user. Visibility policies control which agents' outputs are shown to the user and which are hidden. This keeps the user experience clean while preserving full internal observability for debugging.
:::

:::{warning} Without this
Without visibility policies, every agent in the pipeline sends its output to the user. A 4-agent content pipeline floods the user with 4 messages: the draft, the fact-check results, the compliance notes, and the final published version. The user sees internal debate and contradictions that should have been resolved before the final output. Visibility policies ensure only the final, polished result reaches the user.
:::

:::{tip} What you'll learn
How to hide internal agent outputs from end users with visibility policies.
:::

_Source: `51_visibility_policies.py`_

::::{tab-set}
:::{tab-item} adk-fluent
```python
from adk_fluent import Agent
from adk_fluent._visibility import infer_visibility

MODEL = "gemini-2.5-flash"

# Content review pipeline: only the final publisher output matters to the user.
# Internal agents (drafter, fact-checker, compliance) should be silent.

content_pipeline = (
    Agent("drafter")
    .model(MODEL)
    .instruct(
        "Write a first draft of the article based on the research notes.\n"
        "Focus on clarity and structure. Don't worry about polish yet."
    )
    >> Agent("fact_checker")
    .model(MODEL)
    .instruct(
        "Review the draft for factual accuracy.\n"
        "Flag any unsupported claims. Add source annotations.\n"
        "Output the corrected draft with inline notes."
    )
    >> Agent("compliance")
    .model(MODEL)
    .instruct("Review for brand guidelines, legal requirements, and tone.\nFlag anything that needs legal review.")
    >> Agent("publisher")
    .model(MODEL)
    .instruct(
        "Produce the final published version.\n"
        "Incorporate fact-check corrections and compliance feedback.\n"
        "Remove all internal annotations."
    )
)

# Infer visibility from pipeline topology
ir = content_pipeline.to_ir()
visibility = infer_visibility(ir)

# For debugging: make all agents visible
debug_pipeline = (
    Agent("a").model(MODEL).instruct("Step 1.")
    >> Agent("b").model(MODEL).instruct("Step 2.")
    >> Agent("c").model(MODEL).instruct("Step 3.")
)
debug_pipeline.transparent()

# For production: only terminal agent visible (default behavior)
prod_pipeline = (
    Agent("a").model(MODEL).instruct("Step 1.")
    >> Agent("b").model(MODEL).instruct("Step 2.")
    >> Agent("c").model(MODEL).instruct("Step 3.")
)
prod_pipeline.filtered()

# Per-agent overrides: force an intermediate agent to be visible
compliance_agent = Agent("compliance").model(MODEL).instruct("Review.").show()
cleanup_agent = Agent("cleanup").model(MODEL).instruct("Clean up.").hide()
```
:::
:::{tab-item} Native ADK
```python
# In native ADK, a 4-agent content pipeline (draft → fact-check →
# compliance → publish) sends all intermediate outputs to the user.
# The user sees the raw draft, the fact-checker's internal notes, and
# the compliance report — when they only want the final published version.
# There's no built-in way to suppress intermediate events.
```
:::
:::{tab-item} Architecture
```mermaid
graph TD
    n1[["drafter_then_fact_checker_then_compliance_then_publisher (sequence)"]]
    n2["drafter"]
    n3["fact_checker"]
    n4["compliance"]
    n5["publisher"]
    n2 --> n3
    n3 --> n4
    n4 --> n5
```
:::
::::

## Equivalence

```python
# Only the terminal agent (publisher) is user-facing
assert visibility["drafter"] == "internal"
assert visibility["fact_checker"] == "internal"
assert visibility["compliance"] == "internal"
assert visibility["publisher"] == "user"

# Debug mode: all agents transparent
assert debug_pipeline._config["_visibility_policy"] == "transparent"

# Production mode: filtered
assert prod_pipeline._config["_visibility_policy"] == "filtered"

# Per-agent overrides set config
assert compliance_agent._config["_visibility_override"] == "user"
assert cleanup_agent._config["_visibility_override"] == "internal"
```
