dexcost
Go

Configuration

All Config fields, environment variables, development mode, attribution context helpers, and the dexcost CLI.

Configuration options

Pass a dexcost.Config struct to dexcost.Init(). Init is safe to call multiple times — only the first call takes effect.

FieldTypeDefaultDescription
APIKeystring"" — falls back to DEXCOST_API_KEYAPI key for cloud push. Must start with dx_live_ (production) or dx_test_ (sandbox). Omit or set Storage: "local" for local-only mode.
Storagestring"" (auto-detect)Force "local" to disable cloud push regardless of API key.
BatchSizeint100Maximum number of events per sync batch sent to the Control Layer.
FlushIntervalSecondsfloat645.0Seconds between background sync pushes.
BufferDirstring~/.dexcostDirectory for the local SQLite buffer (dexcost.db). Useful when the default path is on a read-only filesystem.
RedactFields[]stringnil (no redaction)Field names removed from event Details before cloud push (e.g. []string{"prompt", "completion"}).
HashCustomerIDboolfalseSHA-256 hash customer_id before cloud push so raw identifiers never leave the process.
Environmentstring"" — falls back to DEXCOST_ENVSet to "development" to enable dev console output and disable cloud push.
TrackHTTPboolfalseWrap http.DefaultTransport on Init to record external HTTP costs process-wide.
ServiceCatalogURLstring""URL to fetch an updated service catalog JSON at startup, extending or replacing the bundled 163-service catalog.
EnableRetryHeuristicsboolfalseEnable the in-memory RetryHeuristicEngine for automatic retry detection on RecordLLMCall.
RetryHeuristicWindowfloat6430Sliding-window size in seconds used by the heuristic engine.
RetryHeuristicThresholdfloat640.8Confidence threshold in (0, 1] above which an event is automatically flagged as a retry.

Init returns an error if the API key format is invalid, the buffer directory cannot be created, or the pricing engine fails to load.

err := dexcost.Init(dexcost.Config{
    APIKey:               "dx_live_...",
    BatchSize:            200,
    FlushIntervalSeconds: 10.0,
    RedactFields:         []string{"prompt", "completion"},
    HashCustomerID:       true,
    TrackHTTP:            true,
    EnableRetryHeuristics: true,
})
if err != nil {
    log.Fatalf("dexcost init: %v", err)
}
defer dexcost.Close()

Environment variables

Environment variables are read inside Config.init() when Init is called. Explicit field values in Config take precedence over environment variables.

VariableDescription
DEXCOST_API_KEYAPI key. Read when Config.APIKey is empty and Config.Storage is not "local".
DEXCOST_ENDPOINTOverride the Control Layer URL. Defaults to https://api.dexcost.io. Checked by Config.resolvedEndpoint() at push time.
DEXCOST_ENVSet to development to enable dev console mode without setting Config.Environment.

Development mode

Pass Environment: "development" in Config (or set DEXCOST_ENV=development) to enable dev mode:

dexcost.Init(dexcost.Config{Environment: "development"})

In dev mode:

  • Every llm_call, external_cost, compute_cost, and retry_marker event is printed to stderr as it is recorded, with provider, model, token counts, and cost.
  • Task completion is printed with aggregated cost totals and retry counts.
  • Cloud push is disabled — the SyncWorker (EventPusher) is not started.
  • An API key is not required.

Dev mode is controlled by the module-level devMode variable, managed by dexcost.EnableDevMode() and reset by dexcost.Close(). dexcost.IsDevMode() returns the current state.


Attribution & context

SetContext and SetContextWithMetadata

dexcost.SetContext attaches customer_id and project_id to a context.Context without starting an explicit task. HTTP adapters and wrapper clients use this attribution when no explicit task is present:

ctx = dexcost.SetContext(ctx, "acme-corp", "chatbot-v2")
resp, err := trackedClient.CreateChatCompletion(ctx, req)

dexcost.SetContextWithMetadata additionally sets an agent name and arbitrary metadata:

ctx = dexcost.SetContextWithMetadata(ctx,
    "acme-corp",      // customerID
    "chatbot-v2",     // projectID
    "support_agent",  // agent name
    map[string]interface{}{
        "tier":   "enterprise",
        "region": "us-east-1",
    },
)

Both functions return a derived context.Context and follow standard Go context propagation — pass the returned context to all downstream calls.

dexcost.GetContext(ctx) returns the *core.ContextData stored in the context, or nil. dexcost.ClearContext(ctx) returns a context with attribution removed.

WithCustomer and WithProject

dexcost.WithCustomer and dexcost.WithProject are TaskOption values that set attribution on a specific task at StartTask time:

ctx, task := dexcost.StartTask(ctx, "resolve_ticket",
    dexcost.WithCustomer("acme-corp"),
    dexcost.WithProject("support"),
)

Additional task options: dexcost.WithMetadata(map[string]interface{}{...}), dexcost.WithExperiment("exp-id"), dexcost.WithVariant("variant-a").


CLI

The dexcost CLI works offline against the local SQLite buffer. No API key is required.

Install via go install:

go install github.com/DexwoxBusiness/dexcost-go/cmd/dexcost@latest

dexcost status

Show the state of the local buffer:

dexcost status
dexcost status --db /path/to/dexcost.db

Output includes: DB location, event count, task count, last task timestamp, pending and synced event counts, and the current pricing data version.

dexcost rates

Manage the per-service cost rate registry. Rates are stored persistently at ~/.dexcost/rates.yaml:

# List all registered rates
dexcost rates --list

# Import rates from a YAML file into the persistent store
dexcost rates --import rates.yaml

# Export the persistent store to a YAML file
dexcost rates --export rates.yaml

# Override the default store location
dexcost rates --store /path/to/rates.yaml --list

YAML format expected by --import (canonical format shared with the Python SDK):

rates:
  maps.googleapis.com:
    per: request
    cost_usd: "0.005"
  ocr-api.com:
    per: page
    cost_usd: "0.01"

dexcost scan

Static-analysis scan of your codebase to find cost points that are not yet tracked. No API key or network connection is required:

dexcost scan ./cmd
dexcost scan ./cmd --generate-stubs

scan walks the target directory (default .), identifies LLM call sites (reported as auto-instrumented), and flags external API calls that likely incur cost but have no RecordCost() call nearby (reported as needing manual recording).

--generate-stubs prints ready-to-paste RecordCost() snippets for each untracked cost point found.

On this page