Skip to content

cron: log model + token usage per run#18172

Merged
steipete merged 2 commits intoopenclaw:mainfrom
HankAndTheCrew:oliver/cron-token-telemetry
Feb 16, 2026
Merged

cron: log model + token usage per run#18172
steipete merged 2 commits intoopenclaw:mainfrom
HankAndTheCrew:oliver/cron-token-telemetry

Conversation

@HankAndTheCrew
Copy link

@HankAndTheCrew HankAndTheCrew commented Feb 16, 2026

Adds best-effort token telemetry (input/output/total when provider returns usage) to cron run JSONL records and includes a local report script to summarize token usage by job over a time window.

  • Persists fields alongside existing cron run history: ~/.openclaw/cron/runs/.jsonl
  • Adds scripts/cron_usage_report.ts (tokens-only)

No cost estimation included.

Greptile Summary

Adds best-effort token telemetry (model, provider, usage) to cron run JSONL records and includes a local scripts/cron_usage_report.ts to summarize token usage. The telemetry fields are correctly threaded through the cron service layer (state.tstimer.tsserver-cron.ts) and the isolated agent runner (run.ts).

  • CronRunLogEntry type not updated (compile error): The CronRunLogEntry type in src/cron/run-log.ts was not extended with model, provider, and usage. The call site in server-cron.ts:216-218 passes these as an object literal to appendCronRunLog(filePath, entry: CronRunLogEntry), which will fail TypeScript's excess property check. Additionally, readCronRunLogEntries explicitly reconstructs entries from only the old fields, so the gateway API will strip telemetry data when reading logs back.
  • Telemetry omitted on delivery error paths: Several non-best-effort error returns in run.ts (lines 583, 596, 638, 724, 735) don't spread ...telemetry, silently dropping usage data when delivery fails after a successful agent run.

Confidence Score: 2/5

  • The PR has a type-level defect that likely causes a TypeScript compilation error; the core telemetry plumbing is sound but the persistence layer was not updated to match.
  • The CronRunLogEntry type in run-log.ts lacks the new model/provider/usage fields, which should produce a TS excess-property error when server-cron.ts passes them to appendCronRunLog. The readCronRunLogEntries function also strips these fields on read-back. These are fixable issues but they prevent the feature from working as intended without a follow-up change.
  • src/cron/run-log.ts needs CronRunLogEntry type and readCronRunLogEntries updated. src/cron/isolated-agent/run.ts error return paths should include telemetry.

Last reviewed commit: 098a205

(2/5) Greptile learns from your feedback when you react with thumbs up/down!

@openclaw-barnacle openclaw-barnacle bot added gateway Gateway runtime scripts Repository scripts size: M labels Feb 16, 2026
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5 files reviewed, 2 comments

Edit Code Review Agent Settings | Greptile

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 16, 2026

Additional Comments (2)

src/cron/run-log.ts
CronRunLogEntry missing new telemetry fields

appendCronRunLog accepts entry: CronRunLogEntry, but this type does not include the model, provider, or usage fields that server-cron.ts:216-218 now passes. Because the call site uses an object literal, TypeScript's excess property checking should reject this at compile time.

Additionally, readCronRunLogEntries (lines 98-115) reconstructs entries by explicitly copying only the known fields — so even though the data is written to the JSONL file (via JSON.stringify), reads through this function will strip model, provider, and usage, making the new telemetry invisible to the gateway API.

The type needs to be extended:

export type CronRunLogEntry = {
  ts: number;
  jobId: string;
  action: "finished";
  status?: "ok" | "error" | "skipped";
  error?: string;
  summary?: string;
  sessionId?: string;
  sessionKey?: string;
  runAtMs?: number;
  durationMs?: number;
  nextRunAtMs?: number;
  model?: string;
  provider?: string;
  usage?: {
    input_tokens?: number;
    output_tokens?: number;
    total_tokens?: number;
    cache_read_tokens?: number;
    cache_write_tokens?: number;
  };
};

And readCronRunLogEntries should be updated to copy these fields back when reading.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/cron/run-log.ts
Line: 4:16

Comment:
**`CronRunLogEntry` missing new telemetry fields**

`appendCronRunLog` accepts `entry: CronRunLogEntry`, but this type does not include the `model`, `provider`, or `usage` fields that `server-cron.ts:216-218` now passes. Because the call site uses an object literal, TypeScript's excess property checking should reject this at compile time.

Additionally, `readCronRunLogEntries` (lines 98-115) reconstructs entries by explicitly copying only the known fields — so even though the data is written to the JSONL file (via `JSON.stringify`), reads through this function will strip `model`, `provider`, and `usage`, making the new telemetry invisible to the gateway API.

The type needs to be extended:

```suggestion
export type CronRunLogEntry = {
  ts: number;
  jobId: string;
  action: "finished";
  status?: "ok" | "error" | "skipped";
  error?: string;
  summary?: string;
  sessionId?: string;
  sessionKey?: string;
  runAtMs?: number;
  durationMs?: number;
  nextRunAtMs?: number;
  model?: string;
  provider?: string;
  usage?: {
    input_tokens?: number;
    output_tokens?: number;
    total_tokens?: number;
    cache_read_tokens?: number;
    cache_write_tokens?: number;
  };
};
```

And `readCronRunLogEntries` should be updated to copy these fields back when reading.

How can I resolve this? If you propose a fix, please make it concise.

src/cron/isolated-agent/run.ts
Telemetry lost on delivery error paths

Several non-best-effort error returns (here, line 596, 638, 724, 735) omit ...telemetry even though the agent run completed successfully and consumed tokens. Since this PR is specifically about persisting usage telemetry, these paths will silently drop the model/provider/usage data from the cron run log entry. Consider spreading telemetry on error returns too:

        return withRunSession({
          status: "error",
          error: resolvedDelivery.error.message,
          summary,
          outputText,
          ...telemetry,
        });
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/cron/isolated-agent/run.ts
Line: 583:588

Comment:
**Telemetry lost on delivery error paths**

Several non-best-effort error returns (here, line 596, 638, 724, 735) omit `...telemetry` even though the agent run completed successfully and consumed tokens. Since this PR is specifically about persisting usage telemetry, these paths will silently drop the `model`/`provider`/`usage` data from the cron run log entry. Consider spreading telemetry on error returns too:

```suggestion
        return withRunSession({
          status: "error",
          error: resolvedDelivery.error.message,
          summary,
          outputText,
          ...telemetry,
        });
```

How can I resolve this? If you propose a fix, please make it concise.

@steipete steipete merged commit dbe2ab6 into openclaw:main Feb 16, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gateway Gateway runtime scripts Repository scripts size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments