Skip to content

Commit 1d2aed1

Browse files
committed
Refactor to make file name more reasonable.
1 parent 5d49f5d commit 1d2aed1

22 files changed

Lines changed: 68 additions & 63 deletions

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,14 +121,14 @@ clobber the next run's state (per-run cancellation identity).
121121
python_agent_harness/
122122
├── agent.py agent loop (supervision, nudges, compaction)
123123
├── client.py OpenAI-compatible streaming client (httpx)
124-
├── tokenizer.py CJK-aware token estimation + calibration
124+
├── token_estimator.py CJK-aware token estimation + calibration
125125
├── safety.py path guards + bash policy tiers
126126
├── undo.py file snapshots / undo
127127
├── cache.py tool-result cache + dedup
128128
├── planmode.py build/plan mode + plan file lifecycle
129-
├── compaction.py compact frame / anchored summary
130-
├── session.py session persistence + titles
131-
├── harness.py AgentSession (wiring hub)
129+
├── prompts.py prompt loading + system prompt assembly
130+
├── session_store.py session persistence + titles
131+
├── agent_session.py AgentSession (wiring hub)
132132
├── commands.py init/review/custom command definitions
133133
├── cli.py argparse entry points
134134
├── tui.py rich + prompt_toolkit TUI

python_agent_harness/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""python-agent-harness: a Python port of the gptel-agent-harness."""
22

3-
from .harness import AgentSession
3+
from .agent_session import AgentSession
44
from .models import AgentMode, Message, ToolCall, ToolSpec
55

66
__version__ = "0.1.0"

python_agent_harness/agent.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@
1919
from typing import Any
2020

2121
from . import config
22-
from .compaction import last_user_request, read_prompt_file
22+
from .prompts import last_user_request, read_prompt_file
2323
from .models import Message, ToolCall
24-
from .tokenizer import context_window_for, estimate_payload_tokens
24+
from .token_estimator import context_window_for, estimate_payload_tokens
2525

2626

2727
class AgentLoop:
28-
"""Runs one agent session until terminal or max rounds."""
28+
"""Runs one agent session until terminal (main) or max rounds (sub-agent)."""
2929

3030
def __init__(
3131
self,
@@ -47,7 +47,9 @@ def __init__(
4747
else:
4848
attr = "system_prompt" if top_level else "subagent_system_prompt"
4949
self.system = getattr(session, attr, None)
50-
self.max_rounds = max_rounds
50+
# max_rounds only bounds sub-agent loops: the main agent runs until
51+
# the model gives a terminal response or the user aborts it (Ctrl-C)
52+
self.max_rounds = max_rounds if not top_level else None
5153
self.pending: list[ToolCall] = []
5254
self.error: str | None = None
5355
self.harness_injected: bool = False
@@ -234,7 +236,7 @@ def run(self) -> str | None:
234236

235237
def _run(self, rounds: int) -> str | None:
236238
session = self.session
237-
while rounds < self.max_rounds:
239+
while self.max_rounds is None or rounds < self.max_rounds:
238240
rounds += 1
239241
if self._is_cancelled():
240242
return None
@@ -306,7 +308,8 @@ def safe_delta(text: str) -> None:
306308
return f"Error: {self.error or 'unknown error'}"
307309
return assistant.text()
308310

309-
# round budget exhausted, or an API error broke the loop
311+
# round budget exhausted (sub-agents only), or an API error broke
312+
# the loop
310313
if self.error:
311314
return self.error
312315
return self.messages[-1].text() if self.messages else None
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@
1919
from .models import AgentMode
2020
from .planmode import PlanMode
2121
from .safety import BashPolicy, SafetyViolation, check_path
22-
from .session import SessionStore
22+
from .session_store import SessionStore
2323
from .subagent import run_subagent
24-
from .tokenizer import TokenCalibrator
24+
from .token_estimator import TokenCalibrator
2525
from .tools import Registry, ToolContext
2626
from .undo import UndoStack
2727

@@ -428,7 +428,7 @@ def switch_to_plan(self) -> None:
428428
self.registry.register(PlanExit())
429429

430430
def _mode_prompts(self) -> dict[str, str]:
431-
from .compaction import read_prompt_file
431+
from .prompts import read_prompt_file
432432

433433
return {
434434
"plan": read_prompt_file("plan.txt"),
@@ -475,7 +475,7 @@ def generate_session_title(self) -> None:
475475
return
476476
store.title_pending = True
477477
try:
478-
from .compaction import read_prompt_file
478+
from .prompts import read_prompt_file
479479
from .models import Message as Msg
480480

481481
system = read_prompt_file("title.txt")
@@ -542,7 +542,7 @@ def compact_conversation(self) -> tuple[bool, str]:
542542
replaced by the summary frame + the last real user request, the
543543
cache epoch is reset, and the session file is refreshed.
544544
"""
545-
from .compaction import last_user_request, read_prompt_file
545+
from .prompts import last_user_request, read_prompt_file
546546
from .models import Message as Msg
547547

