feature: three archive fields for offline session analysis — distinct tool-result counts, interleaved-completion marker, stream mismatch
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 48/100
- Loại issue
- Tính năng
- Độ rõ ràng
- Khá rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- go
- Lĩnh vực
- observability
Hướng nghiên cứu
Start with core/pipeline/extensions.go to inspect InferenceExtension, then trace the inference parser to find where the previous turn and tool manifest are available. Read core/sessionapi/summary.go and its summarizeEvent function to see how existing counts reach the archive. The issue describes three separate additions; done means the requested counts, utility completion marker, and stream mismatch are recorded and surfaced in the relevant archive or usage view.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Summary
Three small fields the inference parser could record that would make the session archive
answer questions it currently cannot. All three came out of an offline analysis of a
30-day local archive (66 sessions, 29,606 events, 41 MB compressed) read through
archive.Open + Earlier. Each is independently useful; they are filed together because
they share one motivation — the archive already holds the data, the event just does not
carry the count or the flag that makes it readable without a full-session pass.
Scope of the measurements below
One developer's laptop archive, heavily Claude Code (18,785 of 29,606 events carry
claude-code/2.1.270). The ratios here describe one working style and should not be read
as a population — #1494 measured 59% of replies batching tool calls under explicit
prompting, against 7.3% here unprompted, so these numbers clearly move. What is not
style-dependent is the structural point in each item: the archive holds the fact and the
event does not state it.
1. A distinct tool-result count, so ToolResults metrics are not inflated ~272x
Every inference request re-sends the whole conversation, so each tool_result block is
recorded again on every subsequent turn. Counting ToolResults rows across a session
therefore overcounts by the conversation's length.
Measured on this archive:
Raw ToolResult rows across all events |
2,765,534 |
Distinct results (deduped by ToolUseID) |
10,183 |
| Replay amplification | 271.6x |
Distinct results with IsError |
362 (3.6%) |
Taking the raw rows at face value gives "~8 tool errors per LLM call" (75,207 error rows).
The true rate is 3.6%. The two differ by more than two orders of magnitude, and nothing on
the event signals which one you are computing — a consumer has to know to dedup, and has to
hold the whole session to do it.
InferenceExtension already carries MessageCount and ToolCount for exactly this
"counts for a reader of a projected copy" reason. Two more in the same spirit:
-
NewToolResults int— results whoseToolUseIDwas not in the previous turn -
ToolResultErrors int— of those, how many hadIsError
Then a correct failure rate is a sum over events rather than a dedup pass over a session.
Cheap at parse time, where the previous turn is already in hand.
Related but distinct: #1541 fixed in-memory heap from interner misses on interleaved
conversations. This is about analysis-time row counting — a different layer, and
unaffected by that fix.
2. Mark the agent's own interleaved utility completions
Claude Code issues completions that are not conversation turns: the permission security
monitor and the auto-mode state classifier. As AgentRole's own documentation notes, these
come from the same CLI, declare no subagent marker, and are therefore main. What separates
them is that they carry no tool manifest.
This matters for any attempt to measure how long a human took to respond. Classifying
"response with 0 tool calls -> next request" as user wait time gives 1,442 gaps — but 33.6%
of them are under 5 seconds, impossible for a person. Splitting by FinishReason:
FinishReason |
n | p50 | <5s |
|---|---|---|---|
end_turn |
1,072 | 82.5s | 23.7% |
| (empty) | 270 | 2.1s | 64.1% |
stop_sequence |
97 | 0.4s | 100% |
Requiring end_turn and a non-empty tool manifest gets this to 939 gaps, p50 111s, and
drops sub-5s to 16.7%. That is a workable heuristic, but it is a consumer-side guess at
something the parser knows directly.
- A sibling flag (
Interleaved bool, or similar) set when a completion is one of these
utility calls — derivable at parse time from a zero/short tool manifest
Deliberately not a third AgentRole value: that field is parsed from a billing header
and its doc argues against widening it. The precedent is Tunnel, whose doc makes the same
argument for an explicit producer signal rather than letting consumers infer shape.
3. Surface responses that were asked to stream and did not
InferenceExtension already distinguishes Stream (what the request asked for) from
StreamedResponse (what arrived). Nothing reads the disagreement:
| asked / got | n |
|---|---|
true / true |
8,776 |
true / false |
295 |
false / false |
121 |
295 requests asked to stream and did not. That is a real upstream or proxy behaviour worth
knowing about, and today it is invisible unless someone compares the two fields by hand.
- Count or surface the mismatch (usage pane,
/v1/usage, or anagentopcolumn)
While in the area, TunnelReason records failures nothing aggregates either: dial-failed
168, program-refused 66, os-trust-only 53 — 287 tunnels where, per that field's own
doc, "every plugin is blind to that traffic and someone has to restart something." The
visibility half of this is #1022; the counting half is cheap and separate.
Why these are worth the bytes
The archive is already the right place to answer "where did my agent's time go" — with
these three, one more question becomes answerable from Cortex alone, with no agent-harness
access: how much of a session's wall-clock was tool execution versus waiting on a human.
Classifying each response -> next request gap by whether proxied traffic landed inside it:
| n | p50 | total | share of gap time | |
|---|---|---|---|---|
Proxied tool (measured from Duration) |
1,910 | 1,045 ms | 11.6 h | 18.8% |
| Local tool (inferred — no proxied traffic) | 5,653 | 158 ms | 5.3 h | 8.6% |
| User wait (0 tool calls) | 1,442 | 32,358 ms | 44.8 h | 72.6% |
On single-tool-call turns the gap is that tool's latency, which recovers per-tool timings
with no harness data at all: Bash p50 201 ms (n=3,754), Edit 89 ms (n=814), Read 82 ms
(n=338), and AskUserQuestion 62,602 ms (n=68). That last one is useful validation —
the classifier never saw the tool's name, yet separated the one human-blocking tool from
the machine ones by three orders of magnitude.
Two honest limits on that table: the user-wait total is very sensitive to the gap ceiling
(24.8 h at 300s, 44.8 h at 1800s, 56.8 h at 3600s, 539 h uncapped), so the cap has to be
published with the figure; and the ~85 ms floor on Edit/Read is proxy round-trip plus agent
overhead, not tool time, so fast-tool numbers are upper bounds. Items 1 and 2 above remove
the two largest sources of error in it.
Where it lives
core/pipeline/extensions.go—InferenceExtension, besideMessageCount/ToolCount- the inference parser, where the previous turn and the full manifest are both in hand
core/sessionapi/summary.go—summarizeEvent, which already copies the counts
Not part of this
- Time-to-first-token and response-time percentiles: #951 (and #1026, #1466)
- Lossless request capture and replay: #1494
- URL-level egress visibility: #1022
Assisted-By: Claude (Anthropic AI) [email protected]
- Ngôn ngữ chính
- Go
- Star
- 26
- Fork
- 46
- Merge trung bình
- 13 giờ 49 phút
- Pull request đã merge (30 ngày)
- 244
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của rossoctl/cortex
-
enhancement ux
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 25/100
rossoctl/cortex#1739 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Feat: Keep coding agents working when the Cortex proxy stopsCó thể đã có người làm @huang195 đã nhận hôm nay. Đang mở
rossoctl/cortex#1738 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Phase C: Let Praxis core accept CONNECT and decrypt, and remove the Go front doorCó thể đã có người làm @huang195 đã nhận 2 ngày trước. Đang mởlaptop
rossoctl/cortex#1728 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Phase D: Move the Cortex store, pricing, session API and attribution into the binaryCó thể đã có người làm @huang195 đã nhận 2 ngày trước. Đang mởlaptop
rossoctl/cortex#1727 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Phase B: Send absolute-form requests to Praxis and remove the egress listenerCó thể đã có người làm @huang195 đã nhận 2 ngày trước. Đang mởlaptop
rossoctl/cortex#1726 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của rossoctl/cortex
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
google/osv-scalibr#2630 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
php/frankenphp#2829 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Suggested Edit
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 69/100
-
bug
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 88/100
Maintainer thường phản hồi trong vòng 1 ngày
-
tech-debt
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
Maintainer thường phản hồi trong vòng 1 ngày