diff --git a/doc/plyngent.example.toml b/doc/plyngent.example.toml index bd4e16a..3125034 100644 --- a/doc/plyngent.example.toml +++ b/doc/plyngent.example.toml @@ -41,6 +41,9 @@ max_context_tokens = 200000 # developer (default) | user | synthetic_tool | none # (legacy system is treated as developer) # todo_nag_strategy = "developer" +# Append-only developer playbook checkpoints every N prompt_tokens (0 = off). +# directive_reminder_tokens = 100000 +# directive_reminder_text = "" # Optional: custom compact/summarisation prompts (empty = built-in defaults). # compact_system_prompt = "" diff --git a/src/plyngent/cli/slash.py b/src/plyngent/cli/slash.py index 634fb51..ba4d56a 100644 --- a/src/plyngent/cli/slash.py +++ b/src/plyngent/cli/slash.py @@ -544,6 +544,9 @@ def status_cmd(state: ReplState) -> None: f"context_tokens={ctx_tilde}{ctx_tokens}/{ctx_budget} ({ctx_tag}) " f"context_chars={ctx_chars} " f"tool_result_max={state.agent.max_tool_result_chars}\n" + f"peak_prompt_tokens={state.agent.peak_prompt_tokens} " + f"reminder_band={state.agent.reminder_last_band} " + f"reminder_every={state.agent.directive_reminder_tokens or 'off'}\n" f"last_request={last_req.format_line()}\n" f"usage_last_turn={last_u.format_line(billed=True)} " f"rounds={last_rounds}\n" diff --git a/src/plyngent/cli/state.py b/src/plyngent/cli/state.py index 9bb0e4a..ec87d8f 100644 --- a/src/plyngent/cli/state.py +++ b/src/plyngent/cli/state.py @@ -236,7 +236,14 @@ class ReplState: agent_cfg.tool_directives, ) on_limit = prompt_continue_limit_async if self.interactive_limits else None - return ChatAgent( + peak = 0 + band = 0 + last_req = None + if hasattr(self, "agent"): + peak = self.agent.peak_prompt_tokens + band = self.agent.reminder_last_band + last_req = self.agent.last_request_usage + agent = ChatAgent( self.client, model=self.model, tools=self._tool_registry(), @@ -251,7 +258,14 @@ class ReplState: max_context_tokens=agent_cfg.max_context_tokens, todo_stack=self.todo_stack, todo_nag_strategy=agent_cfg.todo_nag_strategy, + directive_reminder_tokens=agent_cfg.directive_reminder_tokens, + directive_reminder_text=agent_cfg.directive_reminder_text or None, + peak_prompt_tokens=peak, + reminder_last_band=band, ) + if last_req is not None and not last_req.is_zero(): + agent.last_request_usage = last_req + return agent def rebuild_client(self) -> None: """Recreate client and agent after provider/model/tools change.""" diff --git a/src/plyngent/config/models.py b/src/plyngent/config/models.py index 8315d73..2529db5 100644 --- a/src/plyngent/config/models.py +++ b/src/plyngent/config/models.py @@ -99,6 +99,12 @@ class AgentConfig(Struct, omit_defaults=True): # developer | user | synthetic_tool | none (legacy "system" → developer) todo_nag_strategy: str = "developer" + # Append-only developer playbook checkpoints when last prompt_tokens crosses + # N * this interval (0 = off). See agent/directive_checkpoint.py. + directive_reminder_tokens: int = 100_000 + # Optional short checklist body (empty = built-in hard-constraint list). + directive_reminder_text: str = "" + # Compact / summarisation prompts (empty = use built-in defaults). compact_system_prompt: str = "" compact_user_prefix: str = ""