mirror of
https://github.com/khodges42/nightShift.git
synced 2026-06-14 18:18:36 +00:00
Fix a windows bug for i/o from ollama
This commit is contained in:
parent
360f449738
commit
169c7aacae
|
|
@ -149,6 +149,8 @@ class AgentExecutor:
|
|||
input=prompt,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
errors="replace",
|
||||
timeout=self.timeout_seconds,
|
||||
)
|
||||
duration = time.monotonic() - started
|
||||
|
|
@ -157,8 +159,8 @@ class AgentExecutor:
|
|||
command=agent.command,
|
||||
prompt=prompt,
|
||||
exit_code=completed.returncode,
|
||||
stdout=completed.stdout,
|
||||
stderr=completed.stderr,
|
||||
stdout=_coerce_output(completed.stdout),
|
||||
stderr=_coerce_output(completed.stderr),
|
||||
duration_seconds=duration,
|
||||
)
|
||||
except subprocess.TimeoutExpired as exc:
|
||||
|
|
@ -186,6 +188,8 @@ class AgentExecutor:
|
|||
input=prompt,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
errors="replace",
|
||||
timeout=self.timeout_seconds,
|
||||
)
|
||||
duration = time.monotonic() - started
|
||||
|
|
@ -194,8 +198,8 @@ class AgentExecutor:
|
|||
command=command,
|
||||
prompt=prompt,
|
||||
exit_code=completed.returncode,
|
||||
stdout=completed.stdout,
|
||||
stderr=completed.stderr,
|
||||
stdout=_coerce_output(completed.stdout),
|
||||
stderr=_coerce_output(completed.stderr),
|
||||
duration_seconds=duration,
|
||||
)
|
||||
except FileNotFoundError as exc:
|
||||
|
|
@ -323,6 +327,9 @@ def parse_review_output(output: str) -> tuple[StageStatus, str, str | None, str
|
|||
|
||||
|
||||
def format_agent_invocation(stage_id: str, invocation: AgentInvocation) -> str:
|
||||
stdout = _coerce_output(invocation.stdout)
|
||||
stderr = _coerce_output(invocation.stderr)
|
||||
prompt = _coerce_output(invocation.prompt)
|
||||
return "\n".join(
|
||||
[
|
||||
f"# Agent Output: {stage_id}",
|
||||
|
|
@ -336,19 +343,19 @@ def format_agent_invocation(stage_id: str, invocation: AgentInvocation) -> str:
|
|||
"## stdout",
|
||||
"",
|
||||
"```text",
|
||||
invocation.stdout.rstrip(),
|
||||
stdout.rstrip(),
|
||||
"```",
|
||||
"",
|
||||
"## stderr",
|
||||
"",
|
||||
"```text",
|
||||
invocation.stderr.rstrip(),
|
||||
stderr.rstrip(),
|
||||
"```",
|
||||
"",
|
||||
"## Prompt",
|
||||
"",
|
||||
"```markdown",
|
||||
invocation.prompt.rstrip(),
|
||||
prompt.rstrip(),
|
||||
"```",
|
||||
"",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -125,6 +125,8 @@ class CommandExecutor:
|
|||
shell=shell,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
errors="replace",
|
||||
timeout=timeout,
|
||||
env=env,
|
||||
)
|
||||
|
|
@ -132,8 +134,8 @@ class CommandExecutor:
|
|||
return CommandRun(
|
||||
command=normalized,
|
||||
exit_code=completed.returncode,
|
||||
stdout=completed.stdout,
|
||||
stderr=completed.stderr,
|
||||
stdout=_coerce_output(completed.stdout),
|
||||
stderr=_coerce_output(completed.stderr),
|
||||
duration_seconds=duration,
|
||||
)
|
||||
except subprocess.TimeoutExpired as exc:
|
||||
|
|
@ -151,6 +153,8 @@ class CommandExecutor:
|
|||
def format_command_runs(stage_id: str, runs: list[CommandRun]) -> str:
|
||||
lines = [f"# Command Output: {stage_id}", ""]
|
||||
for index, run in enumerate(runs, start=1):
|
||||
stdout = _coerce_output(run.stdout)
|
||||
stderr = _coerce_output(run.stderr)
|
||||
lines.extend(
|
||||
[
|
||||
f"## Command {index}",
|
||||
|
|
@ -163,13 +167,13 @@ def format_command_runs(stage_id: str, runs: list[CommandRun]) -> str:
|
|||
"### stdout",
|
||||
"",
|
||||
"```text",
|
||||
run.stdout.rstrip(),
|
||||
stdout.rstrip(),
|
||||
"```",
|
||||
"",
|
||||
"### stderr",
|
||||
"",
|
||||
"```text",
|
||||
run.stderr.rstrip(),
|
||||
stderr.rstrip(),
|
||||
"```",
|
||||
"",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -25,11 +25,18 @@ def run_git(project_root: Path, args: list[str], timeout_seconds: int = 15) -> G
|
|||
cwd=project_root,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
errors="replace",
|
||||
timeout=timeout_seconds,
|
||||
)
|
||||
except (OSError, subprocess.TimeoutExpired) as exc:
|
||||
return GitCommandResult(False, -1, "", str(exc))
|
||||
return GitCommandResult(completed.returncode == 0, completed.returncode, completed.stdout, completed.stderr)
|
||||
return GitCommandResult(
|
||||
completed.returncode == 0,
|
||||
completed.returncode,
|
||||
completed.stdout or "",
|
||||
completed.stderr or "",
|
||||
)
|
||||
|
||||
|
||||
def get_git_status(project_root: Path) -> GitCommandResult:
|
||||
|
|
|
|||
|
|
@ -213,6 +213,8 @@ def collect_modified_files(project_root: Path) -> list[str]:
|
|||
shell=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
encoding="utf-8",
|
||||
errors="replace",
|
||||
timeout=10,
|
||||
)
|
||||
except (OSError, subprocess.TimeoutExpired):
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import unittest
|
|||
from unittest.mock import patch
|
||||
|
||||
from nightshift.agents import AgentExecutor, build_prompt_bundle, parse_review_output
|
||||
from nightshift.agents import AgentInvocation, format_agent_invocation
|
||||
from nightshift.artifacts import ArtifactStore
|
||||
from nightshift.config import AgentConfig, StageConfig
|
||||
from nightshift.tasks import parse_tasks
|
||||
|
|
@ -131,6 +132,22 @@ class AgentExecutorTests(unittest.TestCase):
|
|||
output = (root / result.output_path).read_text(encoding="utf-8")
|
||||
self.assertIn("ollama run tiny-model", output)
|
||||
|
||||
def test_agent_artifact_format_tolerates_missing_streams(self) -> None:
|
||||
invocation = AgentInvocation(
|
||||
agent_id="planner",
|
||||
command="ollama run model",
|
||||
prompt="prompt",
|
||||
exit_code=0,
|
||||
stdout=None, # type: ignore[arg-type]
|
||||
stderr=None, # type: ignore[arg-type]
|
||||
duration_seconds=0.1,
|
||||
)
|
||||
|
||||
output = format_agent_invocation("plan", invocation)
|
||||
|
||||
self.assertIn("Agent: `planner`", output)
|
||||
self.assertIn("## stderr", output)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import unittest
|
|||
|
||||
from nightshift.artifacts import ArtifactStore
|
||||
from nightshift.commands import CommandExecutor
|
||||
from nightshift.commands import CommandRun, format_command_runs
|
||||
from nightshift.config import SafetyConfig, StageConfig
|
||||
from nightshift.errors import CommandError
|
||||
|
||||
|
|
@ -150,6 +151,23 @@ class CommandExecutorTests(unittest.TestCase):
|
|||
output = (root / result.output_path).read_text(encoding="utf-8")
|
||||
self.assertIn("work", output)
|
||||
|
||||
def test_command_artifact_format_tolerates_missing_streams(self) -> None:
|
||||
output = format_command_runs(
|
||||
"test",
|
||||
[
|
||||
CommandRun(
|
||||
command="cmd",
|
||||
exit_code=0,
|
||||
stdout=None, # type: ignore[arg-type]
|
||||
stderr=None, # type: ignore[arg-type]
|
||||
duration_seconds=0.1,
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
self.assertIn("Command: `cmd`", output)
|
||||
self.assertIn("### stderr", output)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user