code-puppy 0.0.90__py3-none-any.whl → 0.0.92__py3-none-any.whl
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.
- code_puppy/agent.py +1 -0
- code_puppy/main.py +8 -3
- code_puppy/message_history_processor.py +7 -9
- code_puppy/status_display.py +12 -1
- code_puppy/token_utils.py +9 -10
- code_puppy/tools/common.py +0 -1
- code_puppy/tools/file_operations.py +3 -5
- {code_puppy-0.0.90.dist-info → code_puppy-0.0.92.dist-info}/METADATA +1 -2
- {code_puppy-0.0.90.dist-info → code_puppy-0.0.92.dist-info}/RECORD +13 -13
- {code_puppy-0.0.90.data → code_puppy-0.0.92.data}/data/code_puppy/models.json +0 -0
- {code_puppy-0.0.90.dist-info → code_puppy-0.0.92.dist-info}/WHEEL +0 -0
- {code_puppy-0.0.90.dist-info → code_puppy-0.0.92.dist-info}/entry_points.txt +0 -0
- {code_puppy-0.0.90.dist-info → code_puppy-0.0.92.dist-info}/licenses/LICENSE +0 -0
    
        code_puppy/agent.py
    CHANGED
    
    
    
        code_puppy/main.py
    CHANGED
    
    | @@ -1,7 +1,6 @@ | |
| 1 1 | 
             
            import argparse
         | 
| 2 2 | 
             
            import asyncio
         | 
| 3 3 | 
             
            import os
         | 
| 4 | 
            -
            import random
         | 
| 5 4 | 
             
            import sys
         | 
| 6 5 |  | 
| 7 6 | 
             
            from dotenv import load_dotenv
         | 
| @@ -23,11 +22,11 @@ from code_puppy.status_display import StatusDisplay | |
| 23 22 | 
             
            # Initialize rich console for pretty output
         | 
| 24 23 | 
             
            from code_puppy.tools.common import console
         | 
| 25 24 | 
             
            from code_puppy.version_checker import fetch_latest_version
         | 
| 26 | 
            -
            from code_puppy.message_history_processor import message_history_processor | 
| 25 | 
            +
            from code_puppy.message_history_processor import message_history_processor
         | 
| 27 26 |  | 
| 28 27 |  | 
| 29 28 | 
             
            # from code_puppy.tools import *  # noqa: F403
         | 
| 30 | 
            -
             | 
| 29 | 
            +
            import logfire
         | 
| 31 30 |  | 
| 32 31 | 
             
            # Define a function to get the secret file path
         | 
| 33 32 | 
             
            def get_secret_file_path():
         | 
| @@ -39,7 +38,13 @@ def get_secret_file_path(): | |
| 39 38 |  | 
| 40 39 | 
             
            async def main():
         | 
| 41 40 | 
             
                # Ensure the config directory and puppy.cfg with name info exist (prompt user if needed)
         | 
| 41 | 
            +
                logfire.configure(
         | 
| 42 | 
            +
                    token="pylf_v1_us_8G5nLznQtHMRsL4hsNG5v3fPWKjyXbysrMgrQ1bV1wRP",
         | 
| 43 | 
            +
                    console=False
         | 
| 44 | 
            +
                )
         | 
| 45 | 
            +
                logfire.instrument_pydantic_ai()
         | 
| 42 46 | 
             
                ensure_config_exists()
         | 
| 47 | 
            +
             | 
| 43 48 | 
             
                current_version = __version__
         | 
| 44 49 | 
             
                latest_version = fetch_latest_version("code-puppy")
         | 
| 45 50 | 
             
                console.print(f"Current version: {current_version}")
         | 
| @@ -4,7 +4,6 @@ import os | |
| 4 4 | 
             
            from pathlib import Path
         | 
| 5 5 |  | 
| 6 6 | 
             
            import pydantic
         | 
| 7 | 
            -
            import tiktoken
         | 
