Artifacts
Register native iOS 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 that Ansight can discover and request from a paired app. Use artifacts when the output should be preserved as a named file or binary/text payload rather than squeezed into a small JSON custom-tool result.
Use artifacts to attach the app’s internal evidence to a session. Screenshots and visual trees show what rendered, logs show what the app said, and touches show what the user did. Artifacts add the missing layer: what the app knew internally when the bug happened.
Good artifact candidates include:
| Artifact | Useful contents | Why use an artifact |
|---|---|---|
network-request.json | URLSession or Alamofire method, route, sanitized URL, status, timing, retry count, request/response body snippets, correlation ids, redacted headers. | Explains a failed screen from the exact request context instead of a generic error label. |
map-state.json | MapKit or Mapbox camera, visible region, zoom/bearing/pitch, style URI, loaded source ids, visible layers, selected annotations/features, last map error. | Lets an agent compare what the map thinks is visible with the screenshot and touch timeline. |
view-model-state.json | SwiftUI model or UIKit presenter state, selected ids, validation errors, loading flags, paging cursors, dirty fields. | Captures object state without opening broad reflection access over live objects. |
navigation-state.json | Navigation path, presented sheets, selected tab, route parameters, pending deep link, last failed navigation. | Makes a replayable UI-flow checkpoint. |
support-bundle.zip | Recent logs, sanitized configuration, cache summaries, Core Data or SQLite diagnostics, 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 become durable session material that Studio and agents can download, inspect, and correlate with screenshots, logs, telemetry, and annotations.
Keep providers explicit and reviewable. Project runtime objects into safe DTOs, redact tokens and secrets, trim large bodies, and register providers only for approved local development or QA workflows.
The native iOS SDK exposes:
AnsightArtifactProviderAnsightArtifactDefinitionAnsightArtifactMetadataAnsightArtifactPayloadAnsightArtifactResult- runtime provider registration and the
artifacts.query/artifacts.requesttools
Register Providers
import Ansight
try AnsightRuntime.shared.initializeAndActivateAnsightSdk { options in
options.withReadOnlyToolAccess()
}
try AnsightRuntime.shared.registerArtifactProvider(CurrentReportArtifactProvider())
Registering a provider also registers the artifact tools when needed:
| Tool id | Scope | Purpose |
|---|---|---|
artifacts.query | read | Discover registered providers and their currently available artifact definitions. |
artifacts.request | read | Ask a provider to create an artifact snapshot and stream its payload to the host. |
withReadOnlyToolAccess() is enough for artifact discovery and requests.
Artifact requests are read-scoped, but payloads can still contain sensitive app data. Treat every provider as an export surface: keep provider ids stable, describe what leaves the process, and avoid publishing raw framework objects directly.
Provider Example
import AnsightCore
import Foundation
struct CurrentReportArtifactProvider: AnsightArtifactProvider {
var descriptor: AnsightArtifactProviderDescriptor {
AnsightArtifactProviderDescriptor(
id: "app.reports",
name: "Reports",
description: "Exports app report artifacts.",
category: "reports",
tags: ["reports", "support"]
)
}
func query(context: AnsightArtifactQueryContext) throws -> [AnsightArtifactDefinition] {
[
AnsightArtifactDefinition(
id: "current-report",
name: "Current Report",
description: "Exports the current report as CSV.",
kind: "report",
category: "reports",
content: AnsightArtifactContentDescriptor(
supportedMimeTypes: ["text/csv"],
defaultMimeType: "text/csv",
suggestedFileName: "current-report.csv",
supportsText: true
),
security: AnsightToolSecurity(
level: .high,
summary: "Exports current report data."
),
tags: ["csv", "current"]
)
]
}
func create(request: AnsightArtifactRequest) throws -> AnsightArtifactResult {
guard request.artifactId == "current-report" else {
throw RuntimeError.invalidInput("Unknown artifact.")
}
let csv = "id,total\n1,42\n"
let payload = AnsightArtifactPayload.fromText(csv)
return AnsightArtifactResult(
metadata: AnsightArtifactMetadata(
artifactId: request.artifactId,
providerId: request.providerId,
name: "Current Report",
kind: "report",
mimeType: "text/csv",
fileName: "current-report.csv",
sizeBytes: payload.sizeBytes,
tags: ["csv", "current"]
),
payload: payload
)
}
}
AnsightArtifactPayload can be created from text, bytes, or a file path:
AnsightArtifactPayload.fromText("debug text")
AnsightArtifactPayload.fromBytes(data)
AnsightArtifactPayload.fromFile(filePath)
Runtime Management
try AnsightRuntime.shared.registerArtifactProviders([provider])
try AnsightRuntime.shared.registerArtifactProvider(provider, replaceExisting: true)
let ids = AnsightRuntime.shared.registeredArtifactProviderIds()
let providers = AnsightRuntime.shared.registeredArtifactProviders()
AnsightRuntime.shared.unregisterArtifactProvider("app.reports")
AnsightRuntime.shared.clearArtifactProviders()
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 looks blank, centered incorrectly, or missing expected annotations
- export SwiftUI model, store, navigation, or Core Data 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.