Skip to content

[Bug]: Usage always 0 for custom OpenAI-compatible provider when using embedded runner (--local) #96463

Description

@bazhang1618

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

When using openclaw agent --local --json with a custom provider configured as api: "openai-completions", the lastCallUsage field in the JSON output, as well as usage entries in session files and trajectory logs, are always 0, despite the upstream provider correctly returning prompt_tokens and completion_tokens in its streaming response.

Steps to reproduce

1、Configure a custom provider in ~/.openclaw/openclaw.json with api: "openai-completions" and a valid baseUrl pointing to an OpenAI-compatible endpoint.

2、Run the following command:

bash
openclaw agent --local --json --session-id test-usage --message "Hi"
3、Inspect the meta.agentMeta.lastCallUsage field in the JSON output.

4、Inspect the session file:

bash
cat ~/.openclaw/agents/main/sessions/test-usage.jsonl | grep usage
5、Inspect the trajectory file:

bash
cat ~/.openclaw/agents/main/sessions/test-usage.trajectory.jsonl | grep usage
6、Run openclaw sessions list and observe the Tokens column.

Expected behavior

Based on the upstream provider's documented and observed behavior, the usage fields (input, output, cacheRead, cacheWrite, totalTokens) in the session file, trajectory, and --json output should contain the non-zero token counts returned by the provider, matching the values observed in the raw API response (e.g., {"prompt_tokens":5, "completion_tokens":10, "total_tokens":15}).

Actual behavior

The following observed outputs consistently show zero usage:

lastCallUsage in --json output: {"input":0,"output":0,"cacheRead":0,"cacheWrite":0,"total":0}

assistant message usage in session file: {"input":0,"output":0,"cacheRead":0,"cacheWrite":0,"totalTokens":0}

model.completed event usage in trajectory: {"input":0,"output":0,"cacheRead":0,"cacheWrite":0,"totalTokens":0}

openclaw sessions list shows unknown/200k (?%) in the Tokens column.

OpenClaw version

2026.6.10

Operating system

macOS 15.7.3 (arm64)

Install method

npm global

Model

DeepSeek-V4-Pro (served via custom MaaS platform)

Provider / routing chain

openclaw agent (embedded runner) -> custom-maas-hikvision-com-cn (api: openai-completions) -> MaaS platform

Additional provider/model setup details

json
{
"models": {
"providers": {
"custom-maas-example": {
"baseUrl": "https://maas.example.com/v1",
"api": "openai-completions",
"models": [
{ "id": "DeepSeek-V4-Pro", "contextWindow": 200000 }
]
}
}
}
}
api: "openai-completions" is explicitly set. The provider is a custom name (custom-maas-*).

Logs, screenshots, and evidence

1、Direct API verification: curl to the MaaS endpoint with stream: true and stream_options: {include_usage: true} returns a final chunk containing:

json
{"usage":{"prompt_tokens":5,"completion_tokens":10,"total_tokens":15}}
2、OpenAI SDK verification: A standalone Node.js test using the same openai SDK version (6.26.0) correctly receives chunk.usage with the same non-zero values.

3、Code inspection (OpenClaw 6.10, compiled):

In openai-completions-vbhA-xck.js, the streaming transport layer unconditionally parses chunk.usage:

js
if (chunk.usage) output.usage = parseChunkUsage(chunk.usage, model);
In run-attempt-DRhLt3eF.js, this.tokenUsage is only updated via:

js
case "thread/tokenUsage/updated":
    this.handleTokenUsage(params);
    break;
The "thread/tokenUsage/updated" event is only emitted by the Codex/Responses API path, not by the openai-completions streaming path.

In embedded-agent-BgF2MOkH.js, attempt.attemptUsage falls back to lastAssistantUsage (which reads from the session file, already 0), and mergeUsageIntoAccumulator receives zero.

4、Session file evidence: For the test-usage session, the assistant message in sessions/test-usage.jsonl contains:

json
"usage":{"input":0,"output":0,"cacheRead":0,"cacheWrite":0,"totalTokens":0}

Impact and severity

Affected users/systems/channels: All users of openclaw agent --local --json with a custom provider configured as api: "openai-completions". This includes users of local LLM servers (e.g., llama.cpp, vLLM) and third-party MaaS platforms.

Severity: High. Token usage data is critical for cost tracking, monitoring, auto-compaction, and session management. This bug makes all these features effectively blind.

Frequency: Always reproducible (6/6 observed attempts).

Consequence: Auto-compaction does not trigger, long-running tasks may fail silently due to context overflow, and cost/metering data is entirely missing from the system.

Additional information

This bug does not affect the cli-runner path (non---local), which correctly passes output to buildCliRunResult and preserves usage data.

The root cause is isolated to the embedded-agent runner's failure to bridge the already-parsed output.usage from the streaming transport layer to the attempt object's token usage, as it relies exclusively on the Codex-specific thread/tokenUsage/updated event.

A workaround is to avoid --local mode if the deployment allows it, but this is not feasible for many local/embedded use cases.

The issue was observed on OpenClaw 2026.6.10, but code analysis suggests it likely affects all versions where the embedded runner and openai-completions transport are used together.

Metadata

Metadata

Assignees

Labels

P2Normal backlog priority with limited blast radius.bugSomething isn't workingbug:behaviorIncorrect behavior without a crashclawsweeper:needs-live-reproClawSweeper needs live local, crabbox, or manual validation to confirm this issue.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.impact:auth-providerAuth, provider routing, model choice, or SecretRef resolution may break.impact:data-lossCan lose, corrupt, or silently drop user/session/config data.impact:session-stateSession, memory, transcript, context, or agent state can drift or corrupt.issue-rating: 🐚 platinum hermitGood issue quality with a plausible reproduction path needing some confirmation.

Type

No type

Fields

Priority

None yet

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions