Skip to content

Commit 966272d

Browse files
committed
.
1 parent acfd7e7 commit 966272d

1 file changed

Lines changed: 56 additions & 0 deletions

File tree

code-interpreter/app/services/executor_kubernetes.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131
BaseExecutor,
3232
EntryKind,
3333
ExecutionResult,
34+
StreamEvent,
35+
StreamResult,
36+
StreamChunk,
3437
WorkspaceEntry,
3538
wrap_last_line_interactive,
3639
)
@@ -597,3 +600,56 @@ def _validate_relative_path(self, path_str: str) -> Path:
597600
raise ValueError("File path must not be empty.")
598601

599602
return Path(*sanitized_parts)
603+
604+
605+
def _stream_kube_output(
606+
exec_resp: Any,
607+
deadline: float,
608+
max_output_bytes: int,
609+
) -> Generator[StreamChunk, None, tuple[int | None, bool]]:
610+
"""Read stdout/stderr from a Kubernetes exec stream and yield StreamChunk events.
611+
612+
Returns a (exit_code, timed_out) tuple.
613+
"""
614+
stdout_bytes = 0
615+
stderr_bytes = 0
616+
exit_code: int | None = None
617+
timed_out = False
618+
619+
while exec_resp.is_open():
620+
remaining = deadline - time.time()
621+
if remaining <= 0:
622+
timed_out = True
623+
break
624+
625+
exec_resp.update(timeout=min(remaining, 1))
626+
627+
if exec_resp.peek_stdout():
628+
text: str = exec_resp.read_stdout()
629+
raw = text.encode("utf-8")
630+
if stdout_bytes < max_output_bytes:
631+
allowed = max_output_bytes - stdout_bytes
632+
if len(raw) > allowed:
633+
text = raw[:allowed].decode("utf-8", errors="ignore")
634+
if text:
635+
yield StreamChunk(stream="stdout", data=text)
636+
stdout_bytes += len(raw)
637+
638+
if exec_resp.peek_stderr():
639+
text = exec_resp.read_stderr()
640+
raw = text.encode("utf-8")
641+
if stderr_bytes < max_output_bytes:
642+
allowed = max_output_bytes - stderr_bytes
643+
if len(raw) > allowed:
644+
text = raw[:allowed].decode("utf-8", errors="ignore")
645+
if text:
646+
yield StreamChunk(stream="stderr", data=text)
647+
stderr_bytes += len(raw)
648+
649+
error: str = exec_resp.read_channel(ws_client.ERROR_CHANNEL)
650+
if error:
651+
exit_code = _parse_exit_code(error)
652+
break
653+
654+
exec_resp.close()
655+
return exit_code, timed_out

0 commit comments

Comments
 (0)