Skip to content
Open
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
9 changes: 7 additions & 2 deletions artifacts/sdk-docs/go-sdk/types.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,13 @@ ExecuteResponse represents a command execution response

```go
type ExecuteResponse struct {
ExitCode int
Result string
ExitCode int
// Result is the combined stdout and stderr in arrival order (interleaved)
Result string
// Stdout is the standard output only; nil when the sandbox daemon predates split streams
Stdout *string
// Stderr is the standard error only; nil when the sandbox daemon predates split streams
Stderr *string
Artifacts *ExecutionArtifacts // nil when no artifacts available
}
```
Expand Down
13 changes: 11 additions & 2 deletions artifacts/sdk-docs/python-sdk/async/async-process.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ Execute a shell command in the Sandbox.

- `ExecuteResponse` - Command execution results containing:
- exit_code: The command's exit status
- result: Standard output from the command
- result: Combined stdout and stderr from the command (interleaved)
Comment thread
MDzaja marked this conversation as resolved.
- stdout: Standard output only; None when the sandbox daemon predates split streams
- stderr: Standard error only; None when the sandbox daemon predates split streams
- artifacts: ExecutionArtifacts object containing `stdout` (same as result)
and `charts` (matplotlib charts metadata)

Expand All @@ -62,6 +64,11 @@ Execute a shell command in the Sandbox.
response = await sandbox.process.exec("echo 'Hello'")
print(response.artifacts.stdout) # Prints: Hello

# Split streams
response = await sandbox.process.exec("echo out; echo err >&2")
print(response.stdout) # Prints: out
print(response.stderr) # Prints: err

# Command with working directory
result = await sandbox.process.exec("ls", cwd="workspace/src")

Expand Down Expand Up @@ -866,7 +873,9 @@ Response from the command execution.
**Attributes**:

- `exit_code` _int_ - The exit code from the command execution
- `result` _str_ - The output from the command execution
- `result` _str_ - Combined stdout and stderr from the command execution (interleaved)
- `stdout` _str | None_ - Standard output only; None when the sandbox daemon predates split streams
- `stderr` _str | None_ - Standard error only; None when the sandbox daemon predates split streams
- `artifacts` _ExecutionArtifacts | None_ - Artifacts from the command execution

## SessionExecuteResponse
Expand Down
13 changes: 11 additions & 2 deletions artifacts/sdk-docs/python-sdk/sync/process.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ Execute a shell command in the Sandbox.

- `ExecuteResponse` - Command execution results containing:
- exit_code: The command's exit status
- result: Standard output from the command
- result: Combined stdout and stderr from the command (interleaved)
- stdout: Standard output only; None when the sandbox daemon predates split streams
- stderr: Standard error only; None when the sandbox daemon predates split streams
- artifacts: ExecutionArtifacts object containing `stdout` (same as result)
and `charts` (matplotlib charts metadata)

Expand All @@ -63,6 +65,11 @@ Execute a shell command in the Sandbox.
response = sandbox.process.exec("echo 'Hello'")
print(response.artifacts.stdout) # Prints: Hello

# Split streams
response = sandbox.process.exec("echo out; echo err >&2")
print(response.stdout) # Prints: out
print(response.stderr) # Prints: err

# Command with working directory
result = sandbox.process.exec("ls", cwd="workspace/src")

Expand Down Expand Up @@ -857,7 +864,9 @@ Response from the command execution.
**Attributes**:

- `exit_code` _int_ - The exit code from the command execution
- `result` _str_ - The output from the command execution
- `result` _str_ - Combined stdout and stderr from the command execution (interleaved)
Comment thread
MDzaja marked this conversation as resolved.
- `stdout` _str | None_ - Standard output only; None when the sandbox daemon predates split streams
- `stderr` _str | None_ - Standard error only; None when the sandbox daemon predates split streams
- `artifacts` _ExecutionArtifacts | None_ - Artifacts from the command execution

## SessionExecuteResponse
Expand Down
3 changes: 2 additions & 1 deletion artifacts/sdk-docs/ruby-sdk/process.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ Execute a shell command in the Sandbox

**Returns**:

