Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion changelog.d/f55-code-execution-text.changed.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
- `code_execution`'s result now reaches the model as text, where it was one line of JSON with the script's output escaped inside it. How the script ended comes first, as `exit code: N` and, when the call's `time_limit_ms` was capped, the time-limit note; then the script's stderr, then its stdout, each under a label. A result past the agent's inline cap (`tool_result_inline_max_chars`, 24,000 characters by default) is cut a stream at a time to each one's head and tail, around a count of what was cut, at a line's end where one is near: stderr keeps up to a third of the room, or more when stdout needs less, and its tail keeps its last line whole when that line fits. So at any cap that holds a cut of each stream, however long stdout runs, it no longer pushes the exit code and the end of stderr, which holds a traceback's last line and the reason a stopped script gives, past the cut. With a writable workspace mount that has no include list, the whole output goes to a file of its own in the folder a long result spills to, and the result's last line says where; without one, or when writing it fails, that line says what was cut wasn't kept. A cap too small to hold a cut of each stream beside that line, a few hundred characters, leaves the whole text to the inline cap's usual spill, which keeps its head.
- `code_execution`'s result now reaches the model as text, where it was one line of JSON with the script's output escaped inside it. How the script ended comes first, as `exit code: N` and, when the call's `time_limit_ms` was capped, the time-limit note; then the script's stderr, then its stdout, each under a label. A result past the agent's inline cap (`tool_result_inline_max_chars`, 24,000 characters by default) is cut a stream at a time to each one's head and tail, around a count of what was cut, at a line's end where one is near: stderr keeps up to a third of the room, or more when stdout needs less, and its tail keeps its last line whole when that line fits. So at any cap that holds a cut of each stream, however long stdout runs, it no longer pushes how the script ended, or the end of stderr, which holds a traceback's last line, past the cut. With a writable workspace mount that has no include list, the whole output goes to a file of its own in the folder a long result spills to, and the result's last line says where; without one, or when writing it fails, that line says what was cut wasn't kept. A cap too small to hold the opening lines and a cut of each stream beside that line, a few hundred characters more than the opening lines, leaves the whole text to the inline cap's usual spill, which keeps its head.
2 changes: 2 additions & 0 deletions changelog.d/feat-code-execution-calls-left-uncertain.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- When a `code_execution` script ends without the answers to some of its tool calls having been seen, because they were still running, or it timed out on them or cancelled them, its result names them, up to ten, and counts the rest by tool, so the agent can tell which effects may still come or came unseen. A call whose answer came after its code stopped waiting is named with the answer's start, and as answered with an error when the answer was one. The lines come in a foreground result's opening lines, after the exit code and the runner's own words, and also in the wake of a background script that dies and in the result of a `cancel`. After an error, a stop or a crash, the first line also counts the calls made while the script ran and those answered while it waited. A call from code an earlier script left running counts in the result of the script running when it's made, and one made while no script runs in the next one's, if its answer hasn't been seen by then. A tool call that times out in a script now raises a `TimeoutError` that says the call was sent and may still take effect, and the tool's description says so too.
- **Hosts:** `PyRunner`'s `ExecResult` carries `calls`, the tool calls made while the script ran, when there were any, as the host saw them when it read the script's end, and `runnerNote`, the runner's own words that end the result, which end `stderr` too, as they did. A foreground `code_execution` result's `structured` carries those lines first, as `tool_calls`, when the result has them. `PYTHON_RUNTIME_SOURCE` sends `{"op": "tool_unwaited", "id": …, "cause": "timeout"}` when the code that made a tool call stops waiting for it at its timeout, and `"cause": "cancelled"` when the script cancels it, which a host that runs the runtime itself can ignore. The `code_execution` tool's description changes, so each agent's prompt cache misses once after upgrading.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- A foreground `code_execution` result's opening lines now hold the runner's own words on how the script ended, such as why it stopped the script or why the script didn't run, after the exit code and the time-limit note, and the stderr the model reads goes without them, so they're said once.
2 changes: 1 addition & 1 deletion changelog.d/fix-code-execution-signal-advice.fixed.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
- When a crash's signal (SIGSEGV, SIGABRT, SIGBUS, SIGFPE or SIGILL) ends `code_execution`'s Python interpreter while a script runs, the result now says to check the traceback above it for the call that crashed in native code, such as an extension module the script uses, or, when no traceback reached the result, to check whether native code the script calls crashes. It used to say to check whether the script uses too much memory, which now comes only after SIGKILL, the signal the out-of-memory killer sends. Any other signal gets `os.kill()` as its example.
- When a crash's signal (SIGSEGV, SIGABRT, SIGBUS, SIGFPE or SIGILL) ends `code_execution`'s Python interpreter while a script runs, the result now says to check the traceback that starts "Fatal Python error:" for the call that crashed in native code, such as an extension module the script uses, or, when no traceback reached the result, to check whether native code the script calls crashes. It used to say to check whether the script uses too much memory, which now comes only after SIGKILL, the signal the out-of-memory killer sends. Any other signal gets `os.kill()` as its example.
6 changes: 5 additions & 1 deletion src/code-execution/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@
* (code_execution tool + tools exposed as async python functions), but runs
* the interpreter on the host and dispatches inner tool calls in-process
* through the framework's own tool routing — intermediate results never
* enter the model's context; the full trace stays on-box.
* enter the model's context, except the start of an answer that came after
* its call's code stopped waiting, which the result's line quotes (callsLine);
* the full trace stays on-box.
*/

export { PyRunner, buildInjectedTools } from './py-runner.js';
export type {
InjectedTool,
ExecResult,
ScriptCalls,
UncertainCall,
PyRunnerOptions,
ScriptToolCallHandler,
ScriptToolResult,
Expand Down
Loading
Loading