Vibe exposes provider-neutral web search and fetch APIs to eval through the Web alias.

Search defaults to the Exa provider when EXA_API_KEY is set:

Web.search!("OpenAI Responses WebSocket agent loop",
  type: :deep,
  num_results: 5,
  highlights: true,
  summary: true
)
|> MD.doc()

Fetch defaults to a local Req provider. Put network/provider concerns in request options:

Web.fetch!("https://hexdocs.pm/ecto/Ecto.html",
  format: :html,
  timeout: 30_000
)

Put local content transformations in pipes:

Web.fetch!("https://hexdocs.pm/ecto/Ecto.html", format: :html)
|> Web.select!("main")
|> MD.doc()

Markdown rendering belongs to the Vibe.Markdown protocol. Use MD.doc/1 or MD.to_markdown/1; do not add renderer-specific Web.markdown/1 helpers.

Supported fetch formats:

:markdown
:text
:html
:json

Search and fetch providers are behaviours, so future backends can share the same eval-facing API:

Vibe.Plugins.WebSearch.SearchProvider
Vibe.Plugins.WebSearch.FetchProvider

Per-call provider override:

Web.search!("query", provider: :exa)
Web.fetch!("https://example.com", provider: :req)

Provider-specific details are normalized into Vibe.Plugins.WebSearch.SearchResult, Vibe.Plugins.WebSearch.SearchItem, and Vibe.Plugins.WebSearch.FetchResult structs with Markdown protocol rendering.

Use Web.parse_html!/1 when you need direct Floki traversal:

Web.fetch!("https://hexdocs.pm/ecto/Ecto.html", format: :html)
|> Web.parse_html!()
|> Floki.find("main h2")
|> Enum.map(&Floki.text/1)

Common extraction should use Web.select!/2 so selector metadata stays with the fetch result. Advanced traversal can use Floki directly after Web.parse_html!/1.

The LiveView console renders image tool results semantically. Inline images use data: URLs, while large image reads are copied to session artifacts and displayed through local artifact URLs such as:

/sessions/<session-id>/artifacts/images/<file>.png

Artifact-backed previews include an “Open original” link.

The session composer accepts inline image references such as:

describe @screenshots/login.png

Image references are converted into semantic prompt content before dispatch. The transcript keeps the user's original text and shows an attachment badge, while the model request receives image content parts.

Orphan artifact directories can be cleaned with:

vibe sessions prune --artifacts

Do not put secrets or authorization headers into telemetry metadata. Pass custom fetch headers only when required.