personal memory agent
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Fix remaining insight terminology missed in initial refactor

Audit of the unify-agents refactor found additional occurrences that
needed updating:

- tests/test_app_generators.py: context="insight.test" → "agent.test"
- think/entities/activity.py: docstring "insight" → "output"
- think/runner.py: example and comment "sol insight" → "sol generate"
- think/importer.py: docstrings and log messages updated
- think/models.py: comment and docstring examples updated
- think/formatters.py: apps/*/insights/ → apps/*/agents/ for consistency
- tests/test_journal_index.py: test path updated
- tests/test_importer.py: docstrings updated
- docs/PROVIDERS.md: context pattern reference updated
- scripts/migrate_insights_to_agents.py: added Step 3 for app directories

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

+310 -72
+1 -1
docs/PROVIDERS.md
··· 251 251 252 252 These are discovered at runtime and merged with static defaults. Use `get_context_registry()` to get the complete context map including discovered entries. 253 253 254 - See `CONTEXT_DEFAULTS` in `think/models.py` for static context patterns (non-discoverable contexts like `observe.detect.*`, `insight.*`). 254 + See `CONTEXT_DEFAULTS` in `think/models.py` for static context patterns (non-discoverable contexts like `observe.detect.*`, `agent.*`). 255 255 256 256 **Resolution** (handled by `think/models.py` `resolve_provider()`): 257 257 1. Exact match in journal.json `providers.contexts`
fixtures/journal/20240101/insights/flow.md fixtures/journal/20240101/agents/flow.md
fixtures/journal/20240101/insights/meetings.md fixtures/journal/20240101/agents/meetings.md
fixtures/journal/20240102/insights/flow.md fixtures/journal/20240102/agents/flow.md
+246
scripts/migrate_insights_to_agents.py
··· 1 + #!/usr/bin/env python3 2 + # SPDX-License-Identifier: AGPL-3.0-only 3 + # Copyright (c) 2026 sol pbc 4 + 5 + """Migrate journal from insights/ to agents/ directory structure. 6 + 7 + This script performs the following migrations: 8 + 1. Renames YYYYMMDD/insights/ -> YYYYMMDD/agents/ for all day directories 9 + 2. Updates config/journal.json: "insights" key -> "agents" key 10 + 3. Updates source paths in facets/*/events/*.jsonl files 11 + 12 + Usage: 13 + python scripts/migrate_insights_to_agents.py [--journal PATH] [--dry-run] 14 + 15 + Options: 16 + --journal PATH Path to journal directory (default: JOURNAL_PATH env or .env) 17 + --dry-run Show what would be done without making changes 18 + """ 19 + 20 + import argparse 21 + import json 22 + import os 23 + import re 24 + import sys 25 + from pathlib import Path 26 + 27 + 28 + def load_env_journal_path() -> str | None: 29 + """Load JOURNAL_PATH from .env file if present.""" 30 + env_file = Path(".env") 31 + if env_file.exists(): 32 + for line in env_file.read_text().splitlines(): 33 + if line.startswith("JOURNAL_PATH="): 34 + return line.split("=", 1)[1].strip().strip('"').strip("'") 35 + return None 36 + 37 + 38 + def get_journal_path(args_path: str | None) -> Path: 39 + """Resolve journal path from args, env, or .env file.""" 40 + if args_path: 41 + return Path(args_path) 42 + if os.environ.get("JOURNAL_PATH"): 43 + return Path(os.environ["JOURNAL_PATH"]) 44 + env_path = load_env_journal_path() 45 + if env_path: 46 + return Path(env_path) 47 + print("ERROR: No journal path specified. Use --journal or set JOURNAL_PATH.") 48 + sys.exit(1) 49 + 50 + 51 + def is_day_directory(name: str) -> bool: 52 + """Check if directory name is YYYYMMDD format.""" 53 + return bool(re.match(r"^\d{8}$", name)) 54 + 55 + 56 + def migrate_day_directories(journal: Path, dry_run: bool) -> int: 57 + """Rename insights/ -> agents/ in all day directories. 58 + 59 + Returns count of directories renamed. 60 + """ 61 + count = 0 62 + for day_dir in sorted(journal.iterdir()): 63 + if not day_dir.is_dir() or not is_day_directory(day_dir.name): 64 + continue 65 + 66 + insights_dir = day_dir / "insights" 67 + agents_dir = day_dir / "agents" 68 + 69 + if insights_dir.is_dir() and not agents_dir.exists(): 70 + if dry_run: 71 + print(f" [DRY-RUN] Would rename: {insights_dir} -> {agents_dir}") 72 + else: 73 + insights_dir.rename(agents_dir) 74 + print(f" Renamed: {insights_dir} -> {agents_dir}") 75 + count += 1 76 + elif insights_dir.is_dir() and agents_dir.exists(): 77 + print(f" WARNING: Both insights/ and agents/ exist in {day_dir.name}") 78 + 79 + return count 80 + 81 + 82 + def migrate_config(journal: Path, dry_run: bool) -> bool: 83 + """Update config/journal.json: "insights" key -> "agents" key. 84 + 85 + Returns True if config was updated. 86 + """ 87 + config_file = journal / "config" / "journal.json" 88 + if not config_file.exists(): 89 + return False 90 + 91 + try: 92 + config = json.loads(config_file.read_text()) 93 + except json.JSONDecodeError as e: 94 + print(f" WARNING: Could not parse config file: {e}") 95 + return False 96 + 97 + if "insights" not in config: 98 + return False 99 + 100 + if "agents" in config: 101 + print(" WARNING: Both 'insights' and 'agents' keys exist in config") 102 + return False 103 + 104 + if dry_run: 105 + print(f" [DRY-RUN] Would update config: 'insights' -> 'agents'") 106 + else: 107 + config["agents"] = config.pop("insights") 108 + config_file.write_text(json.dumps(config, indent=2) + "\n") 109 + print(f" Updated config: 'insights' -> 'agents'") 110 + 111 + return True 112 + 113 + 114 + def migrate_app_directories(journal: Path, dry_run: bool) -> int: 115 + """Rename apps/*/insights/ -> apps/*/agents/ for app-specific outputs. 116 + 117 + Returns count of directories renamed. 118 + """ 119 + apps_dir = journal / "apps" 120 + if not apps_dir.is_dir(): 121 + return 0 122 + 123 + count = 0 124 + for app_dir in sorted(apps_dir.iterdir()): 125 + if not app_dir.is_dir(): 126 + continue 127 + 128 + insights_dir = app_dir / "insights" 129 + agents_dir = app_dir / "agents" 130 + 131 + if insights_dir.is_dir() and not agents_dir.exists(): 132 + if dry_run: 133 + print(f" [DRY-RUN] Would rename: {insights_dir} -> {agents_dir}") 134 + else: 135 + insights_dir.rename(agents_dir) 136 + print(f" Renamed: {insights_dir} -> {agents_dir}") 137 + count += 1 138 + elif insights_dir.is_dir() and agents_dir.exists(): 139 + print(f" WARNING: Both insights/ and agents/ exist in apps/{app_dir.name}") 140 + 141 + return count 142 + 143 + 144 + def migrate_event_sources(journal: Path, dry_run: bool) -> int: 145 + """Update source paths in facets/*/events/*.jsonl files. 146 + 147 + Changes "YYYYMMDD/insights/..." -> "YYYYMMDD/agents/..." 148 + 149 + Returns count of files updated. 150 + """ 151 + facets_dir = journal / "facets" 152 + if not facets_dir.is_dir(): 153 + return 0 154 + 155 + count = 0 156 + pattern = re.compile(r'("source":\s*")(\d{8})/insights/') 157 + 158 + for facet_dir in sorted(facets_dir.iterdir()): 159 + if not facet_dir.is_dir(): 160 + continue 161 + 162 + events_dir = facet_dir / "events" 163 + if not events_dir.is_dir(): 164 + continue 165 + 166 + for jsonl_file in sorted(events_dir.glob("*.jsonl")): 167 + content = jsonl_file.read_text() 168 + if "/insights/" not in content: 169 + continue 170 + 171 + new_content = pattern.sub(r"\g<1>\g<2>/agents/", content) 172 + if new_content != content: 173 + if dry_run: 174 + print(f" [DRY-RUN] Would update sources in: {jsonl_file}") 175 + else: 176 + jsonl_file.write_text(new_content) 177 + print(f" Updated sources in: {jsonl_file}") 178 + count += 1 179 + 180 + return count 181 + 182 + 183 + def main(): 184 + parser = argparse.ArgumentParser( 185 + description="Migrate journal from insights/ to agents/ directory structure." 186 + ) 187 + parser.add_argument( 188 + "--journal", 189 + type=str, 190 + help="Path to journal directory (default: JOURNAL_PATH env or .env)", 191 + ) 192 + parser.add_argument( 193 + "--dry-run", 194 + action="store_true", 195 + help="Show what would be done without making changes", 196 + ) 197 + args = parser.parse_args() 198 + 199 + journal = get_journal_path(args.journal) 200 + if not journal.is_dir(): 201 + print(f"ERROR: Journal directory does not exist: {journal}") 202 + sys.exit(1) 203 + 204 + print(f"Migrating journal: {journal}") 205 + if args.dry_run: 206 + print("DRY-RUN MODE: No changes will be made\n") 207 + 208 + # Step 1: Rename day directories 209 + print("\nStep 1: Renaming insights/ -> agents/ in day directories...") 210 + day_count = migrate_day_directories(journal, args.dry_run) 211 + print( 212 + f" Total: {day_count} directories {'would be ' if args.dry_run else ''}renamed" 213 + ) 214 + 215 + # Step 2: Update config 216 + print("\nStep 2: Updating config/journal.json...") 217 + config_updated = migrate_config(journal, args.dry_run) 218 + if not config_updated: 219 + print(" No config changes needed") 220 + 221 + # Step 3: Rename app directories 222 + print("\nStep 3: Renaming insights/ -> agents/ in app directories...") 223 + app_count = migrate_app_directories(journal, args.dry_run) 224 + print( 225 + f" Total: {app_count} directories {'would be ' if args.dry_run else ''}renamed" 226 + ) 227 + 228 + # Step 4: Update event sources 229 + print("\nStep 4: Updating source paths in event files...") 230 + event_count = migrate_event_sources(journal, args.dry_run) 231 + print(f" Total: {event_count} files {'would be ' if args.dry_run else ''}updated") 232 + 233 + # Summary 234 + print("\n" + "=" * 50) 235 + if args.dry_run: 236 + print("DRY-RUN COMPLETE - no changes were made") 237 + else: 238 + print("MIGRATION COMPLETE") 239 + print(f" - {day_count} day directories renamed") 240 + print(f" - {app_count} app directories renamed") 241 + print(f" - Config {'updated' if config_updated else 'unchanged'}") 242 + print(f" - {event_count} event files updated") 243 + 244 + 245 + if __name__ == "__main__": 246 + main()
+1 -1
tests/test_app_insights.py tests/test_app_generators.py
··· 55 55 assert callable(routes.get_usage_cost) 56 56 57 57 # Verify it returns expected structure for non-existent day 58 - result = routes.get_usage_cost("19000101", context="insight.test") 58 + result = routes.get_usage_cost("19000101", context="agent.test") 59 59 assert "cost" in result 60 60 assert "requests" in result 61 61 assert "tokens" in result
tests/test_get_insights.py tests/test_generators.py
+3 -3
tests/test_importer.py
··· 246 246 247 247 248 248 def test_run_import_summary(tmp_path, monkeypatch): 249 - """Test _run_import_summary calls sol insight correctly.""" 249 + """Test _run_import_summary calls sol generate correctly.""" 250 250 mod = importlib.import_module("think.importer") 251 251 252 252 import_dir = tmp_path / "imports" / "20240101_120000" 253 253 import_dir.mkdir(parents=True) 254 254 255 - # Mock subprocess.run to simulate successful sol insight 255 + # Mock subprocess.run to simulate successful sol generate 256 256 def mock_run(cmd, *args, **kwargs): 257 - # Create the summary file like sol insight would 257 + # Create the summary file like sol generate would 258 258 summary_path = import_dir / "summary.md" 259 259 summary_path.write_text("# Test Summary\n\nContent here.") 260 260 mock_result = MagicMock()
tests/test_insight_full.py tests/test_generate_full.py
tests/test_insight_hooks.py tests/test_output_hooks.py
tests/test_insight_scan_day.py tests/test_generate_scan_day.py
+27 -29
tests/test_journal_index.py
··· 81 81 # Create daily insight 82 82 day = journal / "20240101" 83 83 day.mkdir() 84 - insights_dir = day / "insights" 85 - insights_dir.mkdir() 86 - (insights_dir / "flow.md").write_text( 87 - "# Flow Summary\n\nWorked on project alpha.\n" 88 - ) 84 + agents_dir = day / "agents" 85 + agents_dir.mkdir() 86 + (agents_dir / "flow.md").write_text("# Flow Summary\n\nWorked on project alpha.\n") 89 87 90 88 # Create segment with audio transcript 91 89 segment = day / "100000_300" ··· 149 147 assert index_path.exists() 150 148 151 149 152 - def test_search_journal_insights(journal_fixture): 153 - """Test searching returns insight chunks.""" 150 + def test_search_journal_outputs(journal_fixture): 151 + """Test searching returns agent output chunks.""" 154 152 from think.indexer.journal import scan_journal, search_journal 155 153 156 154 scan_journal(str(journal_fixture)) 157 155 158 156 total, results = search_journal("project alpha") 159 157 assert total >= 1 160 - # Should find the flow insight mentioning "project alpha" 158 + # Should find the flow output mentioning "project alpha" 161 159 found = any("alpha" in r["text"].lower() for r in results) 162 160 assert found 163 161 ··· 304 302 # Non-day paths are never historical 305 303 assert _is_historical_day("facets/work/events/20240101.jsonl") is False 306 304 assert _is_historical_day("imports/123/summary.md") is False 307 - assert _is_historical_day("apps/home/insights/foo.md") is False 305 + assert _is_historical_day("apps/home/agents/foo.md") is False 308 306 309 307 # Future dates are not historical 310 - assert _is_historical_day("29991231/insights/flow.md") is False 308 + assert _is_historical_day("29991231/agents/flow.md") is False 311 309 312 310 # Path without slash is not historical 313 311 assert _is_historical_day("20240101") is False 314 312 assert _is_historical_day("") is False 315 313 316 314 # Day paths before today are historical (tested with a very old date) 317 - assert _is_historical_day("20000101/insights/flow.md") is True 315 + assert _is_historical_day("20000101/agents/flow.md") is True 318 316 319 317 320 318 def test_scan_journal_full_mode(journal_fixture): ··· 339 337 # Should find various file types 340 338 paths = set(files.keys()) 341 339 342 - # Daily insights 343 - assert "20240101/insights/flow.md" in paths 340 + # Daily agent outputs 341 + assert "20240101/agents/flow.md" in paths 344 342 345 343 # Segment content 346 344 assert "20240101/100000_300/screen.md" in paths ··· 543 541 today = datetime.now().strftime("%Y%m%d") 544 542 day_dir = journal / today 545 543 day_dir.mkdir() 546 - insights_dir = day_dir / "insights" 547 - insights_dir.mkdir() 548 - insight_file = insights_dir / "flow.md" 549 - insight_file.write_text("# Today Flow\n\nWorked on unique_today_content.\n") 544 + agents_dir = day_dir / "agents" 545 + agents_dir.mkdir() 546 + output_file = agents_dir / "flow.md" 547 + output_file.write_text("# Today Flow\n\nWorked on unique_today_content.\n") 550 548 551 549 # Initial scan 552 550 scan_journal(str(journal), full=False) ··· 555 553 total, _ = search_journal("unique_today_content") 556 554 assert total >= 1 557 555 558 - # Delete the insight file 559 - insight_file.unlink() 556 + # Delete the output file 557 + output_file.unlink() 560 558 561 559 # Light rescan should detect the deletion 562 560 changed = scan_journal(str(journal), full=False) ··· 577 575 # Create historical day content 578 576 day_dir = journal / "20200101" 579 577 day_dir.mkdir() 580 - insights_dir = day_dir / "insights" 581 - insights_dir.mkdir() 582 - insight_file = insights_dir / "flow.md" 583 - insight_file.write_text("# Historical Flow\n\nWorked on historical_content.\n") 578 + agents_dir = day_dir / "agents" 579 + agents_dir.mkdir() 580 + output_file = agents_dir / "flow.md" 581 + output_file.write_text("# Historical Flow\n\nWorked on historical_content.\n") 584 582 585 583 # Full scan to index historical content 586 584 scan_journal(str(journal), full=True) ··· 590 588 assert total >= 1 591 589 592 590 # Delete the historical file 593 - insight_file.unlink() 591 + output_file.unlink() 594 592 595 593 # Light rescan should NOT remove the historical content (out of scope) 596 594 changed = scan_journal(str(journal), full=False) ··· 612 610 # Create historical day content 613 611 day_dir = journal / "20200101" 614 612 day_dir.mkdir() 615 - insights_dir = day_dir / "insights" 616 - insights_dir.mkdir() 617 - insight_file = insights_dir / "flow.md" 618 - insight_file.write_text("# Historical Flow\n\nWorked on historical_full_test.\n") 613 + agents_dir = day_dir / "agents" 614 + agents_dir.mkdir() 615 + output_file = agents_dir / "flow.md" 616 + output_file.write_text("# Historical Flow\n\nWorked on historical_full_test.\n") 619 617 620 618 # Full scan to index historical content 621 619 scan_journal(str(journal), full=True) ··· 625 623 assert total >= 1 626 624 627 625 # Delete the historical file 628 - insight_file.unlink() 626 + output_file.unlink() 629 627 630 628 # Full rescan SHOULD remove the historical content 631 629 changed = scan_journal(str(journal), full=True)
+2 -2
think/entities/activity.py
··· 66 66 def parse_knowledge_graph_entities(day: str) -> list[str]: 67 67 """Parse entity names from a day's knowledge graph. 68 68 69 - Extracts entity names from markdown tables in the knowledge graph insight. 69 + Extracts entity names from markdown tables in the knowledge graph output. 70 70 Entity names appear in bold (**Name**) in the first column of tables. 71 71 72 72 Args: ··· 81 81 ["Jeremie Miller (Jer)", "Neal Satterfield", "Flightline", ...] 82 82 """ 83 83 journal = get_journal() 84 - kg_path = Path(journal) / day / "insights" / "knowledge_graph.md" 84 + kg_path = Path(journal) / day / "agents" / "knowledge_graph.md" 85 85 86 86 if not kg_path.exists(): 87 87 return []
+16 -16
think/formatters.py
··· 57 57 by the formatter via meta["indexer"]["topic"]. 58 58 59 59 Args: 60 - rel_path: Journal-relative path (e.g., "20240101/insights/flow.md") 60 + rel_path: Journal-relative path (e.g., "20240101/agents/flow.md") 61 61 62 62 Returns: 63 63 Dict with keys: day, facet, topic ··· 104 104 elif parts[0] == "apps" and len(parts) >= 4: 105 105 topic = f"{parts[1]}:{basename}" 106 106 else: 107 - # Daily insights, segment markdown: use basename 107 + # Daily agent outputs, segment markdown: use basename 108 108 topic = basename 109 109 110 110 return {"day": day, "facet": facet, "topic": topic} ··· 127 127 "*/*_audio.jsonl": ("observe.hear", "format_audio"), 128 128 "*/audio.jsonl": ("observe.hear", "format_audio"), 129 129 # Markdown formatter (semantic chunking) 130 - "**/*.md": ("think.insights", "format_insight"), 130 + "**/*.md": ("think.outputs", "format_markdown"), 131 131 } 132 132 133 133 ··· 205 205 be included in the journal index. Excludes agents/*.jsonl. 206 206 207 207 Locations scanned: 208 - - Daily insights: YYYYMMDD/insights/*.md 208 + - Daily agent outputs: YYYYMMDD/agents/*.md 209 209 - Segment content: YYYYMMDD/HHMMSS*/*.md, *.jsonl 210 210 - Facet content: facets/*/events/*.jsonl, entities/, todos/, news/, logs/ 211 211 - Import summaries: imports/*/summary.md 212 - - App insights: apps/*/insights/*.md 212 + - App agent outputs: apps/*/agents/*.md 213 213 214 214 Args: 215 215 journal: Path to journal root directory ··· 224 224 for day, day_abs in day_dirs().items(): 225 225 day_path = Path(day_abs) 226 226 227 - # Daily insights: YYYYMMDD/insights/*.md 228 - insights_dir = day_path / "insights" 229 - if insights_dir.is_dir(): 230 - for md_file in insights_dir.glob("*.md"): 231 - rel = f"{day}/insights/{md_file.name}" 227 + # Daily agent outputs: YYYYMMDD/agents/*.md 228 + agents_dir = day_path / "agents" 229 + if agents_dir.is_dir(): 230 + for md_file in agents_dir.glob("*.md"): 231 + rel = f"{day}/agents/{md_file.name}" 232 232 files[rel] = str(md_file) 233 233 234 234 # Segment content: YYYYMMDD/HHMMSS_LEN/* ··· 310 310 rel = f"imports/{import_dir.name}/summary.md" 311 311 files[rel] = str(summary_file) 312 312 313 - # App insights: apps/*/insights/*.md 313 + # App agent outputs: apps/*/agents/*.md 314 314 apps_dir = journal_path / "apps" 315 315 if apps_dir.is_dir(): 316 316 for app_dir in apps_dir.iterdir(): 317 317 if not app_dir.is_dir(): 318 318 continue 319 - app_insights_dir = app_dir / "insights" 320 - if app_insights_dir.is_dir(): 321 - for md_file in app_insights_dir.glob("*.md"): 322 - rel = f"apps/{app_dir.name}/insights/{md_file.name}" 319 + app_agents_dir = app_dir / "agents" 320 + if app_agents_dir.is_dir(): 321 + for md_file in app_agents_dir.glob("*.md"): 322 + rel = f"apps/{app_dir.name}/agents/{md_file.name}" 323 323 files[rel] = str(md_file) 324 324 325 325 return files ··· 456 456 # For summary format on markdown files, get raw chunks with metadata 457 457 raw_chunks = None 458 458 if args.format == "summary" and args.file.endswith(".md"): 459 - from think.insights import chunk_markdown 459 + from think.outputs import chunk_markdown 460 460 461 461 text = load_markdown(args.file) 462 462 raw_chunks = chunk_markdown(text)
+3 -3
think/importer.py
··· 440 440 day: str, 441 441 segments: list[str], 442 442 ) -> bool: 443 - """Create a summary for imported segments using sol insight. 443 + """Create a summary for imported segments using sol generate. 444 444 445 445 Args: 446 446 import_dir: Directory where the summary will be saved ··· 470 470 ] 471 471 472 472 try: 473 - logger.info(f"Creating summary for {len(segments)} segments via sol insight") 473 + logger.info(f"Creating summary for {len(segments)} segments via sol generate") 474 474 subprocess.run(cmd, capture_output=True, text=True, check=True) 475 475 if summary_path.exists(): 476 476 logger.info(f"Created import summary: {summary_path}") 477 477 return True 478 478 else: 479 - logger.warning("sol insight completed but summary file not created") 479 + logger.warning("sol generate completed but summary file not created") 480 480 return False 481 481 except subprocess.CalledProcessError as e: 482 482 logger.error(f"Failed to create summary: {e.stderr}")
think/insight.py think/generate.py
think/insights.py think/outputs.py
+9 -15
think/models.py
··· 108 108 # Examples: 109 109 # - observe.describe.frame -> observe module, describe feature, frame operation 110 110 # - observe.enrich -> observe module, enrich feature (no sub-operation) 111 - # - insight.* -> insight module, all features (wildcard) 111 + # - agent.* -> agent module, all features (wildcard) 112 112 # - app.chat.title -> apps module, chat app, title operation 113 113 # 114 114 # DYNAMIC DISCOVERY: ··· 169 169 "label": "Summarization", 170 170 "group": "Import", 171 171 }, 172 - # Insight pipeline - daily analysis and summaries 173 - "insight.entities.*": { 172 + # Generator pipeline - daily analysis and summaries 173 + "agent.entities.*": { 174 174 "tier": TIER_LITE, 175 175 "label": "Entity Extraction", 176 176 "group": "Think", 177 177 }, 178 - "insight.*": { 178 + "agent.*": { 179 179 "tier": TIER_FLASH, 180 - "label": "Daily Insights", 180 + "label": "Agent Outputs", 181 181 "group": "Think", 182 182 }, 183 183 # Utilities - miscellaneous processing tasks ··· 197 197 "label": "Chat Title Generation", 198 198 "group": "Apps", 199 199 }, 200 - # Fallback for agents without explicit tier in their JSON 201 - "agent.*": { 202 - "tier": TIER_FLASH, 203 - "label": "Other Agents", 204 - "group": "Agents", 205 - }, 206 200 } 207 201 208 202 ··· 346 340 Parameters 347 341 ---------- 348 342 context 349 - Context string (e.g., "agent.system.default", "insight.meetings"). 343 + Context string (e.g., "agent.system.default", "agent.meetings"). 350 344 351 345 Returns 352 346 ------- ··· 473 467 Parameters 474 468 ---------- 475 469 context 476 - Context string (e.g., "observe.describe.frame", "insight.meetings"). 470 + Context string (e.g., "observe.describe.frame", "agent.meetings"). 477 471 478 472 Returns 479 473 ------- ··· 961 955 contents : str or List 962 956 The content to send to the model. 963 957 context : str 964 - Context string for routing and token logging (e.g., "insight.meetings"). 958 + Context string for routing and token logging (e.g., "agent.meetings"). 965 959 This is required and determines which provider/model to use. 966 960 temperature : float 967 961 Temperature for generation (default: 0.3). ··· 1046 1040 contents : str or List 1047 1041 The content to send to the model. 1048 1042 context : str 1049 - Context string for routing and token logging (e.g., "insight.meetings"). 1043 + Context string for routing and token logging (e.g., "agent.meetings"). 1050 1044 This is required and determines which provider/model to use. 1051 1045 temperature : float 1052 1046 Temperature for generation (default: 0.3).
think/resources/insights.py think/resources/outputs.py
+2 -2
think/runner.py
··· 443 443 444 444 Example: 445 445 success, code = run_task( 446 - ["sol", "insight", "20241101", "-f", "flow"], 446 + ["sol", "generate", "20241101", "-f", "flow"], 447 447 timeout=300, 448 448 ) 449 - # Logs to: {JOURNAL}/{YYYYMMDD}/health/{ref}_insight.log 449 + # Logs to: {JOURNAL}/{YYYYMMDD}/health/{ref}_generate.log 450 450 451 451 # With explicit correlation ID: 452 452 success, code = run_task(
think/templates/daily_insight.md think/templates/daily_preamble.md
think/templates/segment_insight.md think/templates/segment_preamble.md