Skip to content

Commit 357beab

Browse files
committed
Add non-streaming mode.
1 parent 5fed7e5 commit 357beab

14 files changed

Lines changed: 619 additions & 104 deletions

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,8 @@ Edit `~/.config/python-agent-harness/config.json`:
9494
"base_url": "https://api.deepseek.com/v1",
9595
"api_key": "sk-...",
9696
"model": "deepseek-chat",
97-
"reasoning_effort": "medium"
97+
"reasoning_effort": "medium",
98+
"stream": true
9899
},
99100
"paths": {
100101
"context_path": null,
@@ -106,7 +107,9 @@ Edit `~/.config/python-agent-harness/config.json`:
106107
`reasoning_effort` is passed to the API as-is (omitted when unset), so you
107108
can use whatever your provider accepts ("low"/"medium"/"high" for OpenAI
108109
and compatible providers). Other optional keys: `backend`, `temperature`,
109-
`max_tokens`, `timeout`. The `paths` object (`context_path`,
110+
`max_tokens`, `timeout`, `stream` (`true` by default; set `false` for
111+
non-streaming one-shot responses — `python-agent-harness run --no-stream`
112+
overrides it on the command line). The `paths` object (`context_path`,
110113
`skill_path`) overrides the context/skill directory discovery — defaults
111114
are `<project>/contexts` or `~/.emacs.d/contexts` for context files, and
112115
`<project>/skills` or `~/.emacs.d/skills` for skills.

python_agent_harness/agent.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,7 @@ def safe_delta(text: str) -> None:
348348
temperature=session.temperature,
349349
max_tokens=session.max_tokens,
350350
reasoning_effort=session.reasoning_effort,
351+
stream=session.stream,
351352
# sub-agents must not stream into the parent's live
352353
# stream row — their text is private until returned
353354
on_delta=(safe_delta if self.top_level else None),

python_agent_harness/agent_session.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ def __init__(
7373
temperature: float = config.TEMPERATURE,
7474
max_tokens: int = config.MAX_TOKENS,
7575
reasoning_effort: str | None = None,
76+
stream: bool = True,
7677
tool_names: list[str] | None = None,
7778
registry: Registry | None = None,
7879
context_path: str | None = None,
@@ -87,6 +88,7 @@ def __init__(
8788
self.temperature = temperature
8889
self.max_tokens = max_tokens
8990
self.reasoning_effort = reasoning_effort
91+
self.stream = stream
9092
self.tools_enabled = True
9193
self.alive = True
9294
self._configured_context_path = context_path

python_agent_harness/cli.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ def make_session(
2828
project_dir: str,
2929
config_path: str | None = None,
3030
model: str | None = None,
31+
stream: bool | None = None,
3132
) -> AgentSession:
3233
"""Create an AgentSession from config file + env (no env required).
3334
@@ -70,6 +71,7 @@ def make_session(
7071
temperature=settings["temperature"],
7172
max_tokens=settings["max_tokens"],
7273
reasoning_effort=settings["reasoning_effort"],
74+
stream=settings["stream"] if stream is None else stream,
7375
registry=default_registry(),
7476
context_path=paths.get("context_path"),
7577
skill_path=paths.get("skill_path"),
@@ -80,7 +82,10 @@ def cmd_run(args: argparse.Namespace) -> int:
8082
from .tui import Tui
8183

8284
project_dir = args.project or os.getcwd()
83-
session = make_session(project_dir, config_path=args.config)
85+
session = make_session(
86+
project_dir, config_path=args.config,
87+
stream=False if getattr(args, "no_stream", False) else None,
88+
)
8489
Tui(session).run()
8590
session.close()
8691
return 0
@@ -108,6 +113,7 @@ def cmd_config(args: argparse.Namespace) -> int:
108113
print(f"temperature: {settings['temperature']}")
109114
print(f"max_tokens: {settings['max_tokens']}")
110115
print(f"reasoning_effort: {settings['reasoning_effort']}")
116+
print(f"stream: {settings['stream']}")
111117
print(f"timeout: {settings['timeout']}")
112118
print(f"context_path: {paths['context_path'] or '(auto-discover)'}")
113119
print(f"skill_path: {paths['skill_path'] or '(auto-discover)'}")
@@ -135,6 +141,10 @@ def build_parser() -> argparse.ArgumentParser:
135141

136142
p_run = sub.add_parser("run", help="interactive TUI agent session")
137143
_add_config_arg(p_run, suppress=True)
144+
p_run.add_argument(
145+
"--no-stream", action="store_true",
146+
help="disable streaming (one-shot responses; overrides config file)",
147+
)
138148
p_run.add_argument("project", nargs="?", help="project directory (default: cwd)")
139149

140150
p_config = sub.add_parser(

0 commit comments

Comments
 (0)