From 58566a09efb07242ec7f0b4d4052b0a07c316e0e Mon Sep 17 00:00:00 2001 From: Ilyas Salikhov Date: Thu, 17 Sep 2026 06:36:48 +0300 Subject: [PATCH] fix: align direct sandbox hosts and prepare v0.1.7 --- packages/cli/package.json | 2 +- packages/code-interpreter-js/package.json | 2 +- packages/code-interpreter-python/package.json | 2 +- .../code-interpreter-python/pyproject.toml | 2 +- packages/code-interpreter-python/uv.lock | 4 +- packages/go-sdk/README.md | 4 +- packages/go-sdk/sandbox.go | 6 +- packages/go-sdk/sandbox_test.go | 38 ++++ packages/go-sdk/version.go | 2 +- packages/js-sdk/package.json | 2 +- .../python-sdk/agentbox/connection_config.py | 7 +- packages/python-sdk/package.json | 2 +- packages/python-sdk/pyproject.toml | 2 +- .../tests/test_connection_config.py | 19 ++ packages/python-sdk/uv.lock | 2 +- reference-config/javascript/errors.ts | 1 + reference/manifest.json | 19 +- reference/sdk/go/core.md | 2 +- reference/sdk/javascript/errors/README.md | 1 + .../errors/classes/CommandNotFoundError.md | 185 ++++++++++++++++++ .../javascript/errors/classes/SandboxError.md | 1 + 21 files changed, 280 insertions(+), 25 deletions(-) create mode 100644 reference/sdk/javascript/errors/classes/CommandNotFoundError.md diff --git a/packages/cli/package.json b/packages/cli/package.json index 1614aac5..6ca67883 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@abox-dev/cli", - "version": "0.1.6", + "version": "0.1.7", "description": "CLI for AgentBox sandboxes and templates", "homepage": "https://docs.agentbox.ru/en/cli/", "license": "MIT", diff --git a/packages/code-interpreter-js/package.json b/packages/code-interpreter-js/package.json index 93e72d64..b62cc8a9 100644 --- a/packages/code-interpreter-js/package.json +++ b/packages/code-interpreter-js/package.json @@ -1,6 +1,6 @@ { "name": "@abox-dev/code-interpreter", - "version": "0.1.6", + "version": "0.1.7", "packageManager": "pnpm@10.34.5", "description": "AgentBox Code Interpreter - Stateful code execution", "homepage": "https://docs.agentbox.ru/en/sdk/code-interpreter/", diff --git a/packages/code-interpreter-python/package.json b/packages/code-interpreter-python/package.json index 8b0bf526..a1a9cade 100644 --- a/packages/code-interpreter-python/package.json +++ b/packages/code-interpreter-python/package.json @@ -1,7 +1,7 @@ { "name": "@abox-dev/code-interpreter-python", "private": true, - "version": "0.1.6", + "version": "0.1.7", "scripts": { "test": "uv run pytest -n 2 --verbose -x tests/test_sandbox_url.py", "test:integration": "uv run pytest -n 2 --verbose -x", diff --git a/packages/code-interpreter-python/pyproject.toml b/packages/code-interpreter-python/pyproject.toml index 795faeb1..3a86de1d 100644 --- a/packages/code-interpreter-python/pyproject.toml +++ b/packages/code-interpreter-python/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "abox-code-interpreter" -version = "0.1.6" +version = "0.1.7" description = "AgentBox Code Interpreter - Stateful code execution" authors = [{ name = "RetailDriver LLC" }] license = "MIT" diff --git a/packages/code-interpreter-python/uv.lock b/packages/code-interpreter-python/uv.lock index 79cc89ce..4de9fd00 100644 --- a/packages/code-interpreter-python/uv.lock +++ b/packages/code-interpreter-python/uv.lock @@ -16,7 +16,7 @@ members = [ [[package]] name = "abox-code-interpreter" -version = "0.1.6" +version = "0.1.7" source = { editable = "." } dependencies = [ { name = "abox-sdk" }, @@ -58,7 +58,7 @@ dev = [ [[package]] name = "abox-sdk" -version = "0.1.6" +version = "0.1.7" source = { editable = "../python-sdk" } dependencies = [ { name = "attrs" }, diff --git a/packages/go-sdk/README.md b/packages/go-sdk/README.md index 0658dd59..e2b14e78 100644 --- a/packages/go-sdk/README.md +++ b/packages/go-sdk/README.md @@ -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.6) and -[Code Interpreter on pkg.go.dev](https://pkg.go.dev/github.com/abox-dev/sdk/packages/go-sdk/codeinterpreter@v0.1.6). +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.7) and +[Code Interpreter on pkg.go.dev](https://pkg.go.dev/github.com/abox-dev/sdk/packages/go-sdk/codeinterpreter@v0.1.7). Documentation: [core SDK](https://docs.agentbox.ru/en/sdk/), [sandboxes](https://docs.agentbox.ru/en/sdk/sandboxes/), diff --git a/packages/go-sdk/sandbox.go b/packages/go-sdk/sandbox.go index 368fd0fb..41c32505 100644 --- a/packages/go-sdk/sandbox.go +++ b/packages/go-sdk/sandbox.go @@ -664,7 +664,11 @@ func (sandbox *Sandbox) envdURL(port int, direct bool) string { if sandbox.client.config.sandboxURL != "" { parsed, _ := url.Parse(sandbox.client.config.sandboxURL) if direct { - return parsed.Scheme + "://" + fmt.Sprintf("%d-%s.%s", port, sandbox.ID, parsed.Host) + host := parsed.Host + if parsed.Hostname() == "sandbox."+sandbox.Domain { + host = strings.TrimPrefix(host, "sandbox.") + } + return parsed.Scheme + "://" + fmt.Sprintf("%d-%s.%s", port, sandbox.ID, host) } return sandbox.client.config.sandboxURL } diff --git a/packages/go-sdk/sandbox_test.go b/packages/go-sdk/sandbox_test.go index aec27222..4d721c9c 100644 --- a/packages/go-sdk/sandbox_test.go +++ b/packages/go-sdk/sandbox_test.go @@ -13,6 +13,44 @@ import ( api "github.com/abox-dev/sdk/packages/go-sdk/internal/gen/api" ) +func TestSandboxDirectURLWithConfiguredProxy(t *testing.T) { + tests := []struct { + name, proxyURL, domain, directURL string + }{ + { + name: "shared production host", proxyURL: "https://sandbox.agentbox-runtime.ru", + domain: "agentbox-runtime.ru", directURL: "https://49983-sbx.agentbox-runtime.ru", + }, + { + name: "shared production host with port", proxyURL: "https://sandbox.agentbox-runtime.ru:8443", + domain: "agentbox-runtime.ru", directURL: "https://49983-sbx.agentbox-runtime.ru:8443", + }, + { + name: "custom proxy", proxyURL: "https://sandbox.example.com", + domain: "agentbox-runtime.ru", directURL: "https://49983-sbx.sandbox.example.com", + }, + { + name: "local proxy", proxyURL: "http://localhost:3002", + domain: "agentbox-runtime.ru", directURL: "http://49983-sbx.localhost:3002", + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + client, err := NewClient(WithSandboxURL(test.proxyURL), WithDebug(false)) + if err != nil { + t.Fatal(err) + } + sandbox := &Sandbox{ID: "sbx", Domain: test.domain, client: client} + if got := sandbox.envdURL(49983, false); got != test.proxyURL { + t.Fatalf("shared URL = %q, want %q", got, test.proxyURL) + } + if got := sandbox.envdURL(49983, true); got != test.directURL { + t.Fatalf("direct URL = %q, want %q", got, test.directURL) + } + }) + } +} + func TestSandboxLifecycleAPI(t *testing.T) { requests := make(chan *http.Request, 32) server := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { diff --git a/packages/go-sdk/version.go b/packages/go-sdk/version.go index 1213401f..b3737d13 100644 --- a/packages/go-sdk/version.go +++ b/packages/go-sdk/version.go @@ -1,4 +1,4 @@ package agentbox // Version is the AgentBox SDK release version. -const Version = "0.1.6" +const Version = "0.1.7" diff --git a/packages/js-sdk/package.json b/packages/js-sdk/package.json index fea96e22..62d1c54b 100644 --- a/packages/js-sdk/package.json +++ b/packages/js-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@abox-dev/sdk", - "version": "0.1.6", + "version": "0.1.7", "description": "AgentBox SDK for secure cloud sandboxes", "homepage": "https://docs.agentbox.ru/en/sdk/", "license": "MIT", diff --git a/packages/python-sdk/agentbox/connection_config.py b/packages/python-sdk/agentbox/connection_config.py index 70c6b703..aa6ab5a0 100644 --- a/packages/python-sdk/agentbox/connection_config.py +++ b/packages/python-sdk/agentbox/connection_config.py @@ -298,7 +298,12 @@ def get_host(self, sandbox_id: str, sandbox_domain: str, port: int) -> str: if self._sandbox_url: proxy_url = self._parse_sandbox_url() proxy_port = f":{proxy_url.port}" if proxy_url.port else "" - return f"{port}-{sandbox_id}.{proxy_url.hostname}{proxy_port}" + host = ( + sandbox_domain + if proxy_url.hostname == f"sandbox.{sandbox_domain}" + else proxy_url.hostname + ) + return f"{port}-{sandbox_id}.{host}{proxy_port}" if self.debug: return f"localhost:{port}" diff --git a/packages/python-sdk/package.json b/packages/python-sdk/package.json index e92c08ff..68286d34 100644 --- a/packages/python-sdk/package.json +++ b/packages/python-sdk/package.json @@ -1,7 +1,7 @@ { "name": "@abox-dev/python-sdk", "private": true, - "version": "0.1.6", + "version": "0.1.7", "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", diff --git a/packages/python-sdk/pyproject.toml b/packages/python-sdk/pyproject.toml index 93c95931..9ea3bd89 100644 --- a/packages/python-sdk/pyproject.toml +++ b/packages/python-sdk/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "abox-sdk" -version = "0.1.6" +version = "0.1.7" description = "AgentBox SDK for secure cloud sandboxes" authors = [{ name = "RetailDriver LLC" }] license = "MIT" diff --git a/packages/python-sdk/tests/test_connection_config.py b/packages/python-sdk/tests/test_connection_config.py index ec978fd0..7cad1f75 100644 --- a/packages/python-sdk/tests/test_connection_config.py +++ b/packages/python-sdk/tests/test_connection_config.py @@ -99,6 +99,25 @@ def test_sandbox_url_routing_preserves_configured_protocol(): ) +def test_shared_sandbox_url_uses_runtime_domain_for_direct_host(): + config = ConnectionConfig( + debug=False, sandbox_url="https://sandbox.agentbox-runtime.ru" + ) + + assert ( + config.get_sandbox_url("sandbox-id", "agentbox-runtime.ru") + == "https://sandbox.agentbox-runtime.ru" + ) + assert ( + config.get_host("sandbox-id", "agentbox-runtime.ru", 8080) + == "8080-sandbox-id.agentbox-runtime.ru" + ) + assert ( + config.get_sandbox_direct_url("sandbox-id", "agentbox-runtime.ru") + == "https://49983-sandbox-id.agentbox-runtime.ru" + ) + + def test_sandbox_url_routing_rejects_invalid_url(): config = ConnectionConfig(debug=False, sandbox_url="localhost:3002") diff --git a/packages/python-sdk/uv.lock b/packages/python-sdk/uv.lock index 4b0ce643..615a6716 100644 --- a/packages/python-sdk/uv.lock +++ b/packages/python-sdk/uv.lock @@ -8,7 +8,7 @@ resolution-markers = [ [[package]] name = "abox-sdk" -version = "0.1.6" +version = "0.1.7" source = { editable = "." } dependencies = [ { name = "attrs" }, diff --git a/reference-config/javascript/errors.ts b/reference-config/javascript/errors.ts index 868b6763..867917f8 100644 --- a/reference-config/javascript/errors.ts +++ b/reference-config/javascript/errors.ts @@ -1,6 +1,7 @@ export { AuthenticationError, BuildError, + CommandNotFoundError, FileNotFoundError, FileUploadError, InvalidArgumentError, diff --git a/reference/manifest.json b/reference/manifest.json index b96b703e..dc0829ca 100644 --- a/reference/manifest.json +++ b/reference/manifest.json @@ -45,7 +45,7 @@ "sdk/cli/sandbox.md": "16b64c5a4e932eca2452e400e0faf154eba1d3c7373513aa7cd9744e02908313", "sdk/cli/template.md": "f270b22b9ee10a9b954a14f24e04c5449b4d5823bb28002ffde3ed682594cfc5", "sdk/go/code-interpreter.md": "9c56333b8181878d656baa27a4b56b768a0cb01c9d764f7ac8d52d32d8faa70c", - "sdk/go/core.md": "4753f87bfb08f0462964d72780feb338a147be5de5a0bd97a32121ac87916d2b", + "sdk/go/core.md": "6fafc6064961034202df3c0d78beed0f82cb508b00f5225f37bf3297930fd630", "sdk/javascript/code-interpreter/README.md": "a787206eb86f81fc306b373ce20bc6c91464b0ab3c3ec7650eccbb6be5f676c5", "sdk/javascript/code-interpreter/classes/Sandbox.md": "19d9f1f1e8847606a54d93c5a6e5d4c89f936a745866e8d6a2aa06758b605e60", "sdk/javascript/code-interpreter/enumerations/ChartType.md": "cf1ba00cd3258cc88814b7215e101b0d775ceb15dd833636d58ae538d8107ec1", @@ -86,15 +86,16 @@ "sdk/javascript/commands/type-aliases/PtyOutput.md": "bfd9a341150ed358bf7ce8e94aaea30d3b3afcf5974262e78112b1cd959a6d2a", "sdk/javascript/commands/type-aliases/Stderr.md": "e9f4f9cf70ec20e2b61a9e4509a3a8969556b0ad1a17d61c6ac7d7e7e00793fd", "sdk/javascript/commands/type-aliases/Stdout.md": "7e9b82848962f16a596287915ac54187023f87fc3cbcc5a1998a7aaaf4038b70", - "sdk/javascript/errors/README.md": "640f3708d83ec06bd9db78b421c5b8fd66fa09be5f89d945f75dc1ac3415edcc", + "sdk/javascript/errors/README.md": "baae6af75520611679abbdae7e03bf1950895d7cbb51117c46b8452d75ec2e0e", "sdk/javascript/errors/classes/AuthenticationError.md": "4ec1e51898e7f7d6c3a366a9949c1cde62fa8c322328d841e265edcf3661d106", "sdk/javascript/errors/classes/BuildError.md": "02a3b265a03b035ac1b0c7026f2f4432a7ac2fd9650cb9207ca965bb7a0b70a6", + "sdk/javascript/errors/classes/CommandNotFoundError.md": "8caaf9c4ed8a54d402cba1d82585c2b62980d455d77271a0458c2793b6d7e9ba", "sdk/javascript/errors/classes/FileNotFoundError.md": "c34da4d4c47d0a97bd5c57aa1f832fc4dc25832ba3dffb9024d7b6b25a83d1be", "sdk/javascript/errors/classes/FileUploadError.md": "f0429c4aa8fbc71028c17c35eaa32b125b2ab0ed66bd07e3fc69c54461982279", "sdk/javascript/errors/classes/InvalidArgumentError.md": "2912cbd9288e32172416a018f6e0b8151dabaead9fdd25508604d6ca7a46083a", "sdk/javascript/errors/classes/NotEnoughSpaceError.md": "158fc473c131bd144287f09eca6ee4185e4889518a51b4afec14348f199bb930", "sdk/javascript/errors/classes/RateLimitError.md": "d267a303c41b045cfed9294cc57a8811c2c5a4a23ce1f11907797998f036eac9", - "sdk/javascript/errors/classes/SandboxError.md": "f9ba82182638d3f446f8af283ad336aca121bbfa95a63add933b2f25e34bd946", + "sdk/javascript/errors/classes/SandboxError.md": "5d3b7e8f1c8dad7365b648b8251ebecb4c973a7af0b3dc0183897aa4c9c41cfa", "sdk/javascript/errors/classes/SandboxNotFoundError.md": "97043859ea96d8a9036060a9e83c974b7609aff95cf9b94f290534a60f493e9b", "sdk/javascript/errors/classes/TemplateError.md": "5e6aa02a96a73329edbc54615e389a722db93cf4017c266093932befe8d400d5", "sdk/javascript/errors/classes/TimeoutError.md": "cc752f4bc03a682e101d17e13e4ed48e0405b95febc2e09bee7672bfc905401d", @@ -184,12 +185,12 @@ }, "monoRevision": "a7d59d50e3dd84faee59aca08df1b5bb175266e6", "packages": { - "@abox-dev/cli": "0.1.6", - "@abox-dev/code-interpreter": "0.1.6", - "@abox-dev/sdk": "0.1.6", - "abox-code-interpreter": "0.1.6", - "abox-sdk": "0.1.6", - "github.com/abox-dev/sdk/packages/go-sdk": "0.1.6" + "@abox-dev/cli": "0.1.7", + "@abox-dev/code-interpreter": "0.1.7", + "@abox-dev/sdk": "0.1.7", + "abox-code-interpreter": "0.1.7", + "abox-sdk": "0.1.7", + "github.com/abox-dev/sdk/packages/go-sdk": "0.1.7" }, "schemaVersion": 1 } diff --git a/reference/sdk/go/core.md b/reference/sdk/go/core.md index f1e3804c..5160e01b 100644 --- a/reference/sdk/go/core.md +++ b/reference/sdk/go/core.md @@ -261,7 +261,7 @@ Create a client, start a sandbox, and run a command: Version is the AgentBox SDK release version. - const Version = "0.1.6" + const Version = "0.1.7" ## func IAMTokenPlaceholder diff --git a/reference/sdk/javascript/errors/README.md b/reference/sdk/javascript/errors/README.md index 0ec810db..507ec9d3 100644 --- a/reference/sdk/javascript/errors/README.md +++ b/reference/sdk/javascript/errors/README.md @@ -4,6 +4,7 @@ - [AuthenticationError](classes/AuthenticationError.md) - [BuildError](classes/BuildError.md) +- [CommandNotFoundError](classes/CommandNotFoundError.md) - [FileNotFoundError](classes/FileNotFoundError.md) - [FileUploadError](classes/FileUploadError.md) - [InvalidArgumentError](classes/InvalidArgumentError.md) diff --git a/reference/sdk/javascript/errors/classes/CommandNotFoundError.md b/reference/sdk/javascript/errors/classes/CommandNotFoundError.md new file mode 100644 index 00000000..1997de3a --- /dev/null +++ b/reference/sdk/javascript/errors/classes/CommandNotFoundError.md @@ -0,0 +1,185 @@ +[agentbox-sdk-monorepo](../README.md) / CommandNotFoundError + +# Class: CommandNotFoundError + +Thrown when a command process has already exited or its PID does not exist. + +## Extends + +- [`SandboxError`](SandboxError.md) + +## Constructors + +### Constructor + +> **new CommandNotFoundError**(`message`): `CommandNotFoundError` + +#### Parameters + +##### message + +`string` + +#### Returns + +`CommandNotFoundError` + +#### Overrides + +[`SandboxError`](SandboxError.md).[`constructor`](SandboxError.md#constructor) + +## Properties + +### cause? + +> `optional` **cause?**: `unknown` + +#### Inherited from + +[`SandboxError`](SandboxError.md).[`cause`](SandboxError.md#cause) + +*** + +### message + +> **message**: `string` + +#### Inherited from + +[`SandboxError`](SandboxError.md).[`message`](SandboxError.md#message) + +*** + +### name + +> **name**: `string` + +#### Inherited from + +[`SandboxError`](SandboxError.md).[`name`](SandboxError.md#name) + +*** + +### stack? + +> `optional` **stack?**: `string` + +#### Inherited from + +[`SandboxError`](SandboxError.md).[`stack`](SandboxError.md#stack) + +*** + +### stackTraceLimit + +> `static` **stackTraceLimit**: `number` + +The `Error.stackTraceLimit` property specifies the number of stack frames +collected by a stack trace (whether generated by `new Error().stack` or +`Error.captureStackTrace(obj)`). + +The default value is `10` but may be set to any valid JavaScript number. Changes +will affect any stack trace captured _after_ the value has been changed. + +If set to a non-number value, or set to a negative number, stack traces will +not capture any frames. + +#### Inherited from + +[`SandboxError`](SandboxError.md).[`stackTraceLimit`](SandboxError.md#stacktracelimit) + +## Methods + +### captureStackTrace() + +> `static` **captureStackTrace**(`targetObject`, `constructorOpt?`): `void` + +Creates a `.stack` property on `targetObject`, which when accessed returns +a string representing the location in the code at which +`Error.captureStackTrace()` was called. + +```js +const myObject = {}; +Error.captureStackTrace(myObject); +myObject.stack; // Similar to `new Error().stack` +``` + +The first line of the trace will be prefixed with +`${myObject.name}: ${myObject.message}`. + +The optional `constructorOpt` argument accepts a function. If given, all frames +above `constructorOpt`, including `constructorOpt`, will be omitted from the +generated stack trace. + +The `constructorOpt` argument is useful for hiding implementation +details of error generation from the user. For instance: + +```js +function a() { + b(); +} + +function b() { + c(); +} + +function c() { + // Create an error without stack trace to avoid calculating the stack trace twice. + const { stackTraceLimit } = Error; + Error.stackTraceLimit = 0; + const error = new Error(); + Error.stackTraceLimit = stackTraceLimit; + + // Capture the stack trace above function b + Error.captureStackTrace(error, b); // Neither function c, nor b is included in the stack trace + throw error; +} + +a(); +``` + +#### Parameters + +##### targetObject + +`object` + +##### constructorOpt? + +`Function` + +#### Returns + +`void` + +#### Inherited from + +[`SandboxError`](SandboxError.md).[`captureStackTrace`](SandboxError.md#capturestacktrace) + +*** + +### prepareStackTrace() + +> `static` **prepareStackTrace**(`err`, `stackTraces`): `any` + +#### Parameters + +##### err + +`Error` + +##### stackTraces + +`CallSite`[] + +#### Returns + +`any` + +#### See + +https://v8.dev/docs/stack-trace-api#customizing-stack-traces + +#### Inherited from + +[`SandboxError`](SandboxError.md).[`prepareStackTrace`](SandboxError.md#preparestacktrace) diff --git a/reference/sdk/javascript/errors/classes/SandboxError.md b/reference/sdk/javascript/errors/classes/SandboxError.md index 6539d7e3..2debdac4 100644 --- a/reference/sdk/javascript/errors/classes/SandboxError.md +++ b/reference/sdk/javascript/errors/classes/SandboxError.md @@ -12,6 +12,7 @@ Thrown when general sandbox errors occur. ## Extended by +- [`CommandNotFoundError`](CommandNotFoundError.md) - [`FileNotFoundError`](FileNotFoundError.md) - [`InvalidArgumentError`](InvalidArgumentError.md) - [`NotEnoughSpaceError`](NotEnoughSpaceError.md)