Skip to content
Merged
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 packages/cli/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@abox-dev/cli",
"version": "0.1.3",
"version": "0.1.4",
"description": "CLI for AgentBox sandboxes and templates",
"homepage": "https://docs.agentbox.ru/en/cli/",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion packages/code-interpreter-js/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@abox-dev/code-interpreter",
"version": "0.1.3",
"version": "0.1.4",
"packageManager": "pnpm@10.34.5",
"description": "AgentBox Code Interpreter - Stateful code execution",
"homepage": "https://docs.agentbox.ru/en/sdk/code-interpreter/",
Expand Down
2 changes: 1 addition & 1 deletion packages/code-interpreter-python/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@abox-dev/code-interpreter-python",
"private": true,
"version": "0.1.3",
"version": "0.1.4",
"scripts": {
"test": "uv run pytest -n 2 --verbose -x tests/test_sandbox_url.py",
"test:integration": "uv run pytest -n 2 --verbose -x",
Expand Down
2 changes: 1 addition & 1 deletion packages/code-interpreter-python/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "abox-code-interpreter"
version = "0.1.3"
version = "0.1.4"
description = "AgentBox Code Interpreter - Stateful code execution"
authors = [{ name = "RetailDriver LLC" }]
license = "MIT"
Expand Down
4 changes: 2 additions & 2 deletions packages/code-interpreter-python/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions packages/go-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ func main() {
Code Interpreter is available from
`github.com/abox-dev/sdk/packages/go-sdk/codeinterpreter`.

API reference for this release: [core SDK on pkg.go.dev](https://pkg.go.dev/github.com/abox-dev/sdk/packages/go-sdk@v0.1.3) and
[Code Interpreter on pkg.go.dev](https://pkg.go.dev/github.com/abox-dev/sdk/packages/go-sdk/codeinterpreter@v0.1.3).
API reference for this release: [core SDK on pkg.go.dev](https://pkg.go.dev/github.com/abox-dev/sdk/packages/go-sdk@v0.1.4) and
[Code Interpreter on pkg.go.dev](https://pkg.go.dev/github.com/abox-dev/sdk/packages/go-sdk/codeinterpreter@v0.1.4).

Documentation: [core SDK](https://docs.agentbox.ru/en/sdk/),
[sandboxes](https://docs.agentbox.ru/en/sdk/sandboxes/),
Expand Down
4 changes: 4 additions & 0 deletions packages/go-sdk/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,11 @@ func (builder *TemplateBuilder) Run(commands ...string) *TemplateBuilder {
}

// RunAs adds shell commands executed as user.
// An empty user inherits the current build user, as Run does.
func (builder *TemplateBuilder) RunAs(user string, commands ...string) *TemplateBuilder {
if user == "" {
return builder.Run(commands...)
}
return builder.add("RUN", strings.Join(commands, " && "), user)
}

Expand Down
67 changes: 67 additions & 0 deletions packages/go-sdk/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,84 @@ package agentbox

import (
"context"
"encoding/json"
"errors"
"fmt"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"slices"
"strings"
"testing"
"time"
)

func TestTemplateRunUserArguments(t *testing.T) {
tests := []struct {
name string
apply func(*TemplateBuilder) *TemplateBuilder
args []string
}{
{"run-as-current", func(b *TemplateBuilder) *TemplateBuilder { return b.RunAs("", "echo one", "echo two") }, []string{"echo one && echo two"}},
{"run-as-explicit", func(b *TemplateBuilder) *TemplateBuilder { return b.RunAs("root", "id -un") }, []string{"id -un", "root"}},
{"npm-default", func(b *TemplateBuilder) *TemplateBuilder { return b.NPMInstall(PackageInstallOptions{}, "lodash") }, []string{"npm install lodash"}},
{"npm-dev", func(b *TemplateBuilder) *TemplateBuilder {
return b.NPMInstall(PackageInstallOptions{Dev: true}, "typescript")
}, []string{"npm install --save-dev typescript"}},
{"npm-global", func(b *TemplateBuilder) *TemplateBuilder {
return b.NPMInstall(PackageInstallOptions{Global: true}, "tsx")
}, []string{"npm install -g tsx", "root"}},
{"bun-default", func(b *TemplateBuilder) *TemplateBuilder { return b.BunInstall(PackageInstallOptions{}, "lodash") }, []string{"bun install lodash"}},
{"bun-dev", func(b *TemplateBuilder) *TemplateBuilder {
return b.BunInstall(PackageInstallOptions{Dev: true}, "typescript")
}, []string{"bun install --dev typescript"}},
{"bun-global", func(b *TemplateBuilder) *TemplateBuilder {
return b.BunInstall(PackageInstallOptions{Global: true}, "tsx")
}, []string{"bun install -g tsx", "root"}},
{"git-default", func(b *TemplateBuilder) *TemplateBuilder { return b.GitClone("https://example.test/repo.git", nil) }, []string{"git clone 'https://example.test/repo.git'"}},
{"git-options", func(b *TemplateBuilder) *TemplateBuilder {
return b.GitClone("https://example.test/repo.git", &GitCloneOptions{Path: "repo", Depth: 1})
}, []string{"git clone 'https://example.test/repo.git' --depth 1 'repo'"}},
{"git-explicit", func(b *TemplateBuilder) *TemplateBuilder {
return b.GitClone("https://example.test/repo.git", &GitCloneOptions{User: "root"})
}, []string{"git clone 'https://example.test/repo.git'", "root"}},
}
for _, currentUser := range []string{"", "app"} {
for _, test := range tests {
t.Run(currentUser+"/"+test.name, func(t *testing.T) {
builder := NewTemplate("").FromBase()
if currentUser != "" {
builder.User(currentUser)
}
data, err := test.apply(builder).JSON()
if err != nil {
t.Fatal(err)
}
var request struct {
Steps []struct {
Type string `json:"type"`
Args []string `json:"args"`
} `json:"steps"`
}
if err := json.Unmarshal(data, &request); err != nil {
t.Fatal(err)
}
if len(request.Steps) == 0 {
t.Fatal("missing build steps")
}
step := request.Steps[len(request.Steps)-1]
if step.Type != "RUN" || !slices.Equal(step.Args, test.args) {
t.Fatalf("RUN arguments = %#v, want %#v (type %q)", step.Args, test.args, step.Type)
}
if currentUser != "" && (request.Steps[0].Type != "USER" || !slices.Equal(request.Steps[0].Args, []string{currentUser})) {
t.Fatal("configured build user was not preserved")
}
})
}
}
}

func TestTemplateBuilder(t *testing.T) {
contextPath := t.TempDir()
if err := os.WriteFile(filepath.Join(contextPath, "hello.txt"), []byte("hello"), 0o600); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion packages/go-sdk/version.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package agentbox

// Version is the AgentBox SDK release version.
const Version = "0.1.3"
const Version = "0.1.4"
2 changes: 1 addition & 1 deletion packages/js-sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@abox-dev/sdk",
"version": "0.1.3",
"version": "0.1.4",
"description": "AgentBox SDK for secure cloud sandboxes",
"homepage": "https://docs.agentbox.ru/en/sdk/",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion packages/python-sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@abox-dev/python-sdk",
"private": true,
"version": "0.1.3",
"version": "0.1.4",
"scripts": {
"test": "uv run pytest -n 4 --verbose -x tests/test_*.py tests/shared",
"test:integration": "uv run pytest -n 4 --verbose -x tests/sync tests/async",
Expand Down
2 changes: 1 addition & 1 deletion packages/python-sdk/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "abox-sdk"
version = "0.1.3"
version = "0.1.4"
description = "AgentBox SDK for secure cloud sandboxes"
authors = [{ name = "RetailDriver LLC" }]
license = "MIT"
Expand Down
2 changes: 1 addition & 1 deletion packages/python-sdk/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 7 additions & 7 deletions reference/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"sdk/cli/sandbox.md": "16b64c5a4e932eca2452e400e0faf154eba1d3c7373513aa7cd9744e02908313",
"sdk/cli/template.md": "f270b22b9ee10a9b954a14f24e04c5449b4d5823bb28002ffde3ed682594cfc5",
"sdk/go/code-interpreter.md": "9c56333b8181878d656baa27a4b56b768a0cb01c9d764f7ac8d52d32d8faa70c",
"sdk/go/core.md": "ab075a4a3fbafaefb21e58596311fecb24e614240827c7a322a008c3ac06df1c",
"sdk/go/core.md": "41d700b3837e9aa7932779ba44186aaf0c54a6927ebaafa7945b0037b76db49e",
"sdk/javascript/code-interpreter/README.md": "a787206eb86f81fc306b373ce20bc6c91464b0ab3c3ec7650eccbb6be5f676c5",
"sdk/javascript/code-interpreter/classes/Sandbox.md": "19d9f1f1e8847606a54d93c5a6e5d4c89f936a745866e8d6a2aa06758b605e60",
"sdk/javascript/code-interpreter/enumerations/ChartType.md": "cf1ba00cd3258cc88814b7215e101b0d775ceb15dd833636d58ae538d8107ec1",
Expand Down Expand Up @@ -184,12 +184,12 @@
},
"monoRevision": "559cf23aa80d22eeb1bd2769d4ab6646b8e40fcb",
"packages": {
"@abox-dev/cli": "0.1.3",
"@abox-dev/code-interpreter": "0.1.3",
"@abox-dev/sdk": "0.1.3",
"abox-code-interpreter": "0.1.3",
"abox-sdk": "0.1.3",
"github.com/abox-dev/sdk/packages/go-sdk": "0.1.3"
"@abox-dev/cli": "0.1.4",
"@abox-dev/code-interpreter": "0.1.4",
"@abox-dev/sdk": "0.1.4",
"abox-code-interpreter": "0.1.4",
"abox-sdk": "0.1.4",
"github.com/abox-dev/sdk/packages/go-sdk": "0.1.4"
},
"schemaVersion": 1
}
4 changes: 2 additions & 2 deletions reference/sdk/go/core.md
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ Create a client, start a sandbox, and run a command:

<a name="Version"></a>Version is the AgentBox SDK release version.

const Version = "0.1.3"
const Version = "0.1.4"

<a name="IAMTokenPlaceholder"></a>
## func IAMTokenPlaceholder
Expand Down Expand Up @@ -1927,7 +1927,7 @@ Run adds shell commands executed as the current build user.

func (builder *TemplateBuilder) RunAs(user string, commands ...string) *TemplateBuilder

RunAs adds shell commands executed as user.
RunAs adds shell commands executed as user. An empty user inherits the current build user, as Run does.

<a name="TemplateBuilder.SkipCache"></a>
### func \(\*TemplateBuilder\) SkipCache
Expand Down
39 changes: 39 additions & 0 deletions tests/runtime/go/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ func main() {
must(err)
sandbox, err := core.Sandboxes.Create(ctx, &agentbox.CreateSandboxOptions{Timeout: 5 * time.Minute})
must(err)
defer func() { _, _ = sandbox.Kill(context.Background()) }()
result, err := sandbox.Commands.Run(ctx, "printf", &agentbox.CommandOptions{Args: []string{"go-runtime-smoke"}})
must(err)
if string(result.Stdout) != "go-runtime-smoke" {
Expand All @@ -34,6 +35,7 @@ func main() {
must(err)
codeSandbox, err := interpreter.Create(ctx, &agentbox.CreateSandboxOptions{Timeout: 5 * time.Minute})
must(err)
defer func() { _, _ = codeSandbox.Kill(context.Background()) }()
execution, err := codeSandbox.RunCode(ctx, "40 + 2", nil)
must(err)
if !strings.Contains(execution.Text(), "42") {
Expand All @@ -44,6 +46,43 @@ func main() {
if !killed {
panic("code interpreter sandbox was not killed")
}
templateUserSmoke(ctx, core)
}

func templateUserSmoke(ctx context.Context, client *agentbox.Client) {
name := fmt.Sprintf("sdk-go-user-smoke-%d", time.Now().UnixNano())
builder := agentbox.NewTemplate("").FromTemplate("base").User("user").Workdir("/home/user").
RunAs("", "test \"$(id -un)\" = user", "mkdir -p sdk-user-smoke", "printf '{\"name\":\"sdk-user-smoke\",\"version\":\"1.0.0\"}' >sdk-user-smoke/package.json", "git init --bare sdk-user-smoke/source.git").
Workdir("/home/user/sdk-user-smoke").
NPMInstall(agentbox.PackageInstallOptions{}).
GitClone("/home/user/sdk-user-smoke/source.git", &agentbox.GitCloneOptions{Path: "checkout"}).
RunAs("root", "test \"$(id -un)\" = root").
Run("test \"$(id -un)\" = user", "test -f package-lock.json", "test -d checkout/.git")
reference, err := client.Templates.BuildInBackground(ctx, builder, name, nil)
must(err)
defer func() {
cleanupCtx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()
must(client.Templates.Delete(cleanupCtx, reference.TemplateID))
}()
for {
status, err := client.Templates.BuildStatus(ctx, reference.TemplateID, reference.BuildID, 0)
must(err)
if status.Status == agentbox.BuildReady {
fmt.Println("Go template user inheritance smoke passed")
return
}
if status.Status == agentbox.BuildFailed {
panic(fmt.Sprintf("template user smoke failed: %+v", status.Reason))
}
timer := time.NewTimer(time.Second)
select {
case <-ctx.Done():
timer.Stop()
panic(ctx.Err())
case <-timer.C:
}
}
}

func must(err error) {
Expand Down
Loading