jeffkit / jeffkit/agentproc

Runner should expose `usage` from `result` / `error` events in RunResult

Open
#2 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
2
Forks
0
PR merge metrics
No merged PRs in 30d

Description

Bug: usage field is dropped by the runner

The AgentProc protocol explicitly allows a usage object on result and error events (spec/protocol.md lines 262-264):

result and error MAY include a usage object for token/cost stats. Bridges MAY ignore it. Recommended keys (all optional): input_tokens, output_tokens, total_tokens (numbers). Additional keys are forward-compatible and SHOULD be ignored if unrecognised. There is no separate usage event type.

However, the Node SDK runner currently silently discards the field. Two locations:

1. RunResult shape (sdk/node/src/runner.js lines 469-477)
@typedef {Object} RunResult
@property {string} reply
@property {string} sessionId
@property {string} error
@property {number} exitCode
@property {boolean} timedOut

No usage field. Even if the agent emits it correctly, the runner does not expose it.

2. Shared stream utils (hub/_shared/stream_utils.js)

emitResult(text, sessionId) and emitError(text, sessionId) do not accept a usage parameter. The hub bridges can't easily forward CLI-reported token counts without monkey-patching the shared utility.

Fix

Runner side

In handleLine() (around line 680-732 of runner.js), when processing a result or error event:

  • Capture obj.usage if it's a plain object
  • Attach it to RunResult as usage?: object
  • Document the field as "whatever the agent emitted; opaque pass-through, not validated"
Hub bridge utility side

Extend emitResult(text, sessionId, usage?) and emitError(text, sessionId, usage?) in stream_utils.js so bridges can forward CLI-reported usage without bypassing the helper.

Why this matters

Cost / token accounting for IM-bridged agents is the headline use case of bridge observability. Without this, any host that wants to surface "this turn cost $0.012 / used 1234 input tokens" has to parse the agent's stdout itself, defeating the point of using the SDK.

Suggested labels

bug, sdk/node, good first issue

Related

Companion to #1 (Add in-process executor). Once usage is plumbed through, the in-process executor's RunResult will also expose usage — no extra work needed.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read spec/protocol.md lines 262-264, then inspect handleLine() in sdk/node/src/runner.js and emitResult()/emitError() in hub/_shared/stream_utils.js. Trace how result and error events become RunResult values and how bridges emit them. Done means plain-object usage is passed through on both paths, documented as opaque, and the shared helpers accept and forward optional usage.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, node.js
Domain
api, backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
76/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.