cc-transcript 14.19.0__tar.gz → 14.20.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.
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/PKG-INFO +1 -1
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/_native.pyi +5 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/query.py +17 -1
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/pyproject.toml +1 -1
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/context.rs +13 -4
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/parse.rs +1 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/render.rs +56 -17
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/types.rs +1 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/views/attachment.rs +9 -1
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/Cargo.lock +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/Cargo.toml +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/LICENSE +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/README.md +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/__init__.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/__init__.pyi +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/activity.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/activity_probe.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/builders.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/codex.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/command.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/context.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/corrections.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/cost.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/decision_store.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/decisions.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/discovery.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/disktruth.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/evidence.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/extract/__init__.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/extract/correct.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/facts.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/filterspec.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/heartbeats.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/ids.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/judge/__init__.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/judge/llm.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/judge/similar.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/judge/verdicts.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/ledger.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/literals.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/mining/__init__.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/mining/candidates.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/mining/confidence.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/mining/engine.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/mining/formats.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/mining/sampling.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/mining/signals.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/mining/sourcekind.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/mining/spec.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/mining/store.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/models.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/nlp.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/notifications.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/parser.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/py.typed +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/render.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/sentiment/__init__.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/sentiment/buckets.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/sentiment/data/afinn-en-165.tsv +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/sentiment/data/domain_overrides.tsv +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/sentiment/data/en-ewt.udpipe +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/sentiment/engine.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/sentiment/lexicon.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/sentiment/scorespec.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/synthetic.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/tools.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/watch.py +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/cli/Cargo.toml +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/cli/src/commands/blame.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/cli/src/commands/corrections.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/cli/src/commands/digest.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/cli/src/commands/facts.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/cli/src/commands/grep.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/cli/src/commands/list.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/cli/src/commands/mod.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/cli/src/commands/scratchpad.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/cli/src/commands/show.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/cli/src/commands/slice.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/cli/src/commands/stats.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/cli/src/commands/watch.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/cli/src/lib.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/cli/src/main.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/cli/src/output.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/cli/src/target.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/cli/src/timearg.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/Cargo.toml +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/benches/parse.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/benches/render.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/benches/toolcall.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/activity.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/actor.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/blame.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/buckets.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/codex/discovery.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/codex/lower.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/codex/mod.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/codex/parse.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/codex/probe.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/codex/protocol.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/codex/types.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/command.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/corrections.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/cost.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/discovery.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/facts.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/feedback.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/filter.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/gateway.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/ids.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/judge.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/lib.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/literals/command.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/literals/corrections.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/literals/feedback.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/literals/mining.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/literals/mod.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/literals/protocol.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/notifications.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/protocol.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/pystr.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/query.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/rng.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/schema.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/sqlite.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/toolcall.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/value.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/watch.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/Cargo.toml +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/build.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/data/command_prefix_pins.tsv +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/actor_bridge.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/bin/stub_gen.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/codex.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/command.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/context.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/corrections.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/discovery.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/feedback.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/judge.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/lexicon.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/lib.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/mining.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/nlp.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/python.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/render.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/score.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/sqlite.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/toolcall.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/views/blocks.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/views/command.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/views/convert.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/views/dunder.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/views/events.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/views/meta.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/views/mod.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/views/print.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/views/store.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/views/system.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/views/toolcall.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/views/toolresult.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/views/transcript.rs +0 -0
- {cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/py/src/watch.rs +0 -0
|
@@ -1498,12 +1498,17 @@ class QueuedCommand:
|
|
|
1498
1498
|
plain-string prompt (e.g. an image-paste payload).
|
|
1499
1499
|
command_mode: How the command was queued, e.g. ``prompt`` or
|
|
1500
1500
|
``task-notification``, or None.
|
|
1501
|
+
origin: Who sent a ``prompt``-mode command: ``human`` for the user,
|
|
1502
|
+
``peer`` for another agent or session, ``channel`` for an MCP
|
|
1503
|
+
channel event; None when the transcript does not record it.
|
|
1501
1504
|
"""
|
|
1502
1505
|
__match_args__: typing.ClassVar[tuple[str, ...]]
|
|
1503
1506
|
@property
|
|
1504
1507
|
def prompt(self) -> typing.Optional[builtins.str]: ...
|
|
1505
1508
|
@property
|
|
1506
1509
|
def command_mode(self) -> typing.Optional[builtins.str]: ...
|
|
1510
|
+
@property
|
|
1511
|
+
def origin(self) -> typing.Optional[builtins.str]: ...
|
|
1507
1512
|
|
|
1508
1513
|
@typing.final
|
|
1509
1514
|
class ReadCall(ToolCallBase):
|
|
@@ -26,7 +26,7 @@ from cc_transcript.activity import ActivityLift, SessionActivity, Turn, event_st
|
|
|
26
26
|
from cc_transcript.discovery import TranscriptExpiredError, resolve, subagent_paths, subagent_transcripts
|
|
27
27
|
from cc_transcript.filterspec import event_meta, session_id_of
|
|
28
28
|
from cc_transcript.ids import SessionId, ToolUseId
|
|
29
|
-
from cc_transcript.models import AssistantEvent, SystemEvent, ToolResultBlock, UserEvent
|
|
29
|
+
from cc_transcript.models import AssistantEvent, AttachmentEvent, QueuedCommand, SystemEvent, ToolResultBlock, UserEvent
|
|
30
30
|
from cc_transcript.notifications import Notifications
|
|
31
31
|
from cc_transcript.parser import parse
|
|
32
32
|
from cc_transcript.tools import (
|
|
@@ -642,6 +642,16 @@ class Session:
|
|
|
642
642
|
"""The window's last ``n`` events."""
|
|
643
643
|
return windowed(self, max(len(self) - n, 0), len(self))
|
|
644
644
|
|
|
645
|
+
def recent_messages(self, n: int) -> Session:
|
|
646
|
+
"""The window reaching back over its last ``n`` messages, for positive ``n``.
|
|
647
|
+
|
|
648
|
+
A message is a user or assistant event or a queued command. The hook,
|
|
649
|
+
reminder, system and mode events between messages ride along without
|
|
650
|
+
counting, so harness noise never crowds the conversation out of the window.
|
|
651
|
+
"""
|
|
652
|
+
messages = [index for index, event in enumerate(self.events) if is_message(event)]
|
|
653
|
+
return windowed(self, messages[-n] if n <= len(messages) else 0, len(self))
|
|
654
|
+
|
|
645
655
|
@property
|
|
646
656
|
def current_turn(self) -> Session:
|
|
647
657
|
"""The one-turn view of the window's last turn."""
|
|
@@ -960,6 +970,12 @@ class DeepView:
|
|
|
960
970
|
return iter(self.sessions)
|
|
961
971
|
|
|
962
972
|
|
|
973
|
+
def is_message(event: TranscriptEvent) -> bool:
|
|
974
|
+
return isinstance(event, UserEvent | AssistantEvent) or (
|
|
975
|
+
isinstance(event, AttachmentEvent) and isinstance(event.detail, QueuedCommand)
|
|
976
|
+
)
|
|
977
|
+
|
|
978
|
+
|
|
963
979
|
def windowed(session: Session, start: int, stop: int) -> Session:
|
|
964
980
|
turns: list[Turn] = []
|
|
965
981
|
base = 0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "cc-transcript"
|
|
3
|
-
version = "14.
|
|
3
|
+
version = "14.20.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"
|
|
@@ -11,7 +11,7 @@ use sonic_rs::{JsonContainerTrait, JsonValueTrait, Value};
|
|
|
11
11
|
use crate::activity::{LiftedSession, ToolUse, Turn};
|
|
12
12
|
use crate::ids::{encode_string, tool_digest, EventRef};
|
|
13
13
|
use crate::parse::parse_questions;
|
|
14
|
-
use crate::render::{clip, render_tool_call, render_turn, Budget};
|
|
14
|
+
use crate::render::{clip, human_queued_prompt, render_tool_call, render_turn, Budget};
|
|
15
15
|
use crate::toolcall::{parse_tool_call, parse_tool_result, ToolResult};
|
|
16
16
|
use crate::types::{ContentBlock, Entry, Question, ToolUseBlock};
|
|
17
17
|
use crate::value::{field, field_bool, field_str};
|
|
@@ -19,7 +19,7 @@ use crate::value::{field, field_bool, field_str};
|
|
|
19
19
|
pub const SCHEMA: &str = "cc-transcript.context/2";
|
|
20
20
|
pub const PREVIEW_SCHEMA: &str = "cc-transcript.preview/1";
|
|
21
21
|
pub const SUMMARY_LABEL: &str = "[summary fidelity — transcript unavailable]";
|
|
22
|
-
const ASK_USER_QUESTION: &str = "AskUserQuestion";
|
|
22
|
+
pub(crate) const ASK_USER_QUESTION: &str = "AskUserQuestion";
|
|
23
23
|
|
|
24
24
|
/// One structured preview part of a turn (context.py `Preview`): typed text, a tool
|
|
25
25
|
/// call reduced to name + digest + summary, or an AskUserQuestion round with its
|
|
@@ -549,8 +549,17 @@ fn build_previews(turn: &Turn, budget: &Budget) -> Vec<Preview> {
|
|
|
549
549
|
}
|
|
550
550
|
let mut uses = turn.tool_uses.iter();
|
|
551
551
|
for &event in &turn.events {
|
|
552
|
-
let
|
|
553
|
-
|
|
552
|
+
let assistant = match event {
|
|
553
|
+
Entry::Assistant(assistant) => assistant,
|
|
554
|
+
Entry::Attachment(attachment) => {
|
|
555
|
+
if let Some(prompt) = human_queued_prompt(&attachment.detail) {
|
|
556
|
+
parts.push(Preview::Text {
|
|
557
|
+
text: clip(prompt, budget.turn_chars),
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
continue;
|
|
561
|
+
}
|
|
562
|
+
_ => continue,
|
|
554
563
|
};
|
|
555
564
|
for block in &assistant.blocks {
|
|
556
565
|
match block {
|
|
@@ -478,6 +478,7 @@ fn parse_attachment_detail(data: &Value) -> AttachmentDetail {
|
|
|
478
478
|
Some("queued_command") => AttachmentDetail::QueuedCommand(QueuedCommand {
|
|
479
479
|
prompt: opt_str(att, "prompt"),
|
|
480
480
|
command_mode: opt_str(att, "commandMode"),
|
|
481
|
+
origin: field(att, "origin").and_then(|origin| opt_str(origin, "kind")),
|
|
481
482
|
}),
|
|
482
483
|
Some("deferred_tools_delta") => AttachmentDetail::DeferredToolsDelta(DeferredToolsDelta {
|
|
483
484
|
added_names: str_array(att, "addedNames"),
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
//! The one renderer, ported from `cc_transcript/render.py` — every cut happens here,
|
|
2
2
|
//! under a [`Budget`]. Parity notes on the individual helpers.
|
|
3
3
|
|
|
4
|
-
use std::collections::HashMap;
|
|
4
|
+
use std::collections::{HashMap, HashSet};
|
|
5
5
|
|
|
6
6
|
use chrono::{DateTime, FixedOffset};
|
|
7
7
|
use sonic_rs::{JsonContainerTrait, JsonType, JsonValueTrait, Value};
|
|
8
8
|
|
|
9
9
|
use crate::activity::Turn;
|
|
10
10
|
use crate::blame::{SessionWrites, Verdict};
|
|
11
|
+
use crate::context::ASK_USER_QUESTION;
|
|
11
12
|
#[cfg(feature = "command")]
|
|
12
13
|
use crate::facts::{McpServerSummary, ToolFact};
|
|
13
14
|
use crate::filter::{entry_text, event_kind};
|
|
@@ -432,36 +433,73 @@ pub fn render_tool_call(call: &ToolCall, budget: &Budget) -> String {
|
|
|
432
433
|
}
|
|
433
434
|
}
|
|
434
435
|
|
|
435
|
-
/// Render one turn — the prompt,
|
|
436
|
-
///
|
|
437
|
-
///
|
|
436
|
+
/// Render one turn — the prompt, the user's mid-turn messages, assistant prose,
|
|
437
|
+
/// every tool call, and the user's AskUserQuestion answers, in order (render.py
|
|
438
|
+
/// render_turn). Prose clips to `budget.turn_chars`; each tool call and answer
|
|
439
|
+
/// renders under `budget.tool_chars`.
|
|
438
440
|
pub fn render_turn(turn: &Turn, budget: &Budget) -> String {
|
|
439
441
|
let mut parts: Vec<String> = Vec::new();
|
|
440
442
|
if !turn.prompt.is_empty() {
|
|
441
443
|
parts.push(format!("user: {}", clip(&turn.prompt, budget.turn_chars)));
|
|
442
444
|
}
|
|
445
|
+
let mut questions: HashSet<&str> = HashSet::new();
|
|
443
446
|
for &event in &turn.events {
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
447
|
+
match event {
|
|
448
|
+
Entry::Assistant(assistant) => {
|
|
449
|
+
for block in &assistant.blocks {
|
|
450
|
+
match block {
|
|
451
|
+
ContentBlock::Text(text) if !pystr::strip(text).is_empty() => {
|
|
452
|
+
parts.push(format!("assistant: {}", clip(text, budget.turn_chars)));
|
|
453
|
+
}
|
|
454
|
+
ContentBlock::ToolUse(tool_use) => {
|
|
455
|
+
if tool_use.name == ASK_USER_QUESTION {
|
|
456
|
+
questions.insert(&tool_use.id);
|
|
457
|
+
}
|
|
458
|
+
parts.push(render_tool_call(
|
|
459
|
+
&parse_tool_call(&tool_use.name, &tool_use.input),
|
|
460
|
+
budget,
|
|
461
|
+
));
|
|
462
|
+
}
|
|
463
|
+
_ => {}
|
|
464
|
+
}
|
|
451
465
|
}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
466
|
+
}
|
|
467
|
+
Entry::User(user) => {
|
|
468
|
+
parts.extend(user.blocks().iter().filter_map(|block| match block {
|
|
469
|
+
ContentBlock::ToolResult(result)
|
|
470
|
+
if !result.is_error && questions.contains(result.tool_use_id.as_str()) =>
|
|
471
|
+
{
|
|
472
|
+
Some(format!(
|
|
473
|
+
"user answered: {}",
|
|
474
|
+
clip(&result.content, budget.tool_chars)
|
|
475
|
+
))
|
|
476
|
+
}
|
|
477
|
+
_ => None,
|
|
478
|
+
}));
|
|
479
|
+
}
|
|
480
|
+
Entry::Attachment(attachment) => {
|
|
481
|
+
if let Some(prompt) = human_queued_prompt(&attachment.detail) {
|
|
482
|
+
parts.push(format!("user: {}", clip(prompt, budget.turn_chars)));
|
|
457
483
|
}
|
|
458
|
-
_ => {}
|
|
459
484
|
}
|
|
485
|
+
_ => {}
|
|
460
486
|
}
|
|
461
487
|
}
|
|
462
488
|
parts.join("\n")
|
|
463
489
|
}
|
|
464
490
|
|
|
491
|
+
pub(crate) fn human_queued_prompt(detail: &AttachmentDetail) -> Option<&str> {
|
|
492
|
+
match detail {
|
|
493
|
+
AttachmentDetail::QueuedCommand(queued)
|
|
494
|
+
if queued.command_mode.as_deref() == Some("prompt")
|
|
495
|
+
&& queued.origin.as_deref() == Some("human") =>
|
|
496
|
+
{
|
|
497
|
+
queued.prompt.as_deref()
|
|
498
|
+
}
|
|
499
|
+
_ => None,
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
465
503
|
/// One compact `index tag time payload [uuid]` line (render.py compact_line).
|
|
466
504
|
pub fn compact_line(
|
|
467
505
|
index: usize,
|
|
@@ -1802,6 +1840,7 @@ fn attachment_detail_json(detail: &AttachmentDetail) -> Json {
|
|
|
1802
1840
|
AttachmentDetail::QueuedCommand(q) => obj(vec![
|
|
1803
1841
|
("prompt", opt_str(&q.prompt)),
|
|
1804
1842
|
("command_mode", opt_str(&q.command_mode)),
|
|
1843
|
+
("origin", opt_str(&q.origin)),
|
|
1805
1844
|
]),
|
|
1806
1845
|
AttachmentDetail::DeferredToolsDelta(delta) => obj(vec![
|
|
1807
1846
|
("added_count", Json::UInt(delta.added_names.len() as u64)),
|
|
@@ -463,6 +463,9 @@ view_dunders!(
|
|
|
463
463
|
/// plain-string prompt (e.g. an image-paste payload).
|
|
464
464
|
/// command_mode: How the command was queued, e.g. ``prompt`` or
|
|
465
465
|
/// ``task-notification``, or None.
|
|
466
|
+
/// origin: Who sent a ``prompt``-mode command: ``human`` for the user,
|
|
467
|
+
/// ``peer`` for another agent or session, ``channel`` for an MCP
|
|
468
|
+
/// channel event; None when the transcript does not record it.
|
|
466
469
|
#[pyo3_stub_gen::derive::gen_stub_pyclass]
|
|
467
470
|
#[pyclass(name = "QueuedCommand", module = "cc_transcript.models", frozen)]
|
|
468
471
|
pub(crate) struct QueuedCommandView {
|
|
@@ -490,12 +493,17 @@ impl QueuedCommandView {
|
|
|
490
493
|
fn command_mode(&self, _py: Python<'_>) -> PyResult<Option<String>> {
|
|
491
494
|
Ok(self.queued_command().command_mode.clone())
|
|
492
495
|
}
|
|
496
|
+
|
|
497
|
+
#[getter]
|
|
498
|
+
fn origin(&self, _py: Python<'_>) -> PyResult<Option<String>> {
|
|
499
|
+
Ok(self.queued_command().origin.clone())
|
|
500
|
+
}
|
|
493
501
|
}
|
|
494
502
|
|
|
495
503
|
view_dunders!(
|
|
496
504
|
QueuedCommandView,
|
|
497
505
|
"QueuedCommand",
|
|
498
|
-
fields = [prompt, command_mode]
|
|
506
|
+
fields = [prompt, command_mode, origin]
|
|
499
507
|
);
|
|
500
508
|
|
|
501
509
|
/// Tools added to and removed from the deferred tool inventory.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/sentiment/data/afinn-en-165.tsv
RENAMED
|
File without changes
|
{cc_transcript-14.19.0 → cc_transcript-14.20.0}/cc_transcript/sentiment/data/domain_overrides.tsv
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cc_transcript-14.19.0 → cc_transcript-14.20.0}/rust/crates/core/src/literals/corrections.rs
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|