548548
messages = self.last_messages or []
@@ -585,7 +585,7 @@ def summarize_conversation(self) -> str:
585585
text is sent with the summary prompt, and the result is appended
586586
as an assistant message plus a session save.
587587
"""
588-
from .compaction import read_prompt_file
588+
from .prompts import read_prompt_file
589589
from .models import Message as Msg
590590

591591
messages = self.last_messages or []

python_agent_harness/cli.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727
from .commands import (
2828
SessionCommand, find_command, load_custom_commands,
2929
)
30-
from .harness import AgentSession
31-
from .session import SessionStore
30+
from .agent_session import AgentSession
31+
from .session_store import SessionStore
3232
from .tools import default_registry
3333

3434

@@ -58,8 +58,8 @@ def make_session(
5858
model=model,
5959
timeout=settings["timeout"],
6060
)
61-
from .compaction import assemble_agent_prompt, load_agent_prompt
62-
from .harness import find_skill_dir
61+
from .prompts import assemble_agent_prompt, load_agent_prompt
62+
from .agent_session import find_skill_dir
6363

6464
abs_project = os.path.abspath(project_dir)
6565
skill_dir = find_skill_dir(abs_project, paths.get("skill_path"))
@@ -162,7 +162,7 @@ def _adopt(session: AgentSession, kw: dict) -> AgentSession:
162162
# The command's prompt becomes the "actual agent prompt"; the
163163
# project context + task-completion rules are kept in front of it.
164164
if kw.get("system_prompt") is not None:
165-
from .compaction import assemble_agent_prompt
165+
from .prompts import assemble_agent_prompt
166166

167167
session.system_prompt = assemble_agent_prompt(
168168
session.project_dir, kw["system_prompt"],
@@ -187,8 +187,8 @@ def cmd_sessions(args: argparse.Namespace) -> int:
187187

188188

189189
def cmd_restore(args: argparse.Namespace) -> int:
190-
from .session import SessionStore as Store
191-
from .session import title_from_filename
190+
from .session_store import SessionStore as Store
191+
from .session_store import title_from_filename
192192

193193
path = args.file
194194
if not path and args.latest:

python_agent_harness/commands.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from pathlib import Path
1212

1313
from .agent import run_agent_loop
14-
from .compaction import read_prompt_file
14+
from .prompts import read_prompt_file
1515
from .models import Message
1616

1717
PROMPTS_DIR = Path(__file__).parent / "prompts"
@@ -88,7 +88,7 @@ def run(
8888
)
8989
# the command prompt is the "actual agent prompt"; the project
9090
# context and task-completion rules are kept in front of it
91-
from .compaction import assemble_agent_prompt
91+
from .prompts import assemble_agent_prompt
9292

9393
context_path = getattr(session, "_configured_context_path", None)
9494
system = assemble_agent_prompt(cwd, prompt, context_path=context_path)

python_agent_harness/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@
148148
TEMPERATURE = 0.0
149149

150150
# ---- sub-agents ---------------------------------------------------------------
151-
SUBAGENT_MAX_ROUNDS = 40
151+
SUBAGENT_MAX_ROUNDS = 60
152152

153153
# ---- TUI preview limits -------------------------------------------------------
154154
TOOL_RESULT_PREVIEW_LINES = 5 # max lines of a tool result shown in the TUI
Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
"""Context compaction.
2-
3-
Ported from gptel-agent-harness.el: on high context usage, abort the
4-
current round, summarize the whole conversation (compact.txt as system
5-
prompt, tools disabled), wrap the summary in a compact frame, reset the
6-
cache epoch, and resume with the last user request.
1+
"""Prompt loading and assembly.
2+
3+
Ported from gptel-agent-harness.el: loads bundled prompt files
4+
(agent/subagent/commands), strips YAML frontmatter, discovers skills
5+
for the {{SKILLS}} placeholder, assembles the effective system prompt
6+
from project context files + task-completion rules + agent prompt, and
7+
provides last_user_request() for the compaction flow (summarize the
8+
conversation and resume with the last user request).
79
"""
810

911
from __future__ import annotations
@@ -183,7 +185,7 @@ def assemble_agent_prompt(
183185
parts: list[str] = []
184186
if include_context:
185187
# lazy import: harness imports this module at call time
186-
from .harness import find_context_dir
188+
from .agent_session import find_context_dir
187189

188190
context_block = load_context_files(find_context_dir(project_dir, context_path))
189191
if context_block:

python_agent_harness/subagent.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
from . import config
1111
from .agent import run_agent_loop
12-
from .compaction import load_agent_prompt
12+
from .prompts import load_agent_prompt
1313
from .models import Message
1414

1515

0 commit comments

Comments
 (0)