| 8 7 | 
             
            from pydantic_ai.messages import (
         | 
| 9 8 | 
             
                ModelMessage,
         | 
| 10 9 | 
             
                TextPart,
         | 
| @@ -16,6 +15,7 @@ from pydantic_ai.messages import ( | |
| 16 15 | 
             
            from code_puppy.tools.common import console
         | 
| 17 16 | 
             
            from code_puppy.model_factory import ModelFactory
         | 
| 18 17 | 
             
            from code_puppy.config import get_model_name
         | 
| 18 | 
            +
            from code_puppy.token_utils import estimate_tokens
         | 
| 19 19 |  | 
| 20 20 | 
             
            # Import the status display to get token rate info
         | 
| 21 21 | 
             
            try:
         | 
| @@ -46,12 +46,12 @@ except ImportError: | |
| 46 46 | 
             
                    return None
         | 
| 47 47 |  | 
| 48 48 |  | 
| 49 | 
            +
            # Dummy function for backward compatibility
         | 
| 49 50 | 
             
            def get_tokenizer_for_model(model_name: str):
         | 
| 50 51 | 
             
                """
         | 
| 51 | 
            -
                 | 
| 52 | 
            -
                This is a simple approach that works reasonably well for most models.
         | 
| 52 | 
            +
                Dummy function that returns None since we're now using len/4 heuristic.
         | 
| 53 53 | 
             
                """
         | 
| 54 | 
            -
                return  | 
| 54 | 
            +
                return None
         | 
| 55 55 |  | 
| 56 56 |  | 
| 57 57 | 
             
            def stringify_message_part(part) -> str:
         | 
| @@ -96,17 +96,15 @@ def stringify_message_part(part) -> str: | |
| 96 96 |  | 
| 97 97 | 
             
            def estimate_tokens_for_message(message: ModelMessage) -> int:
         | 
| 98 98 | 
             
                """
         | 
| 99 | 
            -
                Estimate the number of tokens in a message using  | 
| 100 | 
            -
                This is  | 
| 99 | 
            +
                Estimate the number of tokens in a message using the len/4 heuristic.
         | 
| 100 | 
            +
                This is a simple approximation that works reasonably well for most text.
         | 
| 101 101 | 
             
                """
         | 
| 102 | 
            -
                tokenizer = get_tokenizer_for_model(get_model_name())
         | 
| 103 102 | 
             
                total_tokens = 0
         | 
| 104 103 |  | 
| 105 104 | 
             
                for part in message.parts:
         | 
| 106 105 | 
             
                    part_str = stringify_message_part(part)
         | 
| 107 106 | 
             
                    if part_str:
         | 
| 108 | 
            -
                         | 
| 109 | 
            -
                        total_tokens += len(tokens)
         | 
| 107 | 
            +
                        total_tokens += estimate_tokens(part_str)
         | 
| 110 108 |  | 
| 111 109 | 
             
                return max(1, total_tokens)
         | 
| 112 110 |  | 
    
        code_puppy/status_display.py
    CHANGED
    
    | @@ -104,9 +104,13 @@ class StatusDisplay: | |
| 104 104 |  | 
| 105 105 | 
             
                def update_token_count(self, tokens: int) -> None:
         | 
| 106 106 | 
             
                    """Update the token count and recalculate the rate"""
         | 
| 107 | 
            +
                    # Reset timing if this is the first update of a new task
         | 
| 107 108 | 
             
                    if self.start_time is None:
         | 
| 108 109 | 
             
                        self.start_time = time.time()
         | 
| 109 110 | 
             
                        self.last_update_time = self.start_time
         | 
| 111 | 
            +
                        # Reset token counters for new task
         | 
| 112 | 
            +
                        self.last_token_count = 0
         | 
| 113 | 
            +
                        self.current_rate = 0.0
         | 
| 110 114 |  | 
| 111 115 | 
             
                    # Allow for incremental updates (common for streaming) or absolute updates
         | 
| 112 116 | 
             
                    if tokens > self.token_count or tokens < 0:
         | 
| @@ -204,6 +208,13 @@ class StatusDisplay: | |
| 204 208 | 
             
                        avg_rate = self.token_count / elapsed if elapsed > 0 else 0
         | 
| 205 209 | 
             
                        self.console.print(f"[dim]Completed: {self.token_count} tokens in {elapsed:.1f}s ({avg_rate:.1f} t/s avg)[/dim]")
         | 
| 206 210 |  | 
| 207 | 
            -
                        # Reset
         | 
| 211 | 
            +
                        # Reset state
         | 
| 208 212 | 
             
                        self.start_time = None
         | 
| 209 213 | 
             
                        self.token_count = 0
         | 
| 214 | 
            +
                        self.last_update_time = None
         | 
| 215 | 
            +
                        self.last_token_count = 0
         | 
| 216 | 
            +
                        self.current_rate = 0
         | 
| 217 | 
            +
                        
         | 
| 218 | 
            +
                        # Reset global rate to 0 to avoid affecting subsequent tasks
         | 
| 219 | 
            +
                        global CURRENT_TOKEN_RATE
         | 
| 220 | 
            +
                        CURRENT_TOKEN_RATE = 0.0
         | 
    
        code_puppy/token_utils.py
    CHANGED
    
    | @@ -1,16 +1,17 @@ | |
| 1 1 | 
             
            import json
         | 
| 2 | 
            -
            import tiktoken
         | 
| 3 2 |  | 
| 4 3 | 
             
            import pydantic
         | 
| 5 4 | 
             
            from pydantic_ai.messages import ModelMessage
         | 
| 6 5 |  | 
| 7 6 |  | 
| 8 | 
            -
            def  | 
| 7 | 
            +
            def estimate_tokens(text: str) -> int:
         | 
| 9 8 | 
             
                """
         | 
| 10 | 
            -
                 | 
| 11 | 
            -
                This is a simple  | 
| 9 | 
            +
                Estimate the number of tokens using the len/4 heuristic.
         | 
| 10 | 
            +
                This is a simple approximation that works reasonably well for most text.
         | 
| 12 11 | 
             
                """
         | 
| 13 | 
            -
                 | 
| 12 | 
            +
                if not text:
         | 
| 13 | 
            +
                    return 0
         | 
| 14 | 
            +
                return max(1, len(text) // 4)
         | 
| 14 15 |  | 
| 15 16 |  | 
| 16 17 | 
             
            def stringify_message_part(part) -> str:
         | 
| @@ -55,16 +56,14 @@ def stringify_message_part(part) -> str: | |
| 55 56 |  | 
| 56 57 | 
             
            def estimate_tokens_for_message(message: ModelMessage) -> int:
         | 
| 57 58 | 
             
                """
         | 
| 58 | 
            -
                Estimate the number of tokens in a message using  | 
| 59 | 
            -
                This is  | 
| 59 | 
            +
                Estimate the number of tokens in a message using the len/4 heuristic.
         | 
| 60 | 
            +
                This is a simple approximation that works reasonably well for most text.
         | 
| 60 61 | 
             
                """
         | 
| 61 | 
            -
                tokenizer = get_tokenizer()
         | 
| 62 62 | 
             
                total_tokens = 0
         | 
| 63 63 |  | 
| 64 64 | 
             
                for part in message.parts:
         | 
| 65 65 | 
             
                    part_str = stringify_message_part(part)
         | 
| 66 66 | 
             
                    if part_str:
         | 
| 67 | 
            -
                         | 
| 68 | 
            -
                        total_tokens += len(tokens)
         | 
| 67 | 
            +
                        total_tokens += estimate_tokens(part_str)
         | 
| 69 68 |  | 
| 70 69 | 
             
                return max(1, total_tokens)
         | 
    
        code_puppy/tools/common.py
    CHANGED
    
    
| @@ -7,7 +7,7 @@ from pydantic import BaseModel, conint | |
| 7 7 | 
             
            from pydantic_ai import RunContext
         | 
| 8 8 |  | 
| 9 9 | 
             
            from code_puppy.tools.common import console
         | 
| 10 | 
            -
            from code_puppy.token_utils import  | 
| 10 | 
            +
            from code_puppy.token_utils import estimate_tokens
         | 
| 11 11 | 
             
            from code_puppy.tools.token_check import token_guard
         | 
| 12 12 | 
             
            # ---------------------------------------------------------------------------
         | 
| 13 13 | 
             
            # Module-level helper functions (exposed for unit tests _and_ used as tools)
         | 
| @@ -218,8 +218,7 @@ def _read_file(context: RunContext, file_path: str, start_line: int | None = Non | |
| 218 218 | 
             
                            # Read the entire file
         | 
| 219 219 | 
             
                            content = f.read()
         | 
| 220 220 |  | 
| 221 | 
            -
                         | 
| 222 | 
            -
                        num_tokens = len(tokenizer.encode(content))
         | 
| 221 | 
            +
                        num_tokens = estimate_tokens(content)
         | 
| 223 222 | 
             
                        if num_tokens > 10000:
         | 
| 224 223 | 
             
                            raise ValueError("The file is massive, greater than 10,000 tokens which is dangerous to read entirely. Please read this file in chunks.")
         | 
| 225 224 | 
             
                        token_guard(num_tokens)
         | 
| @@ -313,8 +312,7 @@ def list_files( | |
| 313 312 | 
             
                context: RunContext, directory: str = ".", recursive: bool = True
         | 
| 314 313 | 
             
            ) -> ListFileOutput:
         | 
| 315 314 | 
             
                list_files_output = _list_files(context, directory, recursive)
         | 
| 316 | 
            -
                 | 
| 317 | 
            -
                num_tokens = len(tokenizer.encode(list_files_output.model_dump_json()))
         | 
| 315 | 
            +
                num_tokens = estimate_tokens(list_files_output.model_dump_json())
         | 
| 318 316 | 
             
                if num_tokens > 10000:
         | 
| 319 317 | 
             
                    return ListFileOutput(
         | 
| 320 318 | 
             
                        files=[],
         | 
| @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            Metadata-Version: 2.4
         | 
| 2 2 | 
             
            Name: code-puppy
         | 
| 3 | 
            -
            Version: 0.0. | 
| 3 | 
            +
            Version: 0.0.92
         | 
| 4 4 | 
             
            Summary: Code generation agent
         | 
| 5 5 | 
             
            Author: Michael Pfaffenberger
         | 
| 6 6 | 
             
            License: MIT
         | 
| @@ -27,7 +27,6 @@ Requires-Dist: python-dotenv>=1.0.0 | |
| 27 27 | 
             
            Requires-Dist: rapidfuzz>=3.13.0
         | 
| 28 28 | 
             
            Requires-Dist: rich>=13.4.2
         | 
| 29 29 | 
             
            Requires-Dist: ruff>=0.11.11
         | 
| 30 | 
            -
            Requires-Dist: tiktoken>=0.11.0
         | 
| 31 30 | 
             
            Requires-Dist: tree-sitter-language-pack>=0.8.0
         | 
| 32 31 | 
             
            Requires-Dist: tree-sitter-typescript>=0.23.2
         | 
| 33 32 | 
             
            Description-Content-Type: text/markdown
         | 
| @@ -1,15 +1,15 @@ | |
| 1 1 | 
             
            code_puppy/__init__.py,sha256=CWH46ZAmJRmHAbOiAhG07OrWYEcEt4yvDTkZU341Wag,169
         | 
| 2 | 
            -
            code_puppy/agent.py,sha256= | 
| 2 | 
            +
            code_puppy/agent.py,sha256=Hwlblm9Om4qZPOur28auxBkdJRAA9Kz-36YPQg7i3SI,3321
         | 
| 3 3 | 
             
            code_puppy/agent_prompts.py,sha256=t3-lqDKrDxCKxFa_va4Suze9BT-JOu1dh9iGiAVNFO4,6828
         | 
| 4 4 | 
             
            code_puppy/config.py,sha256=r5nw5ChOP8xd_K5yo8U5OtO2gy2bFhARiyNtDp1JrwQ,5013
         | 
| 5 | 
            -
            code_puppy/main.py,sha256= | 
| 6 | 
            -
            code_puppy/message_history_processor.py,sha256 | 
| 5 | 
            +
            code_puppy/main.py,sha256=4ru_POVn6_QylecnJ12aNi95mi0bZ4A6P1Ujzn_YD4k,21220
         | 
| 6 | 
            +
            code_puppy/message_history_processor.py,sha256=-bdtufnxMNrX9JLY6dgmxGxjgy4sutTjA_SCKGnEaaA,9931
         | 
| 7 7 | 
             
            code_puppy/model_factory.py,sha256=HXuFHNkVjkCcorAd3ScFmSvBILO932UTq6OmNAqisT8,10898
         | 
| 8 8 | 
             
            code_puppy/models.json,sha256=jr0-LW87aJS79GosVwoZdHeeq5eflPzgdPoMbcqpVA8,2728
         | 
| 9 9 | 
             
            code_puppy/state_management.py,sha256=JkTkmq6f9rl_RHPDoBqJvbAzgaMsIkJf-k38ragItIo,1692
         | 
| 10 | 
            -
            code_puppy/status_display.py,sha256= | 
| 10 | 
            +
            code_puppy/status_display.py,sha256=P4FVtbzdGQs11UDz4ZlWKOpuNYLQ8ILANi2NlMyjKp8,8413
         | 
| 11 11 | 
             
            code_puppy/summarization_agent.py,sha256=jHUQe6iYJsMT0ywEwO7CrhUIKEamO5imhAsDwvNuvow,2684
         | 
| 12 | 
            -
            code_puppy/token_utils.py,sha256= | 
| 12 | 
            +
            code_puppy/token_utils.py,sha256=c3mD-7VSvkybP9J4kptyrq_jushtzaKUTj6qj2ddqZA,2070
         | 
| 13 13 | 
             
            code_puppy/version_checker.py,sha256=aRGulzuY4C4CdFvU1rITduyL-1xTFsn4GiD1uSfOl_Y,396
         | 
| 14 14 | 
             
            code_puppy/command_line/__init__.py,sha256=y7WeRemfYppk8KVbCGeAIiTuiOszIURCDjOMZv_YRmU,45
         | 
| 15 15 | 
             
            code_puppy/command_line/file_path_completion.py,sha256=gw8NpIxa6GOpczUJRyh7VNZwoXKKn-yvCqit7h2y6Gg,2931
         | 
| @@ -20,13 +20,13 @@ code_puppy/command_line/prompt_toolkit_completion.py,sha256=De_grHDPOvCRph-HDOGC | |
| 20 20 | 
             
            code_puppy/command_line/utils.py,sha256=7eyxDHjPjPB9wGDJQQcXV_zOsGdYsFgI0SGCetVmTqE,1251
         | 
| 21 21 | 
             
            code_puppy/tools/__init__.py,sha256=WTHYIfRk2KMmk6o45TELpbB3GIiAm8s7GmfJ7Zy_tww,503
         | 
| 22 22 | 
             
            code_puppy/tools/command_runner.py,sha256=9UWCSPpuEndaPx8Ecc8TRsn3rMHNd2AqerirvYPGRIw,14358
         | 
| 23 | 
            -
            code_puppy/tools/common.py,sha256= | 
| 23 | 
            +
            code_puppy/tools/common.py,sha256=fQL5ub2HgAo_s8RCeQFYwmALgrPfkUi35Q0InK4_7lE,3249
         | 
| 24 24 | 
             
            code_puppy/tools/file_modifications.py,sha256=BzQrGEacS2NZr2ru9N30x_Qd70JDudBKOAPO1XjBohg,13861
         | 
| 25 | 
            -
            code_puppy/tools/file_operations.py,sha256= | 
| 25 | 
            +
            code_puppy/tools/file_operations.py,sha256=htrdURR1mBqBUja1mAHLlySwFN6xNHeGdYbg5eLiOug,13533
         | 
| 26 26 | 
             
            code_puppy/tools/token_check.py,sha256=F3eygdI8fgb6dfCrSkGw_OLI7cb_Kpa5ILft4BQ7hvY,525
         | 
| 27 | 
            -
            code_puppy-0.0. | 
| 28 | 
            -
            code_puppy-0.0. | 
| 29 | 
            -
            code_puppy-0.0. | 
| 30 | 
            -
            code_puppy-0.0. | 
| 31 | 
            -
            code_puppy-0.0. | 
| 32 | 
            -
            code_puppy-0.0. | 
| 27 | 
            +
            code_puppy-0.0.92.data/data/code_puppy/models.json,sha256=jr0-LW87aJS79GosVwoZdHeeq5eflPzgdPoMbcqpVA8,2728
         | 
| 28 | 
            +
            code_puppy-0.0.92.dist-info/METADATA,sha256=gBLvPgAiTg5Ut7rMaBA_wiyVV3pGDe8yBy-TrUJDuRk,6319
         | 
| 29 | 
            +
            code_puppy-0.0.92.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
         | 
| 30 | 
            +
            code_puppy-0.0.92.dist-info/entry_points.txt,sha256=d8YkBvIUxF-dHNJAj-x4fPEqizbY5d_TwvYpc01U5kw,58
         | 
| 31 | 
            +
            code_puppy-0.0.92.dist-info/licenses/LICENSE,sha256=31u8x0SPgdOq3izJX41kgFazWsM43zPEF9eskzqbJMY,1075
         | 
| 32 | 
            +
            code_puppy-0.0.92.dist-info/RECORD,,
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         | 
| 
            File without changes
         |