Terra is a Swift telemetry SDK for tracing AI workflows, tools, inference, streaming, embeddings, and safety checks.
print(Terra.help())
let report = Terra.diagnose()Use one workflow root per request:
let answer = try await Terra.workflow(name: "chat.request", id: "req-1") { workflow in
workflow.event("request.received")
let draft = try await workflow.infer(
"gpt-4o-mini",
prompt: "Summarize the latest issue"
) { span in
span.tokens(input: 24, output: 14)
return "draft"
}
let toolResult = try await workflow.tool(
"search",
callId: "search-1",
type: "web_search"
) { span in
span.event("tool.invoked")
return "docs"
}
return draft + toolResult
}Use the transcript overload when the workflow owns chat history mutation:
var messages = [Terra.ChatMessage(role: "user", content: "Plan the fix.")]
let result = try await Terra.workflow(name: "planner", messages: &messages) { workflow, transcript in
workflow.checkpoint("planning")
await transcript.append(.init(role: "assistant", content: "Draft plan"))
return "ok"
}Keep streaming under a workflow root. The stream span finalizes chunk and output-token metrics when the streaming closure returns or throws:
let streamed = try await Terra.workflow(name: "stream.request") { workflow in
try await workflow.stream("gpt-4o-mini", prompt: "Explain") { span in
span.firstToken()
span.chunk(4)
span.outputTokens(12)
return "done"
}
}If a tool call is discovered inside a child inference/stream span but executed later, hand it off to the wider parent before the child closes:
let answer = try await Terra.workflow(name: "stream.and.tool") { workflow in
let deferred = try await workflow.stream("gpt-4o-mini", prompt: "Explain") { span in
span.firstToken()
span.chunk(4)
return try span.handoff().tool("search", callId: "search-1", type: "web_search")
}
let toolResult = try await deferred.run { "docs" }
return toolResult
}Use manual lifecycle only when even the workflow root cannot own the whole request:
let parent = Terra.startSpan(name: "manual.request")
defer { parent.end() }
_ = try await Terra.tool("search", callId: "manual-1").under(parent).run { "ok" }Terra.help()Terra.diagnose()Terra.ask("workflow with tools")Terra.examples()Terra.guides()Terra.playground()