fix(pi): keep interactive sessions open
This commit is contained in:
@@ -45,7 +45,12 @@ PROVIDER_TEMPLATES = frozenset({PROVIDER_CLAUDE, PROVIDER_CODEX, PROVIDER_PI})
|
||||
# forward_host_credentials is enabled. Pipelock must pass these through
|
||||
# (no TLS MITM) or its header DLP blocks the injected JWT.
|
||||
CODEX_HOST_CREDENTIAL_HOSTS = ("api.openai.com", "chatgpt.com")
|
||||
PromptMode = Literal["append_file", "read_prompt_file", "print_read_prompt_file"]
|
||||
PromptMode = Literal[
|
||||
"append_file",
|
||||
"read_prompt_file",
|
||||
"print_read_prompt_file",
|
||||
"append_system_prompt",
|
||||
]
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@@ -381,4 +386,6 @@ def prompt_args(
|
||||
return [f"Read and follow the instructions in {prompt_path}."]
|
||||
if prompt_mode == "print_read_prompt_file":
|
||||
return ["-p", f"Read and follow the instructions in {prompt_path}."]
|
||||
if prompt_mode == "append_system_prompt":
|
||||
return ["--append-system-prompt", prompt_path]
|
||||
raise ValueError(f"unknown provider prompt mode: {prompt_mode}")
|
||||
|
||||
@@ -111,7 +111,7 @@ _RUNTIME = AgentProviderRuntime(
|
||||
template="pi",
|
||||
command="pi",
|
||||
image="bot-bottle-pi:latest",
|
||||
prompt_mode="print_read_prompt_file",
|
||||
prompt_mode="append_system_prompt",
|
||||
bypass_args=(),
|
||||
resume_args=(),
|
||||
remote_control_args=(),
|
||||
|
||||
@@ -93,7 +93,7 @@ endpoint.
|
||||
The Pi runtime uses:
|
||||
|
||||
- `command="pi"`
|
||||
- `prompt_mode="read_prompt_file"`
|
||||
- `prompt_mode="append_system_prompt"`
|
||||
- `image="bot-bottle-pi:latest"`
|
||||
- `bypass_args=()`
|
||||
- `resume_args=()`
|
||||
|
||||
@@ -273,7 +273,7 @@ class TestAgentProviderRuntime(unittest.TestCase):
|
||||
models = json.loads(Path(tmp, "pi-models.json").read_text())
|
||||
self.assertEqual("pi", plan.template)
|
||||
self.assertEqual("pi", plan.command)
|
||||
self.assertEqual("print_read_prompt_file", plan.prompt_mode)
|
||||
self.assertEqual("append_system_prompt", plan.prompt_mode)
|
||||
self.assertEqual("/tmp/Dockerfile.pi", plan.dockerfile)
|
||||
self.assertEqual("bot-bottle-pi:latest", plan.image)
|
||||
self.assertEqual(
|
||||
@@ -354,10 +354,10 @@ class TestAgentProviderRuntime(unittest.TestCase):
|
||||
self.assertNotIn("OPENROUTER_API_KEY", plan.guest_env)
|
||||
self.assertTrue(provider["compat"]["supportsReasoningEffort"])
|
||||
|
||||
def test_pi_prompt_mode_uses_print_flag(self):
|
||||
def test_pi_prompt_mode_appends_system_prompt_interactively(self):
|
||||
self.assertEqual(
|
||||
["-p", "Read and follow the instructions in /home/node/.bot-bottle-prompt.txt."],
|
||||
prompt_args("print_read_prompt_file", "/home/node/.bot-bottle-prompt.txt"),
|
||||
["--append-system-prompt", "/home/node/.bot-bottle-prompt.txt"],
|
||||
prompt_args("append_system_prompt", "/home/node/.bot-bottle-prompt.txt"),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ def _plan(
|
||||
supervise_plan=None,
|
||||
use_runsc=False,
|
||||
agent_provision=agent_provision or AgentProvisionPlan(
|
||||
template="pi", command="pi", prompt_mode="print_read_prompt_file",
|
||||
template="pi", command="pi", prompt_mode="append_system_prompt",
|
||||
image="bot-bottle-pi:latest", dockerfile="",
|
||||
guest_home="/home/node",
|
||||
instance_name="bot-bottle-demo-abc12",
|
||||
@@ -144,7 +144,7 @@ class TestPiProvisionSkills(unittest.TestCase):
|
||||
class TestPiProvision(unittest.TestCase):
|
||||
def test_creates_dir_and_copies_models_config(self):
|
||||
provision = AgentProvisionPlan(
|
||||
template="pi", command="pi", prompt_mode="print_read_prompt_file",
|
||||
template="pi", command="pi", prompt_mode="append_system_prompt",
|
||||
image="", dockerfile="", guest_home="/home/node",
|
||||
instance_name="bot-bottle-demo-abc12",
|
||||
prompt_file=Path("/tmp/prompt.txt"),
|
||||
@@ -172,7 +172,7 @@ class TestPiProvision(unittest.TestCase):
|
||||
|
||||
def test_dies_when_dir_creation_fails(self):
|
||||
provision = AgentProvisionPlan(
|
||||
template="pi", command="pi", prompt_mode="print_read_prompt_file",
|
||||
template="pi", command="pi", prompt_mode="append_system_prompt",
|
||||
image="", dockerfile="", guest_home="/home/node",
|
||||
instance_name="bot-bottle-demo-abc12",
|
||||
prompt_file=Path("/tmp/prompt.txt"),
|
||||
|
||||
@@ -31,6 +31,16 @@ def _codex_bottle(prompt_path: str | None = None) -> DockerBottle:
|
||||
)
|
||||
|
||||
|
||||
def _pi_bottle(prompt_path: str | None = None) -> DockerBottle:
|
||||
return DockerBottle(
|
||||
container="bot-bottle-dev-abc",
|
||||
teardown=lambda: None,
|
||||
prompt_path_in_container=prompt_path,
|
||||
agent_command="pi",
|
||||
agent_prompt_mode="append_system_prompt",
|
||||
)
|
||||
|
||||
|
||||
class TestClaudeArgv(unittest.TestCase):
|
||||
def test_minimal_argv_no_prompt(self):
|
||||
argv = _bottle().agent_argv([])
|
||||
@@ -117,6 +127,15 @@ class TestClaudeArgv(unittest.TestCase):
|
||||
argv,
|
||||
)
|
||||
|
||||
def test_pi_provider_appends_system_prompt_without_print_mode(self):
|
||||
argv = _pi_bottle("/home/node/.bot-bottle-prompt.txt").agent_argv([])
|
||||
self.assertEqual(
|
||||
["docker", "exec", "-it", "bot-bottle-dev-abc", "pi",
|
||||
"--append-system-prompt", "/home/node/.bot-bottle-prompt.txt"],
|
||||
argv,
|
||||
)
|
||||
self.assertNotIn("-p", argv)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@@ -28,6 +28,15 @@ def _bottle(prompt_path: str | None = None, **env: str) -> SmolmachinesBottle:
|
||||
)
|
||||
|
||||
|
||||
def _pi_bottle(prompt_path: str | None = None) -> SmolmachinesBottle:
|
||||
return SmolmachinesBottle(
|
||||
"bot-bottle-dev-abc",
|
||||
prompt_path=prompt_path,
|
||||
agent_command="pi",
|
||||
agent_prompt_mode="append_system_prompt",
|
||||
)
|
||||
|
||||
|
||||
def _unwrap(argv: list[str]) -> list[str]:
|
||||
"""Strip the pty_resize wrapper from the front of a TTY-mode
|
||||
argv, return the inner smolvm argv. Mirrors what the kernel
|
||||
@@ -122,6 +131,16 @@ class TestClaudeArgvWrapped(unittest.TestCase):
|
||||
argv[agent_idx - 7:agent_idx - 2],
|
||||
)
|
||||
|
||||
def test_pi_provider_appends_system_prompt_without_print_mode(self):
|
||||
argv = _unwrap(
|
||||
_pi_bottle("/home/node/.bot-bottle-prompt.txt").agent_argv([])
|
||||
)
|
||||
self.assertEqual(
|
||||
["pi", "--append-system-prompt", "/home/node/.bot-bottle-prompt.txt"],
|
||||
argv[argv.index("pi"):],
|
||||
)
|
||||
self.assertNotIn("-p", argv)
|
||||
|
||||
|
||||
class TestClaudeArgvNoTTY(unittest.TestCase):
|
||||
"""`tty=False` paths skip the pty_resize wrapper — there's no
|
||||
|
||||
Reference in New Issue
Block a user