fix(tracing): a same-millisecond tie keeps the record already there; nothing is recorded inside a deployment

- The times in the record are stored to the millisecond; two runs finishing
  in the same millisecond compared equal and the later writer won, which
  could leave the older run recorded. A tie now keeps what is there. No
  finer order is worth a field in the file.
- recording_enabled() is false when the platform's integration token is
  present: a deployment normally never reaches this code (the host binds
  the trace before crewAI would start its own), but a container that did
  not would have written a file the platform never reads, against what the
  docs promise. Test added.

89 passed; ruff and mypy clean.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Joao Moura
2026-09-20 17:39:21 -07:00
parent ae2bf77b57
commit 0f14e159cd
2 changed files with 31 additions and 8 deletions

View File

@@ -34,8 +34,16 @@ def project_dir() -> Path:
def recording_enabled() -> bool:
"""Off under the test suite, so kickoff-level tests leave no file behind."""
return os.environ.get("CREWAI_TESTING", "").lower() != "true"
"""Off under the test suite, so kickoff-level tests leave no file behind,
and off inside a deployment — the platform's integration token marks one —
so a run there never writes a file the platform never reads. (A deployment
normally never gets here at all: the host binds the trace before crewAI
would start its own; this is the guard for a container that did not.)"""
from crewai.context import get_platform_integration_token
if os.environ.get("CREWAI_TESTING", "").lower() == "true":
return False
return get_platform_integration_token() is None
def last_run_path(directory: Path | None = None) -> Path:
@@ -62,8 +70,9 @@ def record_last_run(
or the write failed. Never raises — a run is never failed by this.
"Last" means the run that FINISHED last: a record already there for a run
that finished later is kept, so two crews finishing together in one
project leave the newer one whichever writer gets to the file last."""
that finished later — or in the same millisecond — is kept, so two crews
finishing together in one project leave the newer one whichever writer
gets to the file last."""
if not recording_enabled():
return None
record: dict[str, Any] = {
@@ -109,16 +118,17 @@ def record_last_run(
def _newer_than(record: dict[str, Any], existing: dict[str, Any] | None) -> bool:
"""Is RECORD the later-finished run? A missing or unreadable existing record,
or one without a comparable time, never wins over the run just finished."""
or one without a comparable time, never wins over the run just finished; a
tie (the same millisecond) keeps what is there — the times are stored to
the millisecond, and no finer order is worth a field in the file."""
if not existing or existing.get("execution_id") == record["execution_id"]:
return True
ours = record["finished_at"] or record["recorded_at"]
theirs = existing.get("finished_at") or existing.get("recorded_at")
if not isinstance(theirs, str) or not isinstance(ours, str):
return True
return (
ours >= theirs
) # both ISO 8601 in UTC with the same precision: text order is time order
# Both ISO 8601 in UTC at the same precision: text order is time order.
return ours > theirs
def read_last_run(directory: Path | None = None) -> dict[str, Any] | None:

View File

@@ -51,6 +51,15 @@ def test_nothing_is_recorded_under_the_test_suite(monkeypatch, tmp_path):
assert not (tmp_path / ".crewai").exists()
def test_nothing_is_recorded_inside_a_deployment(monkeypatch, tmp_path):
"""The platform's integration token marks a deployment: no file the platform never reads."""
monkeypatch.setattr(last_run, "project_dir", lambda: tmp_path)
monkeypatch.delenv("CREWAI_TESTING", raising=False)
monkeypatch.setenv("CREWAI_PLATFORM_INTEGRATION_TOKEN", "platform-token")
assert last_run.record_last_run(execution_id="x", tier="authenticated", started_at_ns=None, finished_at_ns=None, amp_base_url=None) is None
assert not (tmp_path / ".crewai").exists()
def test_a_missing_or_broken_record_reads_as_none(project):
assert last_run.read_last_run(project) is None
(project / ".crewai").mkdir()
@@ -101,6 +110,10 @@ def test_the_run_that_finished_last_stays_recorded_whichever_writer_comes_last(p
last_run.record_last_run(execution_id="newest", tier="ephemeral", started_at_ns=base, finished_at_ns=base + 40 * second, amp_base_url=None)
assert last_run.read_last_run(project)["execution_id"] == "newest"
# A tie to the millisecond keeps what is there: the file orders runs no finer than it stores them.
last_run.record_last_run(execution_id="same-instant", tier="ephemeral", started_at_ns=base, finished_at_ns=base + 40 * second + 400_000, amp_base_url=None)
assert last_run.read_last_run(project)["execution_id"] == "newest"
# A record without a comparable time never blocks the run just finished.
(project / ".crewai" / "last_run.json").write_text(json.dumps({"execution_id": "legacy"}), encoding="utf-8")
last_run.record_last_run(execution_id="fresh", tier=None, started_at_ns=None, finished_at_ns=None, amp_base_url=None)