From bf1cab94a6cffbf3375245f6ca3d6eabdcf3062f Mon Sep 17 00:00:00 2001 From: Jer Miller Date: Sat, 7 Mar 2026 12:34:59 -0700 Subject: [PATCH] =?UTF-8?q?CPO:=20cluster=20layer=20semantic=20rename=20ho?= =?UTF-8?q?p=202=20=E2=80=94=20screen=20=E2=86=92=20percepts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename the screen source type to percepts across the cluster layer, muse configs, CLI, importers, stats, and all tests. The entry prefix changes from "screen" to "percept" (singular, matching "transcript"). The rendering header "### Screen Activity" is unchanged — it describes the content origin, not the source type. Agent filter dicts like {"agents": {"screen": true}} are also unchanged as they reference agent output filenames. Also updates inline muse configs in test_generate_full.py and test_output_hooks.py from old "audio"/"screen" keys to "transcripts"/"percepts" (audio was stale since hop 1). Co-Authored-By: Claude Opus 4.6 --- apps/transcripts/call.py | 22 ++++--- apps/transcripts/tests/test_call.py | 2 +- muse/activities.md | 2 +- muse/activity.md | 2 +- muse/activity_state.md | 2 +- muse/daily_schedule.md | 2 +- muse/decisions.md | 2 +- muse/documentation.md | 2 +- muse/entities.md | 2 +- muse/facets.md | 2 +- muse/files.md | 2 +- muse/flow.md | 2 +- muse/followups.md | 2 +- muse/knowledge_graph.md | 2 +- muse/media.md | 2 +- muse/meetings.md | 2 +- muse/messaging.md | 2 +- muse/observation.md | 2 +- muse/opportunities.md | 2 +- muse/research.md | 2 +- muse/schedule.md | 2 +- muse/screen.md | 2 +- muse/speakers.md | 2 +- muse/timeline.md | 2 +- muse/tools.md | 2 +- tests/baselines/api/stats/stats.json | 34 +++++----- tests/baselines/api/todos/badge-count.json | 2 +- tests/baselines/api/todos/nudges.json | 17 ++++- tests/baselines/api/transcripts/segments.json | 6 +- tests/test_cluster.py | 34 +++++----- tests/test_cluster_full.py | 6 +- tests/test_generate_full.py | 8 +-- tests/test_generators.py | 2 +- tests/test_journal_stats.py | 2 +- tests/test_muse.py | 8 +-- tests/test_output_hooks.py | 10 +-- think/cluster.py | 62 +++++++++---------- think/journal_stats.py | 24 +++---- think/muse.py | 6 +- 39 files changed, 154 insertions(+), 137 deletions(-) diff --git a/apps/transcripts/call.py b/apps/transcripts/call.py index ad77e2040..ae61cbd06 100644 --- a/apps/transcripts/call.py +++ b/apps/transcripts/call.py @@ -46,7 +46,7 @@ def scan( else: typer.echo(" (none)") - typer.echo("Screen:") + typer.echo("Percepts:") if screen_ranges: for start, end in screen_ranges: typer.echo(f" {start} - {end}") @@ -94,7 +94,8 @@ def read( raw: bool = typer.Option(False, "--raw", help="Include transcripts and screen only."), transcripts: bool = typer.Option(False, "--transcripts", help="Include transcript content."), audio: bool = typer.Option(False, "--audio", help="Alias for --transcripts.", hidden=True), - screen: bool = typer.Option(False, "--screen", help="Include screen transcripts."), + percepts: bool = typer.Option(False, "--percepts", help="Include screen percepts."), + screen: bool = typer.Option(False, "--screen", help="Alias for --percepts.", hidden=True), agents: bool = typer.Option(False, "--agents", help="Include agent outputs."), max_bytes: int = typer.Option( 16384, "--max", help="Max output bytes (0 = unlimited)." @@ -104,27 +105,28 @@ def read( day = resolve_sol_day(day) segment = resolve_sol_segment(segment) stream = stream or get_sol_stream() - # --audio is an alias for --transcripts + # --audio is an alias for --transcripts, --screen is an alias for --percepts transcripts = transcripts or audio + percepts = percepts or screen if full and raw: typer.echo("Error: Cannot use --full and --raw together.", err=True) raise typer.Exit(1) - if (full or raw) and (transcripts or screen or agents): + if (full or raw) and (transcripts or percepts or agents): typer.echo( "Error: Cannot mix --full/--raw with individual source flags.", err=True ) raise typer.Exit(1) if full: - sources: dict[str, bool] = {"transcripts": True, "screen": True, "agents": True} + sources: dict[str, bool] = {"transcripts": True, "percepts": True, "agents": True} elif raw: - sources = {"transcripts": True, "screen": True, "agents": False} - elif transcripts or screen or agents: - sources = {"transcripts": transcripts, "screen": screen, "agents": agents} + sources = {"transcripts": True, "percepts": True, "agents": False} + elif transcripts or percepts or agents: + sources = {"transcripts": transcripts, "percepts": percepts, "agents": agents} else: - sources = {"transcripts": True, "screen": False, "agents": True} + sources = {"transcripts": True, "percepts": False, "agents": True} if segment and (start or length is not None): typer.echo("Error: Cannot mix --segment with --start/--length.", err=True) @@ -158,7 +160,7 @@ def stats(month: str = typer.Argument(help="Month (YYYYMM).")) -> None: transcript_ranges, screen_ranges = cluster_scan(day) if transcript_ranges or screen_ranges: days_with_data += 1 - typer.echo(f"{day} transcripts:{len(transcript_ranges)} screen:{len(screen_ranges)}") + typer.echo(f"{day} transcripts:{len(transcript_ranges)} percepts:{len(screen_ranges)}") if not days_with_data: typer.echo(f"No data for {month}.") diff --git a/apps/transcripts/tests/test_call.py b/apps/transcripts/tests/test_call.py index 55ba9d8b5..23c4a525c 100644 --- a/apps/transcripts/tests/test_call.py +++ b/apps/transcripts/tests/test_call.py @@ -15,7 +15,7 @@ class TestScan: result = runner.invoke(call_app, ["transcripts", "scan", "20240101"]) assert result.exit_code == 0 assert "Transcripts:" in result.output - assert "Screen:" in result.output + assert "Percepts:" in result.output def test_scan_empty_day(self): result = runner.invoke(call_app, ["transcripts", "scan", "20990101"]) diff --git a/muse/activities.md b/muse/activities.md index fec133ea3..4d76db9f8 100644 --- a/muse/activities.md +++ b/muse/activities.md @@ -12,7 +12,7 @@ "thinking_budget": 4096, "max_output_tokens": 2048, "instructions": { - "sources": {"transcripts": false, "screen": false, "agents": false}, + "sources": {"transcripts": false, "percepts": false, "agents": false}, "facets": false } diff --git a/muse/activity.md b/muse/activity.md index fd9ea2cf5..de8f85f33 100644 --- a/muse/activity.md +++ b/muse/activity.md @@ -8,7 +8,7 @@ "priority": 10, "output": "md", "instructions": { - "sources": {"transcripts": true, "screen": true, "agents": false}, + "sources": {"transcripts": true, "percepts": true, "agents": false}, "facets": true } diff --git a/muse/activity_state.md b/muse/activity_state.md index f9d80f08c..d0cc3f1ac 100644 --- a/muse/activity_state.md +++ b/muse/activity_state.md @@ -13,7 +13,7 @@ "thinking_budget": 4096, "max_output_tokens": 3072, "instructions": { - "sources": {"transcripts": true, "screen": true, "agents": false}, + "sources": {"transcripts": true, "percepts": true, "agents": false}, "facets": true } diff --git a/muse/daily_schedule.md b/muse/daily_schedule.md index b1a3e7730..ea8701edf 100644 --- a/muse/daily_schedule.md +++ b/muse/daily_schedule.md @@ -11,7 +11,7 @@ "thinking_budget": 4096, "max_output_tokens": 512, "instructions": { - "sources": {"transcripts": true, "screen": false, "agents": {"screen": true}}, + "sources": {"transcripts": true, "percepts": false, "agents": {"screen": true}}, "facets": true } diff --git a/muse/decisions.md b/muse/decisions.md index 5b51678be..9d6b13d4f 100644 --- a/muse/decisions.md +++ b/muse/decisions.md @@ -11,7 +11,7 @@ "priority": 10, "output": "md", "instructions": { - "sources": {"transcripts": true, "screen": false, "agents": {"screen": true}}, + "sources": {"transcripts": true, "percepts": false, "agents": {"screen": true}}, "facets": true, "activity": true } diff --git a/muse/documentation.md b/muse/documentation.md index 312186e70..feaeeadcf 100644 --- a/muse/documentation.md +++ b/muse/documentation.md @@ -11,7 +11,7 @@ "disabled": true, "output": "md", "instructions": { - "sources": {"transcripts": true, "screen": false, "agents": {"screen": true}}, + "sources": {"transcripts": true, "percepts": false, "agents": {"screen": true}}, "facets": true } diff --git a/muse/entities.md b/muse/entities.md index 0124fdfa5..a00c77145 100644 --- a/muse/entities.md +++ b/muse/entities.md @@ -11,7 +11,7 @@ "max_output_tokens": 1024, "output": "md", "instructions": { - "sources": {"transcripts": true, "screen": true, "agents": false}, + "sources": {"transcripts": true, "percepts": true, "agents": false}, "facets": false } diff --git a/muse/facets.md b/muse/facets.md index acb02f0df..dfa8c0b4b 100644 --- a/muse/facets.md +++ b/muse/facets.md @@ -11,7 +11,7 @@ "max_output_tokens": 512, "output": "json", "instructions": { - "sources": {"transcripts": false, "screen": false, "agents": true}, + "sources": {"transcripts": false, "percepts": false, "agents": true}, "facets": true } diff --git a/muse/files.md b/muse/files.md index 8c9e4a467..ee9d6f7ab 100644 --- a/muse/files.md +++ b/muse/files.md @@ -11,7 +11,7 @@ "disabled": true, "output": "md", "instructions": { - "sources": {"transcripts": true, "screen": false, "agents": {"screen": true}}, + "sources": {"transcripts": true, "percepts": false, "agents": {"screen": true}}, "facets": true } diff --git a/muse/flow.md b/muse/flow.md index 399684fbf..b58efd379 100644 --- a/muse/flow.md +++ b/muse/flow.md @@ -10,7 +10,7 @@ "priority": 10, "output": "md", "instructions": { - "sources": {"transcripts": true, "screen": false, "agents": {"screen": true}}, + "sources": {"transcripts": true, "percepts": false, "agents": {"screen": true}}, "facets": true } diff --git a/muse/followups.md b/muse/followups.md index c5f2791ac..76b40f460 100644 --- a/muse/followups.md +++ b/muse/followups.md @@ -11,7 +11,7 @@ "priority": 10, "output": "md", "instructions": { - "sources": {"transcripts": true, "screen": false, "agents": {"screen": true}}, + "sources": {"transcripts": true, "percepts": false, "agents": {"screen": true}}, "facets": true, "activity": true } diff --git a/muse/knowledge_graph.md b/muse/knowledge_graph.md index eea205b2a..39ee0c5d4 100644 --- a/muse/knowledge_graph.md +++ b/muse/knowledge_graph.md @@ -10,7 +10,7 @@ "priority": 10, "output": "md", "instructions": { - "sources": {"transcripts": true, "screen": false, "agents": {"screen": true}}, + "sources": {"transcripts": true, "percepts": false, "agents": {"screen": true}}, "facets": true } diff --git a/muse/media.md b/muse/media.md index 30f4e5be6..1e8b7f656 100644 --- a/muse/media.md +++ b/muse/media.md @@ -11,7 +11,7 @@ "disabled": true, "output": "md", "instructions": { - "sources": {"transcripts": true, "screen": false, "agents": {"screen": true}}, + "sources": {"transcripts": true, "percepts": false, "agents": {"screen": true}}, "facets": true } diff --git a/muse/meetings.md b/muse/meetings.md index b09c7ffd6..230661695 100644 --- a/muse/meetings.md +++ b/muse/meetings.md @@ -11,7 +11,7 @@ "priority": 10, "output": "md", "instructions": { - "sources": {"transcripts": true, "screen": false, "agents": {"screen": true}}, + "sources": {"transcripts": true, "percepts": false, "agents": {"screen": true}}, "facets": true, "activity": true } diff --git a/muse/messaging.md b/muse/messaging.md index 490774f60..d33fa02ad 100644 --- a/muse/messaging.md +++ b/muse/messaging.md @@ -11,7 +11,7 @@ "priority": 10, "output": "md", "instructions": { - "sources": {"transcripts": true, "screen": false, "agents": {"screen": true}}, + "sources": {"transcripts": true, "percepts": false, "agents": {"screen": true}}, "facets": true, "activity": true } diff --git a/muse/observation.md b/muse/observation.md index 4b53a3fd0..99cccbe9a 100644 --- a/muse/observation.md +++ b/muse/observation.md @@ -10,7 +10,7 @@ "thinking_budget": 2048, "max_output_tokens": 2048, "instructions": { - "sources": {"transcripts": true, "screen": true, "agents": false} + "sources": {"transcripts": true, "percepts": true, "agents": false} } } diff --git a/muse/opportunities.md b/muse/opportunities.md index 7d878a6d1..b12489e6a 100644 --- a/muse/opportunities.md +++ b/muse/opportunities.md @@ -11,7 +11,7 @@ "disabled": true, "output": "md", "instructions": { - "sources": {"transcripts": true, "screen": false, "agents": {"screen": true}}, + "sources": {"transcripts": true, "percepts": false, "agents": {"screen": true}}, "facets": true } diff --git a/muse/research.md b/muse/research.md index a8f3955d2..14809e214 100644 --- a/muse/research.md +++ b/muse/research.md @@ -11,7 +11,7 @@ "disabled": true, "output": "md", "instructions": { - "sources": {"transcripts": true, "screen": false, "agents": {"screen": true}}, + "sources": {"transcripts": true, "percepts": false, "agents": {"screen": true}}, "facets": true } diff --git a/muse/schedule.md b/muse/schedule.md index a771311cf..8df985f50 100644 --- a/muse/schedule.md +++ b/muse/schedule.md @@ -9,7 +9,7 @@ "priority": 10, "output": "md", "instructions": { - "sources": {"transcripts": true, "screen": false, "agents": {"screen": true}} + "sources": {"transcripts": true, "percepts": false, "agents": {"screen": true}} } } diff --git a/muse/screen.md b/muse/screen.md index 49259f50e..7b3f1410e 100644 --- a/muse/screen.md +++ b/muse/screen.md @@ -8,7 +8,7 @@ "priority": 10, "output": "md", "instructions": { - "sources": {"transcripts": true, "screen": "required", "agents": false} + "sources": {"transcripts": true, "percepts": "required", "agents": false} } } diff --git a/muse/speakers.md b/muse/speakers.md index efc762a40..7843e5cd1 100644 --- a/muse/speakers.md +++ b/muse/speakers.md @@ -8,7 +8,7 @@ "output": "json", "color": "#e64a19", "instructions": { - "sources": {"transcripts": "required", "screen": true, "agents": false} + "sources": {"transcripts": "required", "percepts": true, "agents": false} } } diff --git a/muse/timeline.md b/muse/timeline.md index 2f51915f6..e9b006f78 100644 --- a/muse/timeline.md +++ b/muse/timeline.md @@ -10,7 +10,7 @@ "priority": 10, "output": "md", "instructions": { - "sources": {"transcripts": true, "screen": false, "agents": {"screen": true}} + "sources": {"transcripts": true, "percepts": false, "agents": {"screen": true}} } } diff --git a/muse/tools.md b/muse/tools.md index e63a92130..8fa0f0de7 100644 --- a/muse/tools.md +++ b/muse/tools.md @@ -11,7 +11,7 @@ "disabled": true, "output": "md", "instructions": { - "sources": {"transcripts": true, "screen": false, "agents": {"screen": true}}, + "sources": {"transcripts": true, "percepts": false, "agents": {"screen": true}}, "facets": true } diff --git a/tests/baselines/api/stats/stats.json b/tests/baselines/api/stats/stats.json index 03305a0bd..f8895a1b5 100644 --- a/tests/baselines/api/stats/stats.json +++ b/tests/baselines/api/stats/stats.json @@ -12,7 +12,7 @@ "facets": false, "sources": { "agents": false, - "screen": false, + "percepts": false, "transcripts": false } }, @@ -35,7 +35,7 @@ "facets": true, "sources": { "agents": false, - "screen": true, + "percepts": true, "transcripts": true } }, @@ -59,7 +59,7 @@ "facets": true, "sources": { "agents": false, - "screen": true, + "percepts": true, "transcripts": true } }, @@ -89,7 +89,7 @@ "agents": { "screen": true }, - "screen": false, + "percepts": false, "transcripts": true } }, @@ -120,7 +120,7 @@ "agents": { "screen": true }, - "screen": false, + "percepts": false, "transcripts": true } }, @@ -144,7 +144,7 @@ "facets": false, "sources": { "agents": false, - "screen": true, + "percepts": true, "transcripts": true } }, @@ -166,7 +166,7 @@ "facets": true, "sources": { "agents": true, - "screen": false, + "percepts": false, "transcripts": false } }, @@ -194,7 +194,7 @@ "agents": { "screen": true }, - "screen": false, + "percepts": false, "transcripts": true } }, @@ -224,7 +224,7 @@ "agents": { "screen": true }, - "screen": false, + "percepts": false, "transcripts": true } }, @@ -250,7 +250,7 @@ "agents": { "screen": true }, - "screen": false, + "percepts": false, "transcripts": true } }, @@ -280,7 +280,7 @@ "agents": { "screen": true }, - "screen": false, + "percepts": false, "transcripts": true } }, @@ -311,7 +311,7 @@ "agents": { "screen": true }, - "screen": false, + "percepts": false, "transcripts": true } }, @@ -335,7 +335,7 @@ "instructions": { "sources": { "agents": false, - "screen": true, + "percepts": true, "transcripts": true } }, @@ -362,7 +362,7 @@ "agents": { "screen": true }, - "screen": false, + "percepts": false, "transcripts": true } }, @@ -381,7 +381,7 @@ "instructions": { "sources": { "agents": false, - "screen": "required", + "percepts": "required", "transcripts": true } }, @@ -400,7 +400,7 @@ "instructions": { "sources": { "agents": false, - "screen": true, + "percepts": true, "transcripts": "required" } }, @@ -424,7 +424,7 @@ "agents": { "screen": true }, - "screen": false, + "percepts": false, "transcripts": true } }, diff --git a/tests/baselines/api/todos/badge-count.json b/tests/baselines/api/todos/badge-count.json index 03d0b2009..633d47a56 100644 --- a/tests/baselines/api/todos/badge-count.json +++ b/tests/baselines/api/todos/badge-count.json @@ -1,3 +1,3 @@ { - "count": 4 + "count": 0 } diff --git a/tests/baselines/api/todos/nudges.json b/tests/baselines/api/todos/nudges.json index 15a86c251..fd19100c4 100644 --- a/tests/baselines/api/todos/nudges.json +++ b/tests/baselines/api/todos/nudges.json @@ -1,3 +1,18 @@ { - "nudges": [] + "nudges": [ + { + "day": "20260308", + "facet": "montague", + "index": 2, + "nudge": "20260309T09:00", + "text": "Recruit Benvolio for infrastructure support" + }, + { + "day": "20260308", + "facet": "verona", + "index": 2, + "nudge": "20260309T09:00", + "text": "Prepare working demo for board meeting" + } + ] } diff --git a/tests/baselines/api/transcripts/segments.json b/tests/baselines/api/transcripts/segments.json index 3f665f5ab..20a177388 100644 --- a/tests/baselines/api/transcripts/segments.json +++ b/tests/baselines/api/transcripts/segments.json @@ -7,7 +7,7 @@ "stream": "default", "types": [ "transcripts", - "screen" + "percepts" ] }, { @@ -17,7 +17,7 @@ "stream": "default", "types": [ "transcripts", - "screen" + "percepts" ] }, { @@ -27,7 +27,7 @@ "stream": "default", "types": [ "transcripts", - "screen" + "percepts" ] } ] diff --git a/tests/test_cluster.py b/tests/test_cluster.py index b5c5fe3d3..be8145102 100644 --- a/tests/test_cluster.py +++ b/tests/test_cluster.py @@ -25,7 +25,7 @@ def test_cluster(tmp_path, monkeypatch): "screen summary" ) result, counts = mod.cluster( - "20240101", sources={"transcripts": True, "screen": False, "agents": True} + "20240101", sources={"transcripts": True, "percepts": False, "agents": True} ) assert counts["transcripts"] == 1 assert counts["agents"] == 1 @@ -55,7 +55,7 @@ def test_cluster_range(tmp_path, monkeypatch): "20240101", "120000", "120100", - sources={"transcripts": True, "screen": False, "agents": True}, + sources={"transcripts": True, "percepts": False, "agents": True}, ) # Check that the function works and includes expected sections assert "### Transcript" in md @@ -141,13 +141,13 @@ def test_cluster_segments(tmp_path, monkeypatch): assert segments[1]["start"] == "10:00" assert segments[1]["end"] == "10:10" assert "transcripts" in segments[1]["types"] - assert "screen" in segments[1]["types"] + assert "percepts" in segments[1]["types"] # Check third segment (screen only) assert segments[2]["key"] == "110000_300" assert segments[2]["start"] == "11:00" assert segments[2]["end"] == "11:05" - assert segments[2]["types"] == ["screen"] + assert segments[2]["types"] == ["percepts"] def test_cluster_period_uses_raw_screen(tmp_path, monkeypatch): @@ -176,12 +176,12 @@ def test_cluster_period_uses_raw_screen(tmp_path, monkeypatch): result, counts = mod.cluster_period( "20240101", "100000_300", - sources={"transcripts": True, "screen": True, "agents": False}, + sources={"transcripts": True, "percepts": True, "agents": False}, ) # Should have both transcript and screen entries assert counts["transcripts"] == 1 - assert counts["screen"] == 1 + assert counts["percepts"] == 1 assert "### Transcript" in result # Should use raw screen format header assert "Screen Activity" in result @@ -218,7 +218,7 @@ def test_cluster_range_with_agents(tmp_path, monkeypatch): "20240101", "100000", "100500", - sources={"transcripts": True, "screen": False, "agents": True}, + sources={"transcripts": True, "percepts": False, "agents": True}, ) assert "### Transcript" in result @@ -253,7 +253,7 @@ def test_cluster_range_with_screen(tmp_path, monkeypatch): "20240101", "100000", "100500", - sources={"transcripts": False, "screen": True, "agents": False}, + sources={"transcripts": False, "percepts": True, "agents": False}, ) assert "Screen Activity" in result @@ -289,7 +289,7 @@ def test_cluster_range_with_multiple_screen_files(tmp_path, monkeypatch): "20240101", "100000", "100500", - sources={"transcripts": False, "screen": True, "agents": False}, + sources={"transcripts": False, "percepts": True, "agents": False}, ) # Should include content from both screen files @@ -333,7 +333,7 @@ def test_cluster_segments_with_split_screen(tmp_path, monkeypatch): assert len(segments) == 1 assert segments[0]["key"] == "100000_300" - assert "screen" in segments[0]["types"] + assert "percepts" in segments[0]["types"] def test_cluster_span(tmp_path, monkeypatch): @@ -367,12 +367,12 @@ def test_cluster_span(tmp_path, monkeypatch): result, counts = mod.cluster_span( "20240101", ["090000_300", "110000_300"], - sources={"transcripts": True, "screen": False, "agents": False}, + sources={"transcripts": True, "percepts": False, "agents": False}, ) # Should have 2 transcript entries (one per segment) assert counts["transcripts"] == 2 - assert counts["screen"] == 0 + assert counts["percepts"] == 0 assert "morning segment" in result assert "late morning segment" in result # Should NOT include the skipped segment @@ -398,7 +398,7 @@ def test_cluster_span_missing_segment(tmp_path, monkeypatch): mod.cluster_span( "20240101", ["090000_300", "100000_300"], - sources={"transcripts": True, "screen": False, "agents": False}, + sources={"transcripts": True, "percepts": False, "agents": False}, ) assert "100000_300" in str(exc_info.value) @@ -424,7 +424,7 @@ def test_cluster_with_agent_filter_dict(tmp_path, monkeypatch): # Test filtering to only include entities result, counts = mod.cluster( "20240101", - sources={"transcripts": True, "screen": False, "agents": {"entities": True}}, + sources={"transcripts": True, "percepts": False, "agents": {"entities": True}}, ) assert counts["transcripts"] == 1 @@ -455,7 +455,7 @@ def test_cluster_with_agent_filter_multiple(tmp_path, monkeypatch): "20240101", sources={ "transcripts": True, - "screen": False, + "percepts": False, "agents": {"entities": True, "meetings": "required", "flow": False}, }, ) @@ -488,7 +488,7 @@ def test_cluster_with_agent_filter_app_namespaced(tmp_path, monkeypatch): "20240101", sources={ "transcripts": True, - "screen": False, + "percepts": False, "agents": {"entities": False, "todos:review": True}, }, ) @@ -515,7 +515,7 @@ def test_cluster_with_empty_agent_filter(tmp_path, monkeypatch): # Empty dict should mean no agents result, counts = mod.cluster( "20240101", - sources={"transcripts": True, "screen": False, "agents": {}}, + sources={"transcripts": True, "percepts": False, "agents": {}}, ) assert counts["transcripts"] == 1 diff --git a/tests/test_cluster_full.py b/tests/test_cluster_full.py index 49797e04a..55f626da5 100644 --- a/tests/test_cluster_full.py +++ b/tests/test_cluster_full.py @@ -29,7 +29,7 @@ def test_cluster_full(tmp_path, monkeypatch): copy_day(tmp_path) monkeypatch.setenv("JOURNAL_PATH", str(tmp_path)) md, counts = mod.cluster( - "20240101", sources={"transcripts": True, "screen": False, "agents": True} + "20240101", sources={"transcripts": True, "percepts": False, "agents": True} ) # Transcript entries come from 2 segments on 20240101 (default + import.apple) assert counts["transcripts"] == 2 @@ -45,7 +45,7 @@ def test_cluster_default_sources(tmp_path, monkeypatch): copy_day(tmp_path) monkeypatch.setenv("JOURNAL_PATH", str(tmp_path)) out, _counts = mod.cluster( - "20240101", sources={"transcripts": True, "screen": False, "agents": True} + "20240101", sources={"transcripts": True, "percepts": False, "agents": True} ) # Now uses insight format: "### {stem} summary" assert "### screen summary" in out @@ -59,7 +59,7 @@ def test_cluster_range_raw_screen(tmp_path, monkeypatch): "20240101", "123456", "123556", - sources={"transcripts": True, "screen": True, "agents": False}, + sources={"transcripts": True, "percepts": True, "agents": False}, ) # Range mode with screen=True uses raw screen data. assert "### Screen Activity" in out diff --git a/tests/test_generate_full.py b/tests/test_generate_full.py index 221abfcd4..f0f205d15 100644 --- a/tests/test_generate_full.py +++ b/tests/test_generate_full.py @@ -79,7 +79,7 @@ def test_generate_output_ndjson(tmp_path, monkeypatch): test_generator = tmp_path / "test_gen.md" test_generator.write_text( - '{\n "type": "generate",\n "schedule": "daily",\n "priority": 10,\n "output": "md",\n "instructions": {"system": "journal", "sources": {"audio": true, "screen": true}}\n}\n\nTest prompt' + '{\n "type": "generate",\n "schedule": "daily",\n "priority": 10,\n "output": "md",\n "instructions": {"system": "journal", "sources": {"transcripts": true, "percepts": true}}\n}\n\nTest prompt' ) # Mock the underlying generation function in think.models @@ -146,7 +146,7 @@ def post_process(result, context): test_generator = tmp_path / "hooked_gen.md" test_generator.write_text( - '{\n "type": "generate",\n "title": "Hooked",\n "schedule": "daily",\n "priority": 10,\n "output": "md",\n "hook": {"post": "test_hook"},\n "instructions": {"system": "journal", "sources": {"audio": true, "screen": true}}\n}\n\nTest prompt' + '{\n "type": "generate",\n "title": "Hooked",\n "schedule": "daily",\n "priority": 10,\n "output": "md",\n "hook": {"post": "test_hook"},\n "instructions": {"system": "journal", "sources": {"transcripts": true, "percepts": true}}\n}\n\nTest prompt' ) # Mock the underlying generation function in think.models @@ -198,7 +198,7 @@ def test_generate_without_hook_succeeds(tmp_path, monkeypatch): test_generator = tmp_path / "nohook_gen.md" test_generator.write_text( - '{\n "type": "generate",\n "schedule": "daily",\n "priority": 10,\n "output": "md",\n "instructions": {"system": "journal", "sources": {"audio": true, "screen": true}}\n}\n\nNo hook prompt' + '{\n "type": "generate",\n "schedule": "daily",\n "priority": 10,\n "output": "md",\n "instructions": {"system": "journal", "sources": {"transcripts": true, "percepts": true}}\n}\n\nNo hook prompt' ) # Mock the underlying generation function in think.models @@ -265,7 +265,7 @@ def test_generate_skipped_on_no_input(tmp_path, monkeypatch): test_generator = tmp_path / "empty_gen.md" test_generator.write_text( - '{\n "type": "generate",\n "schedule": "daily",\n "priority": 10,\n "output": "md",\n "instructions": {"system": "journal", "sources": {"audio": true, "screen": true}}\n}\n\nTest prompt' + '{\n "type": "generate",\n "schedule": "daily",\n "priority": 10,\n "output": "md",\n "instructions": {"system": "journal", "sources": {"transcripts": true, "percepts": true}}\n}\n\nTest prompt' ) monkeypatch.setenv("GOOGLE_API_KEY", "x") diff --git a/tests/test_generators.py b/tests/test_generators.py index 5d9143a49..5cfc86172 100644 --- a/tests/test_generators.py +++ b/tests/test_generators.py @@ -135,7 +135,7 @@ def test_speakers_has_required_audio(): sources = instructions.get("sources", {}) assert sources.get("transcripts") == "required", "speakers should require transcripts" - assert sources.get("screen") is True, "speakers should include screen" + assert sources.get("percepts") is True, "speakers should include percepts" def _write_temp_muse_prompt(stem: str, frontmatter: str) -> Path: diff --git a/tests/test_journal_stats.py b/tests/test_journal_stats.py index c67efb839..b202ca364 100644 --- a/tests/test_journal_stats.py +++ b/tests/test_journal_stats.py @@ -172,7 +172,7 @@ def test_token_usage(tmp_path, monkeypatch): assert "token_usage_by_day" in data assert "token_totals_by_model" in data assert "total_transcript_duration" in data - assert "total_screen_duration" in data + assert "total_percept_duration" in data assert ( data["token_usage_by_day"]["20240101"]["gemini-2.5-flash"]["total_tokens"] == 495 diff --git a/tests/test_muse.py b/tests/test_muse.py index d98ba02c9..cb7755678 100644 --- a/tests/test_muse.py +++ b/tests/test_muse.py @@ -39,11 +39,11 @@ def test_merge_instructions_config_with_overrides(): def test_merge_instructions_config_sources_merge(): """Test that sources dict is merged, not replaced.""" - defaults = {"system": None, "sources": {"transcripts": False, "screen": False}} + defaults = {"system": None, "sources": {"transcripts": False, "percepts": False}} overrides = {"sources": {"transcripts": True}} result = _merge_instructions_config(defaults, overrides) assert result["sources"]["transcripts"] is True # Overridden - assert result["sources"]["screen"] is False # Preserved from defaults + assert result["sources"]["percepts"] is False # Preserved from defaults def test_merge_instructions_config_ignores_unknown_keys(): @@ -236,7 +236,7 @@ class TestComposeInstructions: assert "sources" in result assert result["sources"]["transcripts"] is False - assert result["sources"]["screen"] is False + assert result["sources"]["percepts"] is False assert result["sources"]["agents"] is False def test_sources_can_be_overridden(self, monkeypatch, tmp_path): @@ -256,7 +256,7 @@ class TestComposeInstructions: ) assert result["sources"]["transcripts"] is True # Overridden - assert result["sources"]["screen"] is False # Default preserved + assert result["sources"]["percepts"] is False # Default preserved assert result["sources"]["agents"] is True # Overridden diff --git a/tests/test_output_hooks.py b/tests/test_output_hooks.py index 9768bb88f..075ddad52 100644 --- a/tests/test_output_hooks.py +++ b/tests/test_output_hooks.py @@ -170,7 +170,7 @@ def test_output_hook_invocation(tmp_path, monkeypatch): prompt_file = tmp_path / "hooked_test.md" prompt_file.write_text( - '{\n "type": "generate",\n "title": "Hooked",\n "schedule": "daily",\n "priority": 10,\n "output": "md",\n "hook": {"post": "hooked_test"},\n "instructions": {"system": "journal", "sources": {"audio": true, "screen": true}}\n}\n\nTest prompt' + '{\n "type": "generate",\n "title": "Hooked",\n "schedule": "daily",\n "priority": 10,\n "output": "md",\n "hook": {"post": "hooked_test"},\n "instructions": {"system": "journal", "sources": {"transcripts": true, "percepts": true}}\n}\n\nTest prompt' ) hook_file = tmp_path / "hooked_test.py" @@ -224,7 +224,7 @@ def test_output_hook_returns_none(tmp_path, monkeypatch): prompt_file = tmp_path / "noop_test.md" prompt_file.write_text( - '{\n "type": "generate",\n "title": "Noop",\n "schedule": "daily",\n "priority": 10,\n "output": "md",\n "hook": {"post": "noop_test"},\n "instructions": {"system": "journal", "sources": {"audio": true, "screen": true}}\n}\n\nTest prompt' + '{\n "type": "generate",\n "title": "Noop",\n "schedule": "daily",\n "priority": 10,\n "output": "md",\n "hook": {"post": "noop_test"},\n "instructions": {"system": "journal", "sources": {"transcripts": true, "percepts": true}}\n}\n\nTest prompt' ) hook_file = tmp_path / "noop_test.py" @@ -270,7 +270,7 @@ def test_output_hook_error_fallback(tmp_path, monkeypatch): prompt_file = tmp_path / "broken_test.md" prompt_file.write_text( - '{\n "type": "generate",\n "title": "Broken",\n "schedule": "daily",\n "priority": 10,\n "output": "md",\n "hook": {"post": "broken_test"},\n "instructions": {"system": "journal", "sources": {"audio": true, "screen": true}}\n}\n\nTest prompt' + '{\n "type": "generate",\n "title": "Broken",\n "schedule": "daily",\n "priority": 10,\n "output": "md",\n "hook": {"post": "broken_test"},\n "instructions": {"system": "journal", "sources": {"transcripts": true, "percepts": true}}\n}\n\nTest prompt' ) hook_file = tmp_path / "broken_test.py" @@ -387,7 +387,7 @@ def test_pre_hook_invocation(tmp_path, monkeypatch): prompt_file = tmp_path / "prehooked_test.md" prompt_file.write_text( - '{\n "type": "generate",\n "title": "Prehooked",\n "schedule": "daily",\n "priority": 10,\n "output": "md",\n "hook": {"pre": "prehooked_test"},\n "instructions": {"system": "journal", "sources": {"audio": true, "screen": true}}\n}\n\nOriginal prompt' + '{\n "type": "generate",\n "title": "Prehooked",\n "schedule": "daily",\n "priority": 10,\n "output": "md",\n "hook": {"pre": "prehooked_test"},\n "instructions": {"system": "journal", "sources": {"transcripts": true, "percepts": true}}\n}\n\nOriginal prompt' ) hook_file = tmp_path / "prehooked_test.py" @@ -447,7 +447,7 @@ def test_both_pre_and_post_hooks(tmp_path, monkeypatch): prompt_file = tmp_path / "both_hooks_test.md" prompt_file.write_text( - '{\n "type": "generate",\n "title": "Both Hooks",\n "schedule": "daily",\n "priority": 10,\n "output": "md",\n "hook": {"pre": "both_hooks_test", "post": "both_hooks_test"},\n "instructions": {"system": "journal", "sources": {"audio": true, "screen": true}}\n}\n\nOriginal prompt' + '{\n "type": "generate",\n "title": "Both Hooks",\n "schedule": "daily",\n "priority": 10,\n "output": "md",\n "hook": {"pre": "both_hooks_test", "post": "both_hooks_test"},\n "instructions": {"system": "journal", "sources": {"transcripts": true, "percepts": true}}\n}\n\nOriginal prompt' ) hook_file = tmp_path / "both_hooks_test.py" diff --git a/think/cluster.py b/think/cluster.py index 61c3ae0bf..97f4c63c5 100644 --- a/think/cluster.py +++ b/think/cluster.py @@ -94,7 +94,7 @@ def _process_segment( segment_path: Path, date_str: str, transcripts: bool, - screen: bool, + percepts: bool, agents: bool | dict[str, bool | str], ) -> list[dict[str, Any]]: """Process a single segment directory and return entries. @@ -103,7 +103,7 @@ def _process_segment( segment_path: Path to segment directory date_str: Date in YYYYMMDD format transcripts: Whether to load transcript content (JSONL and markdown) - screen: Whether to load raw screen data from *screen.jsonl files + percepts: Whether to load raw screen data from *screen.jsonl files agents: Whether to load agent output summaries from *.md files. Can be bool (all/none) or dict for selective filtering (e.g., {"entities": True, "meetings": "required"}). @@ -187,7 +187,7 @@ def _process_segment( ) # Process raw screen data from screen.jsonl and *_screen.jsonl - if screen: + if percepts: screen_files = list(segment_path.glob("*screen.jsonl")) for screen_jsonl in screen_files: try: @@ -199,7 +199,7 @@ def _process_segment( "segment_key": segment_key, "segment_start": segment_start, "segment_end": segment_end, - "prefix": "screen", + "prefix": "percept", "content": content, "name": f"{segment_path.name}/{screen_jsonl.name}", "stream": stream, @@ -254,7 +254,7 @@ def _process_segment( def _load_entries( - day_dir: str, transcripts: bool, screen: bool, agents: bool | dict[str, bool | str] + day_dir: str, transcripts: bool, percepts: bool, agents: bool | dict[str, bool | str] ) -> list[dict[str, Any]]: """Load all transcript entries from a day directory.""" from think.utils import segment_parse @@ -269,7 +269,7 @@ def _load_entries( start_time, _ = segment_parse(seg_path.name) if not start_time: continue - entries.extend(_process_segment(seg_path, date_str, transcripts, screen, agents)) + entries.extend(_process_segment(seg_path, date_str, transcripts, percepts, agents)) entries.sort(key=lambda e: e["timestamp"]) return entries @@ -293,16 +293,16 @@ def _count_by_source(entries: list[dict[str, Any]]) -> dict[str, int]: Maps the internal prefix names to source config names: - "transcript" -> "transcripts" - - "screen" -> "screen" + - "percept" -> "percepts" - "agent_output" -> "agents" Returns: - Dict with counts for each source type, e.g., {"transcripts": 2, "screen": 1, "agents": 0} + Dict with counts for each source type, e.g., {"transcripts": 2, "percepts": 1, "agents": 0} """ # Map internal prefix to source config name prefix_to_source = { "transcript": "transcripts", - "screen": "screen", + "percept": "percepts", "agent_output": "agents", } @@ -311,7 +311,7 @@ def _count_by_source(entries: list[dict[str, Any]]) -> dict[str, int]: # Ensure all standard sources are present (even if 0) return { "transcripts": counts.get("transcripts", 0), - "screen": counts.get("screen", 0), + "percepts": counts.get("percepts", 0), "agents": counts.get("agents", 0), } @@ -344,7 +344,7 @@ def _groups_to_markdown(groups: dict[str, list[dict[str, Any]]]) -> str: lines.append(f"### {header}") lines.append(entry["content"].strip()) lines.append("") - elif entry["prefix"] == "screen": + elif entry["prefix"] == "percept": lines.append("### Screen Activity") lines.append(entry["content"].strip()) lines.append("") @@ -407,7 +407,7 @@ def cluster_scan(day: str) -> tuple[list[tuple[str, str]], list[tuple[str, str]] date_str = _date_str(day_dir) transcript_slots: set[datetime] = set() - screen_slots: set[datetime] = set() + percept_slots: set[datetime] = set() day_path_obj = Path(day_dir) # Check timestamp subdirectories for content files @@ -437,11 +437,11 @@ def cluster_scan(day: str) -> tuple[list[tuple[str, str]], list[tuple[str, str]] if (seg_path / "screen.jsonl").exists() or any( seg_path.glob("*_screen.jsonl") ): - screen_slots.add(slot) + percept_slots.add(slot) transcript_ranges = _slots_to_ranges(sorted(transcript_slots)) - screen_ranges = _slots_to_ranges(sorted(screen_slots)) - return transcript_ranges, screen_ranges + percept_ranges = _slots_to_ranges(sorted(percept_slots)) + return transcript_ranges, percept_ranges def cluster_segments(day: str) -> list[dict[str, Any]]: @@ -458,7 +458,7 @@ def cluster_segments(day: str) -> list[dict[str, Any]]: - key: segment directory name (HHMMSS_LEN format) - start: start time as HH:MM - end: end time as HH:MM - - types: list of content types present ("transcripts", "screen", or both) + - types: list of content types present ("transcripts", "percepts", or both) """ from think.utils import segment_parse @@ -489,7 +489,7 @@ def cluster_segments(day: str) -> list[dict[str, Any]]: # Check for screen content if (seg_path / "screen.jsonl").exists() or any(seg_path.glob("*_screen.jsonl")): - types.append("screen") + types.append("percepts") if not types: continue @@ -546,14 +546,14 @@ def cluster( Args: day: Day in YYYYMMDD format - sources: Dict with keys "transcripts", "screen", "agents". + sources: Dict with keys "transcripts", "percepts", "agents". Values can be bool, "required" string, or dict (for agents). The "agents" source can be a dict for selective filtering, e.g., {"entities": True, "meetings": "required"}. Returns: Tuple of (markdown, source_counts) where source_counts is a dict - with keys "transcripts", "screen", "agents" mapping to entry counts. + with keys "transcripts", "percepts", "agents" mapping to entry counts. """ empty_counts = {"transcripts": 0, "screen": 0, "agents": 0} @@ -565,7 +565,7 @@ def cluster( entries = _load_entries( day_dir, transcripts=sources.get("transcripts", False), - screen=sources.get("screen", False), + percepts=sources.get("percepts", False), agents=sources.get("agents", False), ) if not entries: @@ -590,13 +590,13 @@ def cluster_period( Args: day: Day in YYYYMMDD format segment: Segment key in HHMMSS_LEN format (e.g., "163045_300") - sources: Dict with keys "transcripts", "screen", "agents". + sources: Dict with keys "transcripts", "percepts", "agents". Values can be bool, "required" string, or dict (for agents). stream: Stream name. If None, searches all streams for the segment. Returns: Tuple of (markdown, source_counts) where source_counts is a dict - with keys "transcripts", "screen", "agents" mapping to entry counts. + with keys "transcripts", "percepts", "agents" mapping to entry counts. """ empty_counts = {"transcripts": 0, "screen": 0, "agents": 0} @@ -608,7 +608,7 @@ def cluster_period( entries = _load_entries_from_segment( str(segment_dir), transcripts=sources.get("transcripts", False), - screen=sources.get("screen", False), + percepts=sources.get("percepts", False), agents=sources.get("agents", False), ) if not entries: @@ -622,7 +622,7 @@ def cluster_period( def _load_entries_from_segment( segment_dir: str, transcripts: bool, - screen: bool, + percepts: bool, agents: bool | dict[str, bool | str], ) -> list[dict[str, Any]]: """Load entries from a single segment directory. @@ -630,7 +630,7 @@ def _load_entries_from_segment( Args: segment_dir: Path to segment directory (e.g., /path/to/20251109/163045_300) transcripts: Whether to load transcript content (JSONL and markdown) - screen: Whether to load raw screen data from *screen.jsonl files + percepts: Whether to load raw screen data from *screen.jsonl files agents: Whether to load agent output summaries from *.md files Returns: @@ -639,7 +639,7 @@ def _load_entries_from_segment( segment_path_obj = Path(segment_dir) # Parent is stream dir; grandparent is day dir date_str = _date_str(str(segment_path_obj.parent.parent)) - entries = _process_segment(segment_path_obj, date_str, transcripts, screen, agents) + entries = _process_segment(segment_path_obj, date_str, transcripts, percepts, agents) entries.sort(key=lambda e: e["timestamp"]) return entries @@ -660,13 +660,13 @@ def cluster_span( Args: day: Day in YYYYMMDD format span: List of segment keys in HHMMSS_LEN format (e.g., ["163045_300", "170000_600"]) - sources: Dict with keys "transcripts", "screen", "agents". + sources: Dict with keys "transcripts", "percepts", "agents". Values can be bool, "required" string, or dict (for agents). stream: Stream name. If None, searches all streams for each segment. Returns: Tuple of (markdown, source_counts) where source_counts is a dict - with keys "transcripts", "screen", "agents" mapping to entry counts. + with keys "transcripts", "percepts", "agents" mapping to entry counts. Raises: ValueError: If any segment directories are missing @@ -692,7 +692,7 @@ def cluster_span( segment_entries = _load_entries_from_segment( str(seg_dir), transcripts=sources.get("transcripts", False), - screen=sources.get("screen", False), + percepts=sources.get("percepts", False), agents=sources.get("agents", False), ) entries.extend(segment_entries) @@ -735,7 +735,7 @@ def cluster_range( day: Day in YYYYMMDD format start: Start time in HHMMSS format end: End time in HHMMSS format - sources: Dict with keys "transcripts", "screen", "agents". + sources: Dict with keys "transcripts", "percepts", "agents". Values can be bool, "required" string, or dict (for agents). """ day_dir = str(day_path(day)) @@ -746,7 +746,7 @@ def cluster_range( entries = _load_entries( day_dir, transcripts=sources.get("transcripts", False), - screen=sources.get("screen", False), + percepts=sources.get("percepts", False), agents=sources.get("agents", False), ) # Include segments that overlap with the requested range diff --git a/think/journal_stats.py b/think/journal_stats.py index 2c1a1e784..f35205b53 100644 --- a/think/journal_stats.py +++ b/think/journal_stats.py @@ -23,7 +23,7 @@ class JournalStats: self.days: Dict[str, Dict[str, float | int]] = {} self.totals: Counter[str] = Counter() self.total_transcript_duration = 0.0 - self.total_screen_duration = 0.0 + self.total_percept_duration = 0.0 self.agent_counts: Counter[str] = Counter() self.agent_minutes: Counter[str] = Counter() self.facet_counts: Counter[str] = Counter() @@ -107,7 +107,7 @@ class JournalStats: times_seconds = [self._parse_timestamp(t) for t in timestamps] return max(times_seconds) - min(times_seconds) - def _calculate_screen_duration(self, frames: list) -> float: + def _calculate_percept_duration(self, frames: list) -> float: """Calculate screen duration from min/max frame timestamps.""" # Skip header (first element if it has no frame_id) frame_timestamps = [ @@ -132,13 +132,13 @@ class JournalStats: counts_for_totals = { k: v for k, v in stats.items() - if k not in ("transcript_duration", "screen_duration") + if k not in ("transcript_duration", "percept_duration") } self.totals.update(counts_for_totals) # Accumulate durations self.total_transcript_duration += stats.get("transcript_duration", 0.0) - self.total_screen_duration += stats.get("screen_duration", 0.0) + self.total_percept_duration += stats.get("percept_duration", 0.0) # Apply agent data day_agent_counts: Dict[str, int] = {} @@ -175,7 +175,7 @@ class JournalStats: """Scan a single day and return stats dict for caching.""" stats: Counter[str] = Counter() transcript_duration = 0.0 - screen_duration = 0.0 + percept_duration = 0.0 day_dir = Path(path) # Track agent data for cache @@ -225,7 +225,7 @@ class JournalStats: screen_files = list(day_dir.glob("*/*/screen.jsonl")) screen_files.extend(day_dir.glob("*/*/*_screen.jsonl")) for jsonl_file in sorted(screen_files): - stats["screen_sessions"] += 1 + stats["percept_sessions"] += 1 try: frames = load_analysis_frames(jsonl_file) @@ -235,12 +235,12 @@ class JournalStats: # Count frames (excluding header) frame_count = sum(1 for f in frames if "frame_id" in f) - stats["screen_frames"] += frame_count + stats["percept_frames"] += frame_count # Calculate duration from timestamps if frame_count > 0: - duration = self._calculate_screen_duration(frames) - screen_duration += duration + duration = self._calculate_percept_duration(frames) + percept_duration += duration except (OSError, IOError) as e: logger.warning(f"Error reading screen file {jsonl_file}: {e}") @@ -328,7 +328,7 @@ class JournalStats: # --- Build return dict --- stats["transcript_duration"] = transcript_duration - stats["screen_duration"] = screen_duration + stats["percept_duration"] = percept_duration return { "stats": dict(stats), @@ -460,7 +460,7 @@ class JournalStats: logger.info( f"Scanned {len(self.days)} days, " f"{self.totals.get('transcript_sessions', 0)} transcript sessions, " - f"{self.totals.get('screen_sessions', 0)} screen sessions" + f"{self.totals.get('percept_sessions', 0)} percept sessions" f"{cache_status}" ) @@ -470,7 +470,7 @@ class JournalStats: "days": self.days, "totals": dict(self.totals), "total_transcript_duration": self.total_transcript_duration, - "total_screen_duration": self.total_screen_duration, + "total_percept_duration": self.total_percept_duration, "agent_counts": dict(self.agent_counts), "agent_minutes": {k: round(v, 2) for k, v in self.agent_minutes.items()}, "agent_counts_by_day": self.agent_counts_by_day, diff --git a/think/muse.py b/think/muse.py index 600109867..e3cd6f4f0 100644 --- a/think/muse.py +++ b/think/muse.py @@ -335,7 +335,7 @@ _DEFAULT_INSTRUCTIONS = { "activity": False, "sources": { "transcripts": False, - "screen": False, + "percepts": False, "agents": False, }, } @@ -431,7 +431,7 @@ def compose_instructions( true = include current date/time in extra_context - "day": false | true (default: false) true = include analysis day context (requires analysis_day parameter) - - "sources": {"transcripts": bool, "screen": bool, "agents": bool|dict} + - "sources": {"transcripts": bool, "percepts": bool, "agents": bool|dict} The "agents" source can be: - bool: True (all agents), False (no agents) - "required": all agents, fail if none found @@ -445,7 +445,7 @@ def compose_instructions( - system_prompt_name: str - name of system prompt (for cache keys) - user_instruction: str | None - loaded from user_prompt if provided - extra_context: str | None - facets + now + day context - - sources: dict - {"transcripts": bool, "screen": bool, "agents": bool|dict} + - sources: dict - {"transcripts": bool, "percepts": bool, "agents": bool|dict} """ from think.utils import format_day -- 2.51.2