Artifacts
Register native Android artifact providers so paired hosts can discover and request app-owned diagnostic exports such as network traces, map state, runtime snapshots, and support bundles.
Artifacts are app-owned diagnostic exports requested through artifacts.query and artifacts.request. Use artifacts when the output should become a named file, ZIP, JSON snapshot, or binary/text payload that Studio and agents can keep with the session.
Artifacts are for app-owned ground truth. Screenshots show what rendered, logs show what the app said, and touch input shows what the user did. Artifacts explain what the Android app knew internally at the same moment.
Good artifact candidates include:
| Artifact | Useful contents | Why use an artifact |
|---|---|---|
network-request.json | OkHttp or Retrofit method, route, sanitized URL, status, timing, retry count, cache policy, request/response body snippets, correlation ids, redacted headers. | Connects a failed screen or toast to the exact request that caused it. |
map-state.json | Google Maps or Mapbox camera, viewport, zoom/bearing/pitch, style URI, loaded source ids, visible layer ids, selected markers/features, tile/cache counters, last map error. | Lets an agent compare the map’s internal state with screenshots and user gestures. |
view-model-state.json | ViewModel, Compose state holder, selected ids, validation errors, loading flags, paging cursor, dirty fields. | Captures state that is too nested for logs and too sensitive for broad reflection. |
navigation-state.json | Navigation graph route, back stack, selected tab, sheet/dialog state, deep-link parameters, last failed navigation. | Makes a replayable checkpoint for UI-flow bugs. |
support-bundle.zip | Recent logs, sanitized config, Room or SQLite diagnostics, WorkManager queue summaries, cache summaries, domain snapshots. | Keeps related evidence together as one downloadable session artifact. |
Use a custom tool instead when the host needs a small JSON answer or a narrow action. Use an artifact when the evidence should be durable, downloadable, and correlated with screenshots, logs, telemetry, visual trees, touches, and annotations.
Project runtime objects into safe DTOs, redact tokens and secrets, trim large bodies, and register providers only for approved local development or QA workflows.
Register Providers
val options = AnsightOptions.createBuilder(Ansight.developerOptions(clientName = "Android App"))
.addArtifactProvider(CurrentReportArtifactProvider())
.withReadOnlyToolAccess()
.build()
Ansight.initializeAndActivate(application, options)
When artifactProviders is non-empty, the runtime registers the artifact tools during initialization.
| Tool id | Scope | Purpose |
|---|---|---|
artifacts.query | Read | Discover providers and artifact definitions. |
artifacts.request | Read | Ask a provider to create an artifact and stream the bytes. |
Artifact requests are read-scoped, but payloads can still export sensitive app data. Treat every provider as an explicit export surface with stable ids, clear descriptions, and narrowly shaped payloads.
Provider Example
import ai.ansight.runtime.AndroidArtifactDefinition
import ai.ansight.runtime.AndroidArtifactMetadata
import ai.ansight.runtime.AndroidArtifactProvider
import ai.ansight.runtime.AndroidArtifactProviderDescriptor
import ai.ansight.runtime.AndroidArtifactQueryContext
import ai.ansight.runtime.AndroidArtifactRequest
import ai.ansight.runtime.AndroidArtifactResult
class CurrentReportArtifactProvider : AndroidArtifactProvider {
override val descriptor = AndroidArtifactProviderDescriptor(
id = "app.reports",
name = "Reports",
description = "Exports app report artifacts.",
category = "reports",
)
override fun query(context: AndroidArtifactQueryContext): List<AndroidArtifactDefinition> =
listOf(
AndroidArtifactDefinition(
id = "current-report",
name = "Current Report",
description = "Exports the current report as CSV.",
kind = "report",
category = "reports",
mimeType = "text/csv",
fileName = "current-report.csv",
tags = listOf("csv", "current"),
),
)
override fun create(request: AndroidArtifactRequest): AndroidArtifactResult {
require(request.artifactId == "current-report") { "Unknown artifact." }
val bytes = "id,total\n1,42\n".toByteArray(Charsets.UTF_8)
return AndroidArtifactResult(
metadata = AndroidArtifactMetadata(
providerId = request.providerId,
artifactId = request.artifactId,
name = "Current Report",
kind = "report",
mimeType = "text/csv",
fileName = "current-report.csv",
sizeBytes = bytes.size.toLong(),
tags = listOf("csv", "current"),
),
bytes = bytes,
)
}
}
Choosing Artifacts
Choose artifacts for outputs that should leave the app as files or durable session evidence:
- attach a sanitized network request/response bundle to a failed checkout, login, sync, or search flow
- export a map-state snapshot when a map is blank, centered incorrectly, or missing expected markers
- export ViewModel, Compose, navigation, Room, or WorkManager state that is too nested for a short tool result
- package a support bundle that should stay attached to the captured session
Use Custom Tools for small reads or controlled actions that do not need file materialization.