cc-transcript 14.22.0__tar.gz → 14.23.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of cc-transcript might be problematic. Click here for more details.

Files changed (162) hide show
  1. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/PKG-INFO +1 -1
  2. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/render.py +4 -2
  3. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/pyproject.toml +1 -1
  4. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/render.rs +52 -21
  5. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/Cargo.lock +0 -0
  6. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/Cargo.toml +0 -0
  7. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/LICENSE +0 -0
  8. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/README.md +0 -0
  9. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/__init__.py +0 -0
  10. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/__init__.pyi +0 -0
  11. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/_native.pyi +0 -0
  12. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/activity.py +0 -0
  13. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/activity_probe.py +0 -0
  14. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/builders.py +0 -0
  15. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/codex.py +0 -0
  16. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/command.py +0 -0
  17. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/context.py +0 -0
  18. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/corrections.py +0 -0
  19. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/cost.py +0 -0
  20. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/decision_store.py +0 -0
  21. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/decisions.py +0 -0
  22. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/discovery.py +0 -0
  23. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/disktruth.py +0 -0
  24. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/evidence.py +0 -0
  25. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/extract/__init__.py +0 -0
  26. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/extract/correct.py +0 -0
  27. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/facts.py +0 -0
  28. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/filterspec.py +0 -0
  29. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/heartbeats.py +0 -0
  30. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/ids.py +0 -0
  31. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/judge/__init__.py +0 -0
  32. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/judge/llm.py +0 -0
  33. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/judge/similar.py +0 -0
  34. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/judge/verdicts.py +0 -0
  35. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/ledger.py +0 -0
  36. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/literals.py +0 -0
  37. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/mining/__init__.py +0 -0
  38. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/mining/candidates.py +0 -0
  39. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/mining/confidence.py +0 -0
  40. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/mining/engine.py +0 -0
  41. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/mining/formats.py +0 -0
  42. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/mining/sampling.py +0 -0
  43. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/mining/signals.py +0 -0
  44. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/mining/sourcekind.py +0 -0
  45. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/mining/spec.py +0 -0
  46. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/mining/store.py +0 -0
  47. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/models.py +0 -0
  48. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/nlp.py +0 -0
  49. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/notifications.py +0 -0
  50. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/parser.py +0 -0
  51. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/py.typed +0 -0
  52. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/query.py +0 -0
  53. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/sentiment/__init__.py +0 -0
  54. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/sentiment/buckets.py +0 -0
  55. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/sentiment/data/afinn-en-165.tsv +0 -0
  56. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/sentiment/data/domain_overrides.tsv +0 -0
  57. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/sentiment/data/en-ewt.udpipe +0 -0
  58. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/sentiment/engine.py +0 -0
  59. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/sentiment/lexicon.py +0 -0
  60. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/sentiment/scorespec.py +0 -0
  61. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/synthetic.py +0 -0
  62. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/tools.py +0 -0
  63. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/cc_transcript/watch.py +0 -0
  64. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/cli/Cargo.toml +0 -0
  65. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/cli/src/commands/blame.rs +0 -0
  66. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/cli/src/commands/corrections.rs +0 -0
  67. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/cli/src/commands/digest.rs +0 -0
  68. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/cli/src/commands/facts.rs +0 -0
  69. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/cli/src/commands/grep.rs +0 -0
  70. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/cli/src/commands/list.rs +0 -0
  71. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/cli/src/commands/mod.rs +0 -0
  72. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/cli/src/commands/scratchpad.rs +0 -0
  73. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/cli/src/commands/show.rs +0 -0
  74. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/cli/src/commands/slice.rs +0 -0
  75. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/cli/src/commands/stats.rs +0 -0
  76. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/cli/src/commands/watch.rs +0 -0
  77. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/cli/src/lib.rs +0 -0
  78. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/cli/src/main.rs +0 -0
  79. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/cli/src/output.rs +0 -0
  80. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/cli/src/target.rs +0 -0
  81. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/cli/src/timearg.rs +0 -0
  82. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/Cargo.toml +0 -0
  83. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/benches/parse.rs +0 -0
  84. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/benches/render.rs +0 -0
  85. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/benches/toolcall.rs +0 -0
  86. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/activity.rs +0 -0
  87. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/actor.rs +0 -0
  88. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/blame.rs +0 -0
  89. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/buckets.rs +0 -0
  90. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/codex/discovery.rs +0 -0
  91. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/codex/lower.rs +0 -0
  92. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/codex/mod.rs +0 -0
  93. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/codex/parse.rs +0 -0
  94. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/codex/probe.rs +0 -0
  95. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/codex/protocol.rs +0 -0
  96. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/codex/types.rs +0 -0
  97. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/command.rs +0 -0
  98. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/context.rs +0 -0
  99. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/corrections.rs +0 -0
  100. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/cost.rs +0 -0
  101. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/discovery.rs +0 -0
  102. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/facts.rs +0 -0
  103. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/feedback.rs +0 -0
  104. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/filter.rs +0 -0
  105. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/gateway.rs +0 -0
  106. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/ids.rs +0 -0
  107. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/judge.rs +0 -0
  108. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/lib.rs +0 -0
  109. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/literals/command.rs +0 -0
  110. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/literals/corrections.rs +0 -0
  111. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/literals/feedback.rs +0 -0
  112. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/literals/mining.rs +0 -0
  113. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/literals/mod.rs +0 -0
  114. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/literals/protocol.rs +0 -0
  115. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/notifications.rs +0 -0
  116. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/parse.rs +0 -0
  117. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/protocol.rs +0 -0
  118. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/pystr.rs +0 -0
  119. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/query.rs +0 -0
  120. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/rng.rs +0 -0
  121. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/schema.rs +0 -0
  122. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/sqlite.rs +0 -0
  123. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/toolcall.rs +0 -0
  124. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/types.rs +0 -0
  125. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/value.rs +0 -0
  126. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/core/src/watch.rs +0 -0
  127. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/Cargo.toml +0 -0
  128. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/build.rs +0 -0
  129. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/data/command_prefix_pins.tsv +0 -0
  130. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/actor_bridge.rs +0 -0
  131. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/bin/stub_gen.rs +0 -0
  132. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/codex.rs +0 -0
  133. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/command.rs +0 -0
  134. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/context.rs +0 -0
  135. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/corrections.rs +0 -0
  136. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/discovery.rs +0 -0
  137. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/feedback.rs +0 -0
  138. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/judge.rs +0 -0
  139. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/lexicon.rs +0 -0
  140. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/lib.rs +0 -0
  141. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/mining.rs +0 -0
  142. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/nlp.rs +0 -0
  143. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/python.rs +0 -0
  144. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/render.rs +0 -0
  145. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/score.rs +0 -0
  146. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/sqlite.rs +0 -0
  147. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/toolcall.rs +0 -0
  148. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/views/attachment.rs +0 -0
  149. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/views/blocks.rs +0 -0
  150. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/views/command.rs +0 -0
  151. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/views/convert.rs +0 -0
  152. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/views/dunder.rs +0 -0
  153. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/views/events.rs +0 -0
  154. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/views/meta.rs +0 -0
  155. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/views/mod.rs +0 -0
  156. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/views/print.rs +0 -0
  157. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/views/store.rs +0 -0
  158. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/views/system.rs +0 -0
  159. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/views/toolcall.rs +0 -0
  160. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/views/toolresult.rs +0 -0
  161. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/views/transcript.rs +0 -0
  162. {cc_transcript-14.22.0 → cc_transcript-14.23.0}/rust/crates/py/src/watch.rs +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cc-transcript
3
- Version: 14.22.0
3
+ Version: 14.23.0
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Environment :: Console
6
6
  Classifier: Intended Audience :: Developers
@@ -72,8 +72,10 @@ def render_turn(turn: Turn, *, budget: Budget, tool_results: bool = False) -> st
72
72
  Args:
73
73
  turn: The turn to render.
74
74
  budget: Character budgets for prose and tool calls.
75
- tool_results: Render each other tool result after its call, as ``result:``,
76
- or ``failed:`` when the call errored, clipped to ``budget.turn_chars``.
75
+ tool_results: Render each other tool result after its call: a ``result:``
76
+ head, or ``failed:`` when the call errored, naming the tool, then the
77
+ content clipped to ``budget.turn_chars`` on ``> `` lines. Calls batched in
78
+ one message and their results carry a ``call i/n``/``result i/n`` ordinal.
77
79
  """
78
80
  return _native.render_turn_from_events(
79
81
  turn.prompt,
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "cc-transcript"
3
- version = "14.22.0" # informational — releases stamp the version from the git tag
3
+ version = "14.23.0" # informational — releases stamp the version from the git tag
4
4
  description = "Grep every Claude Code session you've ever run."
5
5
  readme = "README.md"
6
6
  license = "PolyForm-Noncommercial-1.0.0"
@@ -438,29 +438,44 @@ pub fn render_tool_call(call: &ToolCall, budget: &Budget) -> String {
438
438
 
439
439
  /// Render one turn — the prompt, the user's mid-turn messages, assistant prose,
440
440
  /// every tool call, and the user's AskUserQuestion answers, in order (render.py
441
- /// render_turn). With `tool_results`, each other result follows its call. Prose and
442
- /// tool results clip to `budget.turn_chars`; each tool call and answer preview
443
- /// renders under `budget.tool_chars`.
441
+ /// render_turn). With `tool_results`, each other result follows its call as a
442
+ /// `result:`/`failed:` head naming the call, its content on `> ` lines, and a
443
+ /// `call i/n`/`result i/n` ordinal on calls batched in one message.
444
444
  pub fn render_turn(turn: &Turn, budget: &Budget, tool_results: bool) -> String {
445
445
  let mut parts: Vec<String> = Vec::new();
446
446
  if !turn.prompt.is_empty() {
447
447
  parts.push(format!("user: {}", clip(&turn.prompt, budget.turn_chars)));
448
448
  }
449
- let mut calls: HashMap<&str, &str> = HashMap::new();
449
+ let mut calls: HashMap<&str, CallLabel<'_>> = HashMap::new();
450
450
  for &event in &turn.events {
451
451
  match event {
452
452
  Entry::Assistant(assistant) => {
453
+ let batch = assistant
454
+ .blocks
455
+ .iter()
456
+ .filter(|block| matches!(block, ContentBlock::ToolUse(_)))
457
+ .count();
458
+ let mut ordinal = 0;
453
459
  for block in &assistant.blocks {
454
460
  match block {
455
461
  ContentBlock::Text(text) if !pystr::strip(text).is_empty() => {
456
462
  parts.push(format!("assistant: {}", clip(text, budget.turn_chars)));
457
463
  }
458
464
  ContentBlock::ToolUse(tool_use) => {
459
- calls.insert(&tool_use.id, &tool_use.name);
460
- parts.push(render_tool_call(
465
+ ordinal += 1;
466
+ let label = CallLabel {
467
+ name: &tool_use.name,
468
+ ordinal: (tool_results && batch > 1).then_some((ordinal, batch)),
469
+ };
470
+ let rendered = render_tool_call(
461
471
  &parse_tool_call(&tool_use.name, &tool_use.input),
462
472
  budget,
463
- ));
473
+ );
474
+ parts.push(match label.ordinal {
475
+ Some((i, n)) => format!("call {i}/{n}: {rendered}"),
476
+ None => rendered,
477
+ });
478
+ calls.insert(&tool_use.id, label);
464
479
  }
465
480
  _ => {}
466
481
  }
@@ -469,8 +484,8 @@ pub fn render_turn(turn: &Turn, budget: &Budget, tool_results: bool) -> String {
469
484
  Entry::User(user) => {
470
485
  for block in user.blocks() {
471
486
  if let ContentBlock::ToolResult(result) = block {
472
- if let Some(name) = calls.get(result.tool_use_id.as_str()) {
473
- parts.extend(result_lines(name, result, budget, tool_results));
487
+ if let Some(label) = calls.get(result.tool_use_id.as_str()) {
488
+ parts.extend(result_lines(label, result, budget, tool_results));
474
489
  }
475
490
  }
476
491
  }
@@ -486,8 +501,22 @@ pub fn render_turn(turn: &Turn, budget: &Budget, tool_results: bool) -> String {
486
501
  parts.join("\n")
487
502
  }
488
503
 
504
+ struct CallLabel<'a> {
505
+ name: &'a str,
506
+ ordinal: Option<(usize, usize)>,
507
+ }
508
+
509
+ impl CallLabel<'_> {
510
+ fn head(&self, verdict: &str) -> String {
511
+ match self.ordinal {
512
+ Some((i, n)) => format!("{verdict} {i}/{n}: {}", self.name),
513
+ None => format!("{verdict}: {}", self.name),
514
+ }
515
+ }
516
+ }
517
+
489
518
  fn result_lines(
490
- name: &str,
519
+ label: &CallLabel<'_>,
491
520
  result: &ToolResultBlock,
492
521
  budget: &Budget,
493
522
  tool_results: bool,
@@ -496,16 +525,13 @@ fn result_lines(
496
525
  if !tool_results {
497
526
  return Vec::new();
498
527
  }
499
- return vec![format!(
500
- "failed: {}",
501
- clip(&result.content, budget.turn_chars)
502
- )];
528
+ return quoted_result(label.head("failed"), &result.content, budget);
503
529
  }
504
- if name == ASK_USER_QUESTION {
530
+ if label.name == ASK_USER_QUESTION {
505
531
  if let Some(ToolResult::AskUserQuestion(answer)) = result
506
532
  .tool_use_result
507
533
  .as_ref()
508
- .map(|payload| parse_tool_result(name, payload))
534
+ .map(|payload| parse_tool_result(label.name, payload))
509
535
  {
510
536
  return answer_lines(&answer, budget);
511
537
  }
@@ -514,13 +540,18 @@ fn result_lines(
514
540
  clip(&result.content, budget.tool_chars)
515
541
  )];
516
542
  }
517
- if !tool_results || pystr::strip(&result.content).is_empty() {
543
+ if !tool_results {
518
544
  return Vec::new();
519
545
  }
520
- vec![format!(
521
- "result: {}",
522
- clip(&result.content, budget.turn_chars)
523
- )]
546
+ quoted_result(label.head("result"), &result.content, budget)
547
+ }
548
+
549
+ fn quoted_result(head: String, content: &str, budget: &Budget) -> Vec<String> {
550
+ let mut lines = vec![head];
551
+ if !pystr::strip(content).is_empty() {
552
+ lines.extend(prefixed("> ", &clip(content, budget.turn_chars)));
553
+ }
554
+ lines
524
555
  }
525
556
 
526
557
  fn answer_lines(answer: &AskUserQuestionResult, budget: &Budget) -> Vec<String> {
File without changes