personal memory agent
0

Configure Feed

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

solstone / tests / test_cogitate_contract.py
6.3 kB 194 lines
1# SPDX-License-Identifier: AGPL-3.0-only 2# Copyright (c) 2026 sol pbc 3 4from pathlib import Path 5 6import pytest 7 8from solstone.think import cogitate_contract 9from solstone.think.cogitate_contract import ( 10 COGITATE_ACCESS_TIERS, 11 COGITATE_DIAGNOSTIC_PREAMBLE, 12 COGITATE_READ_TOOL_NAMES, 13 COGITATE_RUNTIME_PREAMBLE, 14 FUTURE_ACCESS_TIERS, 15 TALENT_ACCESS_TIERS, 16 TALENT_FINALIZATION_MODES, 17 expects_emit_final, 18) 19from solstone.think.providers.cli import assemble_prompt 20 21 22def test_cogitate_preamble_injected_with_and_without_system_instruction(): 23 _, system = assemble_prompt({"system_instruction": "X"}, sol_tool_name="sol") 24 assert system is not None 25 assert system.startswith(COGITATE_RUNTIME_PREAMBLE) 26 27 _, system = assemble_prompt({}, sol_tool_name="sol") 28 assert system is not None 29 assert system.startswith(COGITATE_RUNTIME_PREAMBLE) 30 31 32def test_cogitate_preamble_ordering_with_scope_hint(): 33 _, system = assemble_prompt( 34 {"system_instruction": "X", "read_scope": ["c"]}, 35 sol_tool_name="sol", 36 ) 37 38 assert system is not None 39 assert system.startswith(COGITATE_RUNTIME_PREAMBLE) 40 assert ( 41 system.index(COGITATE_RUNTIME_PREAMBLE.rstrip("\n")) 42 < system.index("X") 43 < system.index("through the `sol` tool") 44 < system.index("Limit filesystem reads to today's segment dir") 45 ) 46 47 48def test_non_cogitate_prompt_omits_preamble(): 49 _, system = assemble_prompt({"system_instruction": "X"}, sol_tool_name=None) 50 51 assert system == "X" 52 assert COGITATE_RUNTIME_PREAMBLE not in system 53 54 55def test_prompt_body_unchanged_under_cogitate_injection(): 56 body, _ = assemble_prompt( 57 { 58 "transcript": "t", 59 "extra_context": "e", 60 "user_instruction": "u", 61 "prompt": "p", 62 "system_instruction": "X", 63 }, 64 sol_tool_name="sol", 65 ) 66 67 assert body == "t\n\ne\n\nu\n\np" 68 69 70def test_cogitate_vocabulary_lock(): 71 assert COGITATE_ACCESS_TIERS == ( 72 "normal", 73 "system-read", 74 "outbound", 75 "synthesis", 76 "diagnostic", 77 ) 78 assert COGITATE_READ_TOOL_NAMES == ( 79 "read_file", 80 "list_directory", 81 "glob", 82 "grep_search", 83 ) 84 assert FUTURE_ACCESS_TIERS == ("code-agent",) 85 assert TALENT_ACCESS_TIERS == ( 86 "normal", 87 "system-read", 88 "outbound", 89 "synthesis", 90 ) 91 assert TALENT_FINALIZATION_MODES == ("emit_final", "FinishTool", "quiet") 92 assert "repair" not in COGITATE_ACCESS_TIERS 93 assert "repair" not in FUTURE_ACCESS_TIERS 94 95 96def test_access_tier_capability_mapping_matches_vocabulary(): 97 assert set(cogitate_contract._ACCESS_TIER_CAPABILITIES) == set( 98 COGITATE_ACCESS_TIERS 99 ) 100 101 102@pytest.mark.parametrize( 103 ("config", "expected"), 104 [ 105 ({"output_path": "/tmp/out.md"}, True), 106 ({"schedule": "daily"}, True), 107 ({"schedule": "weekly"}, True), 108 ({"schedule": "activity"}, True), 109 ({"diagnostic": True}, True), 110 ({"diagnostic": False}, False), 111 ({"schedule": "segment"}, False), 112 ({"schedule": "none"}, False), 113 ({}, False), 114 ], 115) 116def test_expects_emit_final(config, expected): 117 assert expects_emit_final(config) is expected 118 119 120@pytest.mark.parametrize( 121 ("tier", "expected"), 122 [ 123 ("normal", (True, True, False)), 124 ("system-read", (True, True, False)), 125 ("outbound", (True, False, True)), 126 ("synthesis", (True, False, False)), 127 ("diagnostic", (False, False, False)), 128 ], 129) 130def test_capabilities_for_access_tier_real_tiers(tier, expected): 131 caps = cogitate_contract.capabilities_for_access_tier(tier) 132 133 assert (caps.sol, caps.reads, caps.submit) == expected 134 135 136def test_outbound_tier_has_no_read_tools(): 137 assert cogitate_contract.capabilities_for_access_tier("outbound").reads is False 138 139 140@pytest.mark.parametrize("tier", ["repair", "code-agent", "bogus"]) 141def test_capabilities_for_access_tier_unknown_names_tier(tier): 142 with pytest.raises(ValueError, match=tier): 143 cogitate_contract.capabilities_for_access_tier(tier) 144 145 146def test_cogitate_runtime_preamble_content_guard(): 147 assert "sol call ..." in COGITATE_RUNTIME_PREAMBLE 148 assert "single parsed command-line invocation" in COGITATE_RUNTIME_PREAMBLE 149 assert "journal root" in COGITATE_RUNTIME_PREAMBLE 150 assert "node_modules" in COGITATE_RUNTIME_PREAMBLE 151 assert "emit_final" in COGITATE_RUNTIME_PREAMBLE 152 assert "finish tool" in COGITATE_RUNTIME_PREAMBLE 153 154 155def test_diagnostic_preamble_omits_journal_tooling(): 156 _, system = assemble_prompt( 157 {"system_instruction": "X", "read_scope": ["chronicle/<day>"]}, 158 sol_tool_name="sol", 159 diagnostic=True, 160 ) 161 162 assert system is not None 163 assert system.startswith(COGITATE_DIAGNOSTIC_PREAMBLE) 164 assert "emit_final" in system 165 assert "X" in system 166 assert "read_file" not in system 167 assert "grep_search" not in system 168 assert "through the `sol` tool" not in system 169 assert "Limit filesystem reads" not in system 170 assert "through a `sol` domain command" in COGITATE_RUNTIME_PREAMBLE 171 assert "no MCP tools" in COGITATE_RUNTIME_PREAMBLE 172 assert "no bare `journal ...` commands" in COGITATE_RUNTIME_PREAMBLE 173 assert "no shell composition" in COGITATE_RUNTIME_PREAMBLE 174 assert "read_file" in COGITATE_RUNTIME_PREAMBLE 175 assert "list_directory" in COGITATE_RUNTIME_PREAMBLE 176 assert "glob" in COGITATE_RUNTIME_PREAMBLE 177 assert "grep_search" in COGITATE_RUNTIME_PREAMBLE 178 assert "when this run provides a read tool" not in COGITATE_RUNTIME_PREAMBLE 179 180 181def test_cogitate_doc_preamble_block_matches_source_constant(): 182 docs_path = Path(__file__).resolve().parents[1] / "docs" / "COGITATE.md" 183 text = docs_path.read_text(encoding="utf-8") 184 heading = "## The in-context preamble (named source constant)" 185 _, heading_found, tail = text.partition(heading) 186 assert heading_found 187 _, verbatim_found, tail = tail.partition("verbatim text:") 188 assert verbatim_found 189 _, fence_found, tail = tail.partition("```\n") 190 assert fence_found 191 block, closing_fence, _tail = tail.partition("\n```") 192 assert closing_fence 193 194 assert block == COGITATE_RUNTIME_PREAMBLE.rstrip("\n")