}
record.Turn = request.Turn
+ record.Agent = request.Agent
response, err := c.send(httpRequest, &record)
if err != nil {
record.Error = err.Error()
// ModelRequest is one model call. Input holds the input items in order, such as
// modelUserMessage values or output items of an earlier response. Node names
// the node that a compaction builds, or is nil. Turn names the request of a
-// turn: first or next. Node and Turn go only to the usage file, never to the
-// endpoint.
+// turn: first or next. Agent names the subagent that makes the call, or is
+// empty for a call of the agent itself. Node, Turn, and Agent go only to the
+// usage file, never to the endpoint.
type ModelRequest struct {
Model string
Effort string
Input []any
Node *NodeKey
Turn string
+ Agent string
}
// ModelResponse is the result of a model call. Output holds the output items as
// ModelUsageRecord is one line of usage.jsonl. Date is the start of the call,
// and Seconds its length. Node is the node [l, i] of a compaction. Status is
// the HTTP status, or 0 when no response came. TextBytes is the size of the
-// text of the reply. Turn names the request of a turn. Quota holds the
-// x-codex-* headers of the response, without the turn state.
+// text of the reply. Turn names the request of a turn. Agent names the subagent
+// of the call. Quota holds the x-codex-* headers of the response, without the
+// turn state.
type ModelUsageRecord struct {
Date string `json:"date"`
Seconds float64 `json:"seconds"`
Model string `json:"model"`
Node *[2]int `json:"node,omitempty"`
Turn string `json:"turn,omitempty"`
+ Agent string `json:"agent,omitempty"`
Status int `json:"status"`
InputTokens int `json:"input_tokens"`
CachedTokens int `json:"cached_tokens"`
client := newTestModelClient(t, server)
request := modelTestRequest()
request.Node = &NodeKey{2, 5}
+ request.Agent = "GreenOtter"
_, err := client.Create(t.Context(), request)
require.NoError(t, err)
require.NotContains(t, server.Call(0).body, "node")
require.NotContains(t, string(server.Call(0).raw), "[2,5]")
+ require.NotContains(t, string(server.Call(0).raw), "GreenOtter")
_, err = client.Create(t.Context(), modelTestRequest())
require.ErrorContains(t, err, "HTTP 429")
require.Equal(t, 7, records[0].OutputTokens)
require.Equal(t, quota, records[0].Quota)
require.Equal(t, &[2]int{2, 5}, records[0].Node)
+ require.Equal(t, "GreenOtter", records[0].Agent)
require.Equal(t, len("ok"), records[0].TextBytes)
require.Greater(t, records[0].Seconds, 0.0)
require.Empty(t, records[0].Error)
require.NotEmpty(t, records[0].Date)
require.Nil(t, records[1].Node)
+ require.Empty(t, records[1].Agent)
require.Zero(t, records[1].TextBytes)
require.Equal(t, http.StatusTooManyRequests, records[1].Status)