Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
71d1ad5
init commit
sid-rl Dec 6, 2025
853a998
formatting fix
sid-rl Dec 8, 2025
1630a87
clean up imports in scenario ops unit tests
sid-rl Dec 9, 2025
f3145a9
use Blueprint and Snapshot objects directly in ScenarioBuilder
sid-rl Dec 9, 2025
01cdb36
consolidate from_blueprint and from_snapshot unit tests
sid-rl Dec 9, 2025
1868d9f
further consolidate scenario builder unit tests, make sure async cove…
sid-rl Dec 9, 2025
9ecbc3d
stricter type declaration for _build_params
sid-rl Dec 10, 2025
9908844
expose request options in push()
sid-rl Dec 10, 2025
9511827
add scenario creation smoketests, with push_or_update logic
sid-rl Dec 10, 2025
c145f3b
update sdk smoke tests with all ops
sid-rl Dec 10, 2025
c1e9936
avoid modifyng _scorers internal state when normalizing weights (crea…
sid-rl Dec 10, 2025
2592482
formatting fixes
sid-rl Dec 10, 2025
8750137
update builder docstrings to use fluent pattern, replaced all referen…
sid-rl Dec 10, 2025
b2084a9
clarify from_blueprint and from_snapshot docstrings
sid-rl Dec 10, 2025
6132ca8
rename add_scorer methods to be more clear
sid-rl Dec 10, 2025
e8d024d
format fix
sid-rl Dec 10, 2025
a70af1b
address type check errors in scenario builder unit tests
sid-rl Dec 10, 2025
1242c7f
rename add_scorer methods in docstrings
sid-rl Dec 10, 2025
cdb28a1
make sure it is clear that score is 0.0-1.0 inclusive
sid-rl Dec 10, 2025
1727c2e
update script scorer docstrings
sid-rl Dec 10, 2025
30c4497
formatting
sid-rl Dec 10, 2025
797c6fd
clarify reference solution/gold patch terminology and validation stra…
sid-rl Dec 10, 2025
a099739
make name first argument passed to scenario builder
sid-rl Dec 10, 2025
cd9adce
add preview method
sid-rl Dec 10, 2025
034399b
clean up unit test imports, rename builder fixture to mock_builder
sid-rl Dec 10, 2025
1fffeeb
added `preview()` method to scenario builder
sid-rl Dec 11, 2025
44ae5d0
rename `_build_params` to `build` (now publicly exposed method)
sid-rl Dec 11, 2025
49ff2c2
formatting
sid-rl Dec 11, 2025
cc77ba4
update docstring examples to use builder.build() instead of builder.p…
sid-rl Dec 11, 2025
e2c0b5c
formatting
sid-rl Dec 11, 2025
5f1e260
update with_problem_statement and with_additional_context docstrings
sid-rl Dec 11, 2025
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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ For a higher-level, Pythonic interface, check out the new [`RunloopSDK`](README-
```python
from runloop_api_client import RunloopSDK

sdk = RunloopSDK() # Uses RUNLOOP_API_KEY environment variable by default
runloop = RunloopSDK() # Uses RUNLOOP_API_KEY environment variable by default

# Create a devbox and execute commands with a clean, object-oriented interface
with sdk.devbox.create(name="my-devbox") as devbox:
with runloop.devbox.create(name="my-devbox") as devbox:
result = devbox.cmd.exec("echo 'Hello from Runloop!'")
print(result.stdout())
```
Expand Down
6 changes: 6 additions & 0 deletions src/runloop_api_client/sdk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from .sync import AgentOps, DevboxOps, ScorerOps, RunloopSDK, ScenarioOps, SnapshotOps, BlueprintOps, StorageObjectOps
from .agent import Agent
from ._types import ScenarioPreview
from .async_ import (
AsyncAgentOps,
AsyncDevboxOps,
Expand All @@ -33,9 +34,11 @@
from .async_blueprint import AsyncBlueprint
from .async_execution import AsyncExecution
from .execution_result import ExecutionResult
from .scenario_builder import ScenarioBuilder
from .async_scenario_run import AsyncScenarioRun
from .async_storage_object import AsyncStorageObject
from .async_execution_result import AsyncExecutionResult
from .async_scenario_builder import AsyncScenarioBuilder

__all__ = [
# Main SDK entry points
Expand Down Expand Up @@ -71,6 +74,9 @@
"AsyncScenario",
"ScenarioRun",
"AsyncScenarioRun",
"ScenarioBuilder",
"AsyncScenarioBuilder",
"ScenarioPreview",
"Scorer",
"AsyncScorer",
"Snapshot",
Expand Down
17 changes: 17 additions & 0 deletions src/runloop_api_client/sdk/_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from ..lib.polling import PollingConfig
from ..types.devboxes import DiskSnapshotListParams, DiskSnapshotUpdateParams
from ..types.scenarios import ScorerListParams, ScorerCreateParams, ScorerUpdateParams, ScorerValidateParams
from ..types.input_context import InputContext
from ..types.scenario_view import ScenarioView
from ..types.agent_list_params import AgentListParams
from ..types.devbox_list_params import DevboxListParams
from ..types.object_list_params import ObjectListParams
Expand Down Expand Up @@ -186,3 +188,18 @@ class SDKScenarioRunAsyncParams(ScenarioStartRunBaseParams, LongRequestOptions):

class SDKScenarioRunParams(ScenarioStartRunBaseParams, LongPollingRequestOptions):
pass


class InputContextPreview(InputContext):
problem_statement: Optional[str] = None # type: ignore[assignment]
"""The problem statement for the Scenario."""


class ScenarioPreview(ScenarioView):
"""Preview of scenario configuration with all fields optional."""

id: Optional[str] = None # type: ignore[assignment]
"""The ID of the Scenario."""

input_context: InputContextPreview # type: ignore[assignment]
"""The input context for the Scenario."""
21 changes: 21 additions & 0 deletions src/runloop_api_client/sdk/async_.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
from .async_blueprint import AsyncBlueprint
from ..lib.context_loader import TarFilter, build_directory_tar
from .async_storage_object import AsyncStorageObject
from .async_scenario_builder import AsyncScenarioBuilder
from ..types.object_create_params import ContentType
from ..types.shared_params.agent_source import Git, Npm, Pip, Object

Expand Down Expand Up @@ -773,6 +774,16 @@ class AsyncScenarioOps:
>>> scenario = runloop.scenario.from_id("scn-xxx")
>>> run = await scenario.run()
>>> scenarios = await runloop.scenario.list()

Example using builder:
>>> builder = (
... runloop.scenario.builder("my-scenario")
... .from_blueprint(blueprint)
... .with_problem_statement("Fix the bug")
... .add_test_command_scorer("tests", test_command="pytest")
... )
>>> params = builder.build()
>>> scenario = await runloop.scenario.create(**params) # equivalent to builder.push()
"""

def __init__(self, client: AsyncRunloop) -> None:
Expand All @@ -783,6 +794,16 @@ def __init__(self, client: AsyncRunloop) -> None:
"""
self._client = client

def builder(self, name: str) -> AsyncScenarioBuilder:
"""Create a new scenario builder.

:param name: Name for the scenario
:type name: str
:return: A new AsyncScenarioBuilder instance
:rtype: AsyncScenarioBuilder
"""
return AsyncScenarioBuilder(name, self._client)

def from_id(self, scenario_id: str) -> AsyncScenario:
"""Get an AsyncScenario instance for an existing scenario ID.

Expand Down
Loading