Logging and troubleshooting
September 11, 2026 · View on GitHub
Documentation index · CodexKit
Configure developer diagnostics and check common integration problems before shipping.
Developer Logging
CodexKit includes opt-in developer logging for the SDK itself. Logging is disabled by default and can be enabled independently on the runtime, built-in backend, and bundled stores.
let logging = AgentLoggingConfiguration.console(
minimumLevel: .debug
)
let backend = CodexResponsesBackend(
configuration: .init(
model: .gpt56Sol,
logging: logging
)
)
let stateStore = try SQLiteRuntimeStateStore(
logging: logging
)
let runtime = try AgentRuntime(configuration: .init(
authProvider: authProvider,
secureStore: secureStore,
backend: backend,
approvalPresenter: approvalInbox,
stateStore: stateStore,
logging: logging
))
You can also filter by category:
let logging = AgentLoggingConfiguration.osLog(
minimumLevel: .debug,
categories: [.runtime, .persistence, .network, .tools],
subsystem: "com.example.myapp"
)
Available logging categories include:
authruntimepersistencenetworkretrycompactiontoolsapprovalsstructuredOutputmemory
Network logging is split between .debug and .verbose so day-to-day diagnostics stay readable:
.debugincludes lifecycle/status breadcrumbs plus the outbound/responsesrequest JSON body, important received/responsespayloads such as final output items and completion/failure events, and streamed compaction request/output payloads. Encrypted compaction content is redacted..verboseadditionally includes every raw streaming SSE event payload, including token-by-token deltas.
Payload logs may include prompt text, request context, tool arguments, and model output, so use them only for developer diagnostics. Prefer .debug when you need request/response visibility without the streaming firehose, and .verbose when you need complete wire-level traces.
Use AgentConsoleLogSink for stderr-style console logs, AgentOSLogSink for unified Apple logging, or provide your own AgentLogSink.
Custom sinks make it possible to bridge CodexKit logs into your own telemetry or logging pipeline:
struct RemoteTelemetrySink: AgentLogSink {
func log(_ entry: AgentLogEntry) {
Telemetry.shared.enqueue(
level: entry.level,
category: entry.category.rawValue,
message: entry.message,
metadata: entry.metadata,
timestamp: entry.timestamp
)
}
}
let logging = AgentLoggingConfiguration(
minimumLevel: .info,
sink: RemoteTelemetrySink()
)
AgentLogEntry includes:
- timestamp
- level
- category
- message
- metadata
For remote telemetry or file-backed logging, prefer a sink that buffers or enqueues work quickly. AgentLogSink.log(_:) is called inline, so it should avoid blocking network I/O on the caller's execution path.
Production Checklist
- Store sessions in keychain (
KeychainSessionSecureStore) - Use persistent runtime state (
SQLiteRuntimeStateStore) - Gate impactful tools with approvals
- Handle auth cancellation and sign-out resets cleanly
- Tune retry/backoff policy for your app’s UX and latency targets
- Log tool invocations and failures for supportability
- Validate HealthKit/notification permission fallback states if using health features
Troubleshooting
- OAuth sheet closes but app does not update:
- confirm redirect is
http://localhost:1455/auth/callback - ensure app refreshes snapshot/state after sign-in completion
- confirm redirect is
- Health steps stay at
0:- verify HealthKit permission granted for Steps
- confirm this is running on a device/profile with step data
- Tool never executes:
- check approval prompt handling
- inspect host logs for
toolCallStarted/toolCallFinished