- `ExecuteResponse` - Command execution results containing exit_code, result, and artifacts
- `ExecuteResponse` - Command execution results containing exit_code, combined stdout and stderr (interleaved) as result,
split stdout/stderr (nil when the sandbox daemon predates split streams), and artifacts

**Examples:**

Expand Down
4 changes: 3 additions & 1 deletion artifacts/sdk-docs/typescript-sdk/execute-response.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ Response from the command execution.

- `artifacts?` _ExecutionArtifacts_ - Artifacts from the command execution
- `exitCode` _number_ - The exit code from the command execution
- `result` _string_ - The output from the command execution
- `result` _string_ - Combined stdout and stderr from the command execution (interleaved)
- `stderr?` _string_ - Standard error only; undefined when the sandbox daemon predates split streams
- `stdout?` _string_ - Standard output only; undefined when the sandbox daemon predates split streams
## ExecutionArtifacts

Artifacts from the command execution.
Expand Down
11 changes: 10 additions & 1 deletion artifacts/sdk-docs/typescript-sdk/process.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,9 @@ Executes a shell command in the Sandbox.

- `Promise<ExecuteResponse>` - Command execution results containing:
- exitCode: The command's exit status
- result: Standard output from the command
- result: Combined stdout and stderr from the command (interleaved)
- stdout: Standard output only; undefined when the sandbox daemon predates split streams
- stderr: Standard error only; undefined when the sandbox daemon predates split streams
- artifacts: ExecutionArtifacts object containing `stdout` (same as result) and `charts` (matplotlib charts metadata)

**Examples:**
Expand All @@ -333,6 +335,13 @@ const response = await process.executeCommand('echo "Hello"');
console.log(response.artifacts.stdout); // Prints: Hello
```

```ts
// Split streams
const response = await process.executeCommand('echo out; echo err >&2');
console.log(response.stdout); // Prints: out
console.log(response.stderr); // Prints: err
```

```ts
// Command with working directory
const result = await process.executeCommand('ls', 'workspace/src');
Expand Down
9 changes: 9 additions & 0 deletions openapi-specs/toolbox.json
Original file line number Diff line number Diff line change
Expand Up @@ -4427,6 +4427,15 @@
"type": "integer"
},
"result": {
"description": "Combined stdout and stderr in arrival order (interleaved)",
"type": "string"
},
"stderr": {
"description": "Standard error only; omitted by daemons that predate split streams",
"type": "string"
},
"stdout": {
"description": "Standard output only; omitted by daemons that predate split streams",
"type": "string"
}
}
Expand Down
2 changes: 2 additions & 0 deletions sdk-go/pkg/daytona/process.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ func (p *ProcessService) ExecuteCommand(ctx context.Context, command string, opt
return &types.ExecuteResponse{
ExitCode: exitCode,
Result: resp.Result,
Stdout: resp.Stdout,
Stderr: resp.Stderr,
Artifacts: &types.ExecutionArtifacts{
Stdout: resp.Result,
},
Expand Down
9 changes: 7 additions & 2 deletions sdk-go/pkg/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -377,8 +377,13 @@ type CodeRunParams struct {

// ExecuteResponse represents a command execution response
type ExecuteResponse struct {
ExitCode int
Result string
ExitCode int
// Result is the combined stdout and stderr in arrival order (interleaved)
Result string
// Stdout is the standard output only; nil when the sandbox daemon predates split streams
Stdout *string
// Stderr is the standard error only; nil when the sandbox daemon predates split streams
Stderr *string
Artifacts *ExecutionArtifacts // nil when no artifacts available
}

Expand Down
32 changes: 32 additions & 0 deletions sdk-java/src/main/java/io/daytona/sdk/model/ExecuteResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ public ExecuteResponse(io.daytona.toolbox.client.model.ExecuteResponse source) {
if (source != null) {
setExitCode(source.getExitCode());
setResult(source.getResult());
setStdout(source.getStdout());
setStderr(source.getStderr());
}
}

Expand All @@ -35,4 +37,34 @@ public CodeRunArtifacts getArtifacts() {
public void setArtifacts(CodeRunArtifacts artifacts) {
this.artifacts = artifacts;
}

/**
* Gets the combined stdout and stderr (interleaved).
*
* @return combined stdout and stderr (interleaved)
*/
@Override
public String getResult() {
return super.getResult();
}

/**
* Gets the split stdout stream; null when the sandbox daemon predates split streams.
*
* @return split stdout stream, or {@code null}
*/
@Override
public String getStdout() {
return super.getStdout();
}

/**
* Gets the split stderr stream; null when the sandbox daemon predates split streams.
*
* @return split stderr stream, or {@code null}
*/
@Override
public String getStderr() {
return super.getStderr();
}
}
18 changes: 18 additions & 0 deletions sdk-java/src/test/java/io/daytona/sdk/ProcessTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,18 +72,36 @@ void executeCommandUsesMinimalRequest() {
io.daytona.toolbox.client.model.ExecuteResponse response = new io.daytona.toolbox.client.model.ExecuteResponse();
response.setExitCode(0);
response.setResult("ok");
response.setStdout("out");
response.setStderr("err");
when(processApi.executeCommand(any())).thenReturn(response);

ExecuteResponse result = process.executeCommand("echo hello");

assertThat(result.getExitCode()).isEqualTo(0);
assertThat(result.getResult()).isEqualTo("ok");
assertThat(result.getStdout()).isEqualTo("out");
assertThat(result.getStderr()).isEqualTo("err");
ArgumentCaptor<ExecuteRequest> captor = ArgumentCaptor.forClass(ExecuteRequest.class);
verify(processApi).executeCommand(captor.capture());
assertThat(captor.getValue().getCommand()).isEqualTo("echo hello");
assertThat(captor.getValue().getCwd()).isNull();
}

@Test
void executeCommandKeepsSplitStreamsNullForOlderDaemons() {
io.daytona.toolbox.client.model.ExecuteResponse response = new io.daytona.toolbox.client.model.ExecuteResponse();
response.setExitCode(0);
response.setResult("combined");
when(processApi.executeCommand(any())).thenReturn(response);

ExecuteResponse result = process.executeCommand("echo hello");

assertThat(result.getResult()).isEqualTo("combined");
assertThat(result.getStdout()).isNull();
assertThat(result.getStderr()).isNull();
}

@Test
void executeCommandPassesCwdEnvAndTimeout() {
Map<String, String> env = new HashMap<String, String>();
Expand Down
11 changes: 10 additions & 1 deletion sdk-python/src/daytona/_async/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,9 @@ async def exec(
Returns:
ExecuteResponse: Command execution results containing:
- exit_code: The command's exit status
- result: Standard output from the command
- result: Combined stdout and stderr from the command (interleaved)
- stdout: Standard output only; None when the sandbox daemon predates split streams
- stderr: Standard error only; None when the sandbox daemon predates split streams
- artifacts: ExecutionArtifacts object containing `stdout` (same as result)
and `charts` (matplotlib charts metadata)

Expand All @@ -115,6 +117,11 @@ async def exec(
response = await sandbox.process.exec("echo 'Hello'")
print(response.artifacts.stdout) # Prints: Hello

# Split streams
response = await sandbox.process.exec("echo out; echo err >&2")
print(response.stdout) # Prints: out
print(response.stderr) # Prints: err

# Command with working directory
result = await sandbox.process.exec("ls", cwd="workspace/src")

Expand All @@ -138,6 +145,8 @@ async def exec(
response.exit_code if response.exit_code is not None else response.additional_properties.get("code")
),
result=result,
stdout=response.stdout,
stderr=response.stderr,
artifacts=artifacts,
additional_properties=response.additional_properties,
)
Expand Down
11 changes: 10 additions & 1 deletion sdk-python/src/daytona/_sync/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,9 @@ def exec(
Returns:
ExecuteResponse: Command execution results containing:
- exit_code: The command's exit status
- result: Standard output from the command
- result: Combined stdout and stderr from the command (interleaved)
- stdout: Standard output only; None when the sandbox daemon predates split streams
- stderr: Standard error only; None when the sandbox daemon predates split streams
- artifacts: ExecutionArtifacts object containing `stdout` (same as result)
and `charts` (matplotlib charts metadata)

Expand All @@ -111,6 +113,11 @@ def exec(
response = sandbox.process.exec("echo 'Hello'")
print(response.artifacts.stdout) # Prints: Hello

# Split streams
response = sandbox.process.exec("echo out; echo err >&2")
print(response.stdout) # Prints: out
print(response.stderr) # Prints: err

# Command with working directory
result = sandbox.process.exec("ls", cwd="workspace/src")

Expand All @@ -133,6 +140,8 @@ def exec(
response.exit_code if response.exit_code is not None else response.additional_properties.get("code")
),
result=result,
stdout=response.stdout,
stderr=response.stderr,
artifacts=artifacts,
additional_properties=response.additional_properties,
)
Expand Down
6 changes: 5 additions & 1 deletion sdk-python/src/daytona/common/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,16 @@ class ExecuteResponse(BaseModel):

Attributes:
exit_code (int): The exit code from the command execution
result (str): The output from the command execution
result (str): Combined stdout and stderr from the command execution (interleaved)
stdout (str | None): Standard output only; None when the sandbox daemon predates split streams
stderr (str | None): Standard error only; None when the sandbox daemon predates split streams
artifacts (ExecutionArtifacts | None): Artifacts from the command execution
"""

exit_code: int
result: str
stdout: str | None = None
stderr: str | None = None
artifacts: ExecutionArtifacts | None = None
additional_properties: dict[str, object] = Field(default_factory=dict)

Expand Down
20 changes: 20 additions & 0 deletions sdk-python/tests/test_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,26 @@ def test_exec_falls_back_to_additional_properties_code(self):
result = proc.exec("false")
assert result.exit_code == 42

def test_exec_returns_split_streams(self):
proc, api = self._make_process()
api.execute_command.return_value = MagicMock(
result="out\nerr\n", exit_code=0, stdout="out\n", stderr="err\n", additional_properties={}
)
result = proc.exec("echo out; echo err >&2")
assert result.result == "out\nerr\n"
assert result.stdout == "out\n"
assert result.stderr == "err\n"

def test_exec_split_streams_none_on_old_daemon(self):
proc, api = self._make_process()
api.execute_command.return_value = MagicMock(
result="combined", exit_code=0, stdout=None, stderr=None, additional_properties={}
)
result = proc.exec("echo combined")
assert result.result == "combined"
assert result.stdout is None
assert result.stderr is None

def test_code_run_uses_language_and_params(self):
proc, api = self._make_process()
api.code_run.return_value = MagicMock(
Expand Down
16 changes: 13 additions & 3 deletions sdk-ruby/lib/daytona/common/process.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,15 @@ class ExecuteResponse
# @return [Integer] The exit code from the command execution
attr_reader :exit_code

# @return [String] The output from the command execution
# @return [String] Combined stdout and stderr (interleaved)
attr_reader :result

# @return [String, nil] Split stdout; nil when the sandbox daemon predates split streams
attr_reader :stdout

# @return [String, nil] Split stderr; nil when the sandbox daemon predates split streams
attr_reader :stderr

# @return [ExecutionArtifacts, nil] Artifacts from the command execution
attr_reader :artifacts

Expand All @@ -20,12 +26,16 @@ class ExecuteResponse
# Initialize a new ExecuteResponse
#
# @param exit_code [Integer] The exit code from the command execution
# @param result [String] The output from the command execution
# @param result [String] Combined stdout and stderr (interleaved)
# @param stdout [String, nil] Split stdout; nil when the sandbox daemon predates split streams
# @param stderr [String, nil] Split stderr; nil when the sandbox daemon predates split streams
# @param artifacts [ExecutionArtifacts, nil] Artifacts from the command execution
# @param additional_properties [Hash] Additional properties from the response
def initialize(exit_code:, result:, artifacts: nil, additional_properties: {})
def initialize(exit_code:, result:, stdout: nil, stderr: nil, artifacts: nil, additional_properties: {})
@exit_code = exit_code
@result = result
@stdout = stdout
@stderr = stderr
@artifacts = artifacts
@additional_properties = additional_properties
end
Expand Down
Loading
Loading