NOIR
Capabilities

Media, browser, and web

Process private attachments, generate owned artifacts, render card groups, hand off browser work, and research public pages safely.

Model-visible references should be opaque and owner-scoped. Resolve provider URLs, bytes, credentials, and network destinations only inside trusted host code.

Attachment processing

@noir-agent/agent/media preprocesses attachments from the current verified message. mediaCapability() selects a host-provided processor by normalized MIME type, then bounds input bytes, dimensions, processor output, and derived text.

processCurrentAttachment() accepts only attachment IDs present in the active message context. It does not fetch an arbitrary model-provided URL. Provider tokens and raw storage pointers are removed before results return to the model.

Image generation

@noir-agent/agent/images wraps a host-injected generator or editor. Generated bytes are validated and saved through an exact-owner artifact store. Memory and Postgres stores return opaque image references; they do not expose provider URLs or bytes in tool output.

Use the same owner check when resolving an artifact for channel delivery or a repository write. Idempotent generation replays the stored artifact instead of billing the provider twice.

Card groups

@noir-agent/agent/cards turns reviewed templates into one to ten rendered slides.

import {
  defineRenderTemplate,
  renderTemplateCardsCapability,
} from '@noir-agent/agent/cards'

const cards = renderTemplateCardsCapability({
  agentId: 'data-agent',
  renderer,
  store: imageArtifacts,
  templates: [defineRenderTemplate({
    name: 'daily_metrics',
    description: 'Render the reviewed daily metrics layout.',
    groupText: 'Daily metrics',
    fallbackText: 'The visual report could not be delivered.',
    input: metricsInput,
    slides: ({ metrics }) => metrics.map((metric) => ({ metric })),
  })],
})

Templates and slide data are cloned, validated, bounded, and frozen before rendering. A channel must advertise atomic media-group support. Failure queues one deterministic text fallback and never claims a partial carousel succeeded.

Browser handoff

@noir-agent/agent/browser coordinates a browser session owned by an exact agent scope. A signed handoff token binds the browser task to its run and is consumed exactly once. Memory and Postgres stores persist the pending handoff and terminal result.

Use browser handoff for a user-visible login or UI step that cannot be completed through a provider API. The browser does not grant general access to other owners or resume a different run.

Public-web research

@noir-agent/agent/web exposes bounded scrape, same-origin crawl, and brand-extraction tools through a host-injected provider. safeWebUrl() and resolveSafeWebTarget() require public HTTPS destinations and reject unsafe targets.

For lower-level outbound calls, @noir-agent/agent/http provides createSafeHttpClient(), createSafeFetch(), and safeHttpCapability(). The boundary validates allowlisted endpoints, resolves and pins public DNS addresses, rechecks redirects, strips sensitive cross-origin headers, injects secrets host-side, and caps request/response bytes and time.

Security rules

  • never accept a provider URL, secret name, or destination host as an unrestricted model argument
  • re-authorize opaque artifacts at resolution time
  • keep generated and uploaded bytes outside model context
  • bound page count, crawl depth, output text, image dimensions, and render time
  • require a true isolation boundary before browsing or executing untrusted content
  • preserve the source URL and retrieval status in evidence returned to the model

Verify

Test an oversized attachment, stale artifact owner, duplicate generation key, partial card delivery, replayed browser token, private IP, DNS rebinding, cross-origin redirect, crawl escape, and provider timeout.

On this page