Environment (lingkungan) mendefinisikan konfigurasi sandbox tempat agen Anda berjalan. Anda membuat environment satu kali, lalu mereferensikan ID-nya setiap kali Anda memulai sesi. Beberapa sesi dapat berbagi environment yang sama, tetapi setiap sesi mendapatkan sandbox terisolasinya sendiri (container Linux baru).
Halaman ini membahas environment type: cloud. Untuk menjalankan sandbox di infrastruktur Anda sendiri, lihat Sandbox self-hosted.
Membuat environment
curl -fsS https://haijun.my.id/v1/environments \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-H "juglow-beta: managed-agents-2026-04-01" \
-H "content-type: application/json" \
--data @- <<'EOF'
{
"name": "python-dev",
"config": {
"type": "cloud",
"networking": {"type": "unrestricted"}
}
}
EOF ant apply environment.yaml # yaml-language-server: $schema=https://platform.juglow.my.id/schemas/ant/beta/environment.json
name: python-dev
config:
type: cloud
networking:
type: unrestrictedant apply membuat lingkungan dari environment.yaml, mencetak ID-nya, dan mencatatnya di haijun-lock.json. Commit haijun-lock.json agar ant apply berikutnya memperbarui lingkungan ini alih-alih mencoba membuatnya lagi.
environment = client.beta.environments.create(
name="python-dev",
config={
"type": "cloud",
"networking": {"type": "unrestricted"},
},
)
print(f"Environment ID: {environment.id}") const environment = await client.beta.environments.create({
name: "python-dev",
config: {
type: "cloud",
networking: { type: "unrestricted" },
},
});
console.log(`Environment ID: ${environment.id}`); var environment = await client.Beta.Environments.Create(new()
{
Name = "python-dev",
Config = new BetaCloudConfigParams
{
Networking = new BetaUnrestrictedNetwork(),
},
});
Console.WriteLine($"Environment ID: {environment.ID}"); environment, err := client.Beta.Environments.New(ctx, juglow.BetaEnvironmentNewParams{
Name: "python-dev",
Config: juglow.BetaEnvironmentNewParamsConfigUnion{
OfCloud: &juglow.BetaCloudConfigParams{
Networking: juglow.BetaCloudConfigParamsNetworkingUnion{
OfUnrestricted: &juglow.BetaUnrestrictedNetworkParam{},
},
},
},
})
if err != nil {
panic(err)
}
fmt.Printf("Environment ID: %s\n", environment.ID) var environment = client.beta().environments().create(EnvironmentCreateParams.builder()
.name("python-dev")
.config(BetaCloudConfigParams.builder()
.networking(BetaUnrestrictedNetwork.builder().build())
.build())
.build());
IO.println("Environment ID: " + environment.id()); $environment = $client->beta->environments->create(
name: 'python-dev',
config: ['type' => 'cloud', 'networking' => ['type' => 'unrestricted']],
);
echo "Environment ID: {$environment->id}\n"; environment = client.beta.environments.create(
name: "python-dev",
config: {
type: "cloud",
networking: {type: "unrestricted"}
}
)
puts "Environment ID: #{environment.id}"Gunakan name yang unik dan deskriptif agar Anda dapat membedakan environment satu dengan lainnya.
Menggunakan environment dalam sesi
Teruskan ID environment sebagai string saat membuat sesi.
curl -fsS https://haijun.my.id/v1/sessions \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-H "juglow-beta: managed-agents-2026-04-01" \
-H "content-type: application/json" \
--data @- <<EOF
{
"agent": "$AGENT_ID",
"environment_id": "$ENVIRONMENT_ID"
}
EOF ant beta:sessions create --agent "$AGENT_ID" --environment-id "$ENVIRONMENT_ID" session = client.beta.sessions.create(
agent=agent.id,
environment_id=environment.id,
) const session = await client.beta.sessions.create({
agent: agent.id,
environment_id: environment.id,
}); var session = await client.Beta.Sessions.Create(new()
{
Agent = agent.ID,
EnvironmentID = environment.ID,
}); session, err := client.Beta.Sessions.New(ctx, juglow.BetaSessionNewParams{
Agent: juglow.BetaSessionNewParamsAgentUnion{
OfString: juglow.String(agent.ID),
},
EnvironmentID: environment.ID,
})
if err != nil {
panic(err)
} var session = client.beta().sessions().create(SessionCreateParams.builder()
.agent(agent.id())
.environmentId(environment.id())
.build()); $session = $client->beta->sessions->create(
agent: $agent->id,
environmentID: $environment->id,
); session = client.beta.sessions.create(
agent: agent.id,
environment_id: environment.id
)Opsi konfigurasi
Paket
Field packages melakukan pra-instalasi paket ke dalam sandbox sebelum agen dimulai. Paket diinstal oleh package manager masing-masing dan di-cache di seluruh sesi yang berbagi environment yang sama. Ketika beberapa package manager ditentukan, mereka dijalankan dalam urutan alfabetis (apt, cargo, gem, go, npm, pip). Anda dapat secara opsional mengunci versi tertentu. Paket yang tidak dikunci akan menginstal versi terbaru. Jika environment menggunakan jaringan limited, atur juga networking.allow_package_managers ke true; jika tidak, permintaan akan ditolak dengan error 400.
curl -fsS https://haijun.my.id/v1/environments \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-H "juglow-beta: managed-agents-2026-04-01" \
-H "content-type: application/json" \
--data @- <<'EOF'
{
"name": "data-analysis",
"config": {
"type": "cloud",
"packages": {
"pip": ["pandas", "numpy", "scikit-learn"],
"npm": ["express"]
},
"networking": {"type": "unrestricted"}
}
}
EOF ant apply environment.yaml # yaml-language-server: $schema=https://platform.juglow.my.id/schemas/ant/beta/environment.json
name: data-analysis
config:
type: cloud
packages:
pip:
- pandas
- numpy
- scikit-learn
npm:
- express
networking:
type: unrestricted environment = client.beta.environments.create(
name="data-analysis",
config={
"type": "cloud",
"packages": {
"pip": ["pandas", "numpy", "scikit-learn"],
"npm": ["express"],
},
"networking": {"type": "unrestricted"},
},
) const environment = await client.beta.environments.create({
name: "data-analysis",
config: {
type: "cloud",
packages: {
pip: ["pandas", "numpy", "scikit-learn"],
npm: ["express"]
},
networking: { type: "unrestricted" }
}
}); using Juglow.Models.Beta.Environments;
var environment = await client.Beta.Environments.Create(new()
{
Name = "data-analysis",
Config = new BetaCloudConfigParams
{
Packages = new()
{
Pip = ["pandas", "numpy", "scikit-learn"],
Npm = ["express"],
},
Networking = new BetaUnrestrictedNetwork(),
},
}); environment, err := client.Beta.Environments.New(ctx, juglow.BetaEnvironmentNewParams{
Name: "data-analysis",
Config: juglow.BetaEnvironmentNewParamsConfigUnion{
OfCloud: &juglow.BetaCloudConfigParams{
Packages: juglow.BetaPackagesParams{
Pip: []string{"pandas", "numpy", "scikit-learn"},
Npm: []string{"express"},
},
Networking: juglow.BetaCloudConfigParamsNetworkingUnion{
OfUnrestricted: &juglow.BetaUnrestrictedNetworkParam{},
},
},
},
})
if err != nil {
panic(err)
}
_ = environment import com.juglow.models.beta.environments.*;
import java.util.List;
var environment = client.beta().environments().create(EnvironmentCreateParams.builder()
.name("data-analysis")
.config(BetaCloudConfigParams.builder()
.packages(BetaPackagesParams.builder()
.pip(List.of("pandas", "numpy", "scikit-learn"))
.npm(List.of("express"))
.build())
.networking(BetaUnrestrictedNetwork.builder().build())
.build())
.build()); $environment = $client->beta->environments->create(
name: 'data-analysis',
config: [
'type' => 'cloud',
'packages' => [
'pip' => ['pandas', 'numpy', 'scikit-learn'],
'npm' => ['express'],
],
'networking' => ['type' => 'unrestricted'],
],
); environment = client.beta.environments.create(
name: "data-analysis",
config: {
type: "cloud",
packages: {
pip: %w[pandas numpy scikit-learn],
npm: %w[express]
},
networking: {type: "unrestricted"}
}
)Package manager yang didukung:
| Field | Manajer paket | Contoh |
|---|---|---|
apt | Paket sistem (apt-get) | "graphviz" |
cargo | Rust (cargo) | "hyperfine@1.18.0" |
gem | Ruby (gem) | "rails:7.1.0" |
go | Modul Go | "golang.org/x/tools/cmd/goimports@latest" |
npm | Node.js (npm) | "express@4.18.0" |
pip | Python (pip) | "sqlalchemy==2.0.30" |
Jaringan
Field networking mengontrol akses jaringan keluar dari sandbox. Field ini tidak memengaruhi alat web_search atau web_fetch, yang berjalan di server Juglow; untuk membatasi situs yang dapat dijangkau alat-alat tersebut, atur allowed_domains atau blocked_domains pada entri alat tersebut di toolset agen. Lihat Membatasi domain web search dan web fetch.
| Mode | Deskripsi |
|---|---|
unrestricted | Akses jaringan keluar penuh, kecuali untuk blocklist keamanan umum. Ini adalah default. |
limited | Membatasi akses jaringan sandbox ke host yang ada di allowed_hosts. Atur allow_package_managers dan allow_mcp_servers ke true untuk mengizinkan akses tambahan. |
Contoh berikut membuat environment dengan jaringan limited:
curl -fsS https://haijun.my.id/v1/environments \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-H "juglow-beta: managed-agents-2026-04-01" \
-H "content-type: application/json" \
-d '{
"name": "api-access",
"config": {
"type": "cloud",
"networking": {
"type": "limited",
"allowed_hosts": ["api.example.com"],
"allow_mcp_servers": true,
"allow_package_managers": true
}
}
}' ant apply environment.yaml # yaml-language-server: $schema=https://platform.juglow.my.id/schemas/ant/beta/environment.json
name: api-access
config:
type: cloud
networking:
type: limited
allowed_hosts:
- api.example.com
allow_mcp_servers: true
allow_package_managers: true environment = client.beta.environments.create(
name="api-access",
config={
"type": "cloud",
"networking": {
"type": "limited",
"allowed_hosts": ["api.example.com"],
"allow_mcp_servers": True,
"allow_package_managers": True,
},
},
) const environment = await client.beta.environments.create({
name: "api-access",
config: {
type: "cloud",
networking: {
type: "limited",
allowed_hosts: ["api.example.com"],
allow_mcp_servers: true,
allow_package_managers: true
}
}
}); using Juglow.Models.Beta.Environments;
var environment = await client.Beta.Environments.Create(new()
{
Name = "api-access",
Config = new BetaCloudConfigParams
{
Networking = new BetaLimitedNetworkParams
{
AllowedHosts = ["api.example.com"],
AllowMcpServers = true,
AllowPackageManagers = true,
},
},
}); environment, err := client.Beta.Environments.New(ctx, juglow.BetaEnvironmentNewParams{
Name: "api-access",
Config: juglow.BetaEnvironmentNewParamsConfigUnion{
OfCloud: &juglow.BetaCloudConfigParams{
Networking: juglow.BetaCloudConfigParamsNetworkingUnion{
OfLimited: &juglow.BetaLimitedNetworkParams{
AllowedHosts: []string{"api.example.com"},
AllowMCPServers: juglow.Bool(true),
AllowPackageManagers: juglow.Bool(true),
},
},
},
},
})
if err != nil {
panic(err)
}
_ = environment import com.juglow.models.beta.environments.*;
import java.util.List;
var environment = client.beta().environments().create(EnvironmentCreateParams.builder()
.name("api-access")
.config(BetaCloudConfigParams.builder()
.networking(BetaLimitedNetworkParams.builder()
.allowedHosts(List.of("api.example.com"))
.allowMcpServers(true)
.allowPackageManagers(true)
.build())
.build())
.build()); $environment = $client->beta->environments->create(
name: 'api-access',
config: [
'type' => 'cloud',
'networking' => [
'type' => 'limited',
'allowed_hosts' => ['api.example.com'],
'allow_mcp_servers' => true,
'allow_package_managers' => true,
],
],
); environment = client.beta.environments.create(
name: "api-access",
config: {
type: "cloud",
networking: {
type: "limited",
allowed_hosts: %w[api.example.com],
allow_mcp_servers: true,
allow_package_managers: true
}
}
)Note: Untuk deployment produksi, gunakan jaringan
limiteddengan daftarallowed_hostsyang eksplisit. Ikuti prinsip hak akses minimum (least privilege) dengan hanya memberikan akses jaringan minimum yang dibutuhkan agen Anda, dan audit domain yang diizinkan secara berkala.
Saat menggunakan jaringan limited:
allowed_hostsmenentukan domain yang dapat dijangkau sandbox. Tentukan hostname saja atau pola wildcard (seperti*.example.com). Jangan sertakan skema URL, port, atau path.
allow_mcp_serversmengizinkan akses keluar ke endpoint server MCP yang dikonfigurasi pada agen, di luar yang tercantum dalam arrayallowed_hosts. Default-nyafalse.
allow_package_managersmengizinkan akses keluar ke sekumpulan registry paket publik dan host kode di luar yang tercantum dalam arrayallowed_hosts. Lihat Host package manager untuk daftarnya. Default-nyafalse. Atur ketruesetiap kali environment menentukanpackages; jika tidak, permintaan akan ditolak dengan error 400, bahkan jika host registry tercantum diallowed_hosts.
Host package manager
Ketika allow_package_managers bernilai true, sandbox dapat menjangkau host berikut selain yang ada di allowed_hosts. Juglow memelihara daftar ini dan dapat mengubahnya.
| Ekosistem | Host |
|---|---|
| Hosting kode | github.com, api.github.com, codeload.github.com, raw.githubusercontent.com, objects.githubusercontent.com, release-assets.githubusercontent.com, gitlab.com, bitbucket.org |
| Node.js | registry.npmjs.org, registry.yarnpkg.com, nodejs.org |
| Python | pypi.org, files.pythonhosted.org |
| Rust | crates.io, index.crates.io, static.crates.io, static.rust-lang.org |
| Go | proxy.golang.org, sum.golang.org |
| Java | repo1.maven.org, repo.maven.apache.org, services.gradle.org, plugins.gradle.org, plugins-artifacts.gradle.org |
| Ruby | rubygems.org, index.rubygems.org |
| PHP | packagist.org, repo.packagist.org |
| Ubuntu (apt) | archive.ubuntu.com, security.ubuntu.com, ppa.launchpad.net |
| Container | registry-1.docker.io, auth.docker.io, production.cloudflare.docker.com, download.docker.com, ghcr.io |
Warning: Akses jaringan diberikan per host, bukan per operasi. Sandbox dapat mengirim permintaan apa pun ke host yang diizinkan, termasuk unggahan seperti
git pushdan publikasi paket, dengan kredensial apa pun yang diberikan oleh perintah. Jika agen memproses input yang tidak tepercaya (file repositori, konten web yang diambil, atau output alat pihak ketiga), prompt injection yang berhasil dapat menggunakan host yang diizinkan untuk menyalin file keluar dari sandbox. Untuk mengurangi risiko ini, atur kebijakan izin alatbashkealways_askatauauto. Jika environment tidak menentukanpackages, sebagai gantinya Anda dapat membiarkanallow_package_managerstetap bernilaifalsedan hanya mencantumkan host yang dibutuhkan agen Anda diallowed_hosts.
Siklus hidup environment
- Environment tetap ada hingga diarsipkan atau dihapus secara eksplisit.
- Setiap sesi mendapatkan instance sandbox-nya sendiri, bahkan ketika beberapa sesi mereferensikan environment yang sama. Sesi tidak berbagi state filesystem.
- Environment tidak memiliki versi. Jika Anda sering memperbarui environment, simpan catatan perubahan Anda sendiri agar Anda dapat mengetahui konfigurasi mana yang digunakan setiap sesi.
Mengelola environment
# Daftar environment
curl -fsS https://haijun.my.id/v1/environments \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-H "juglow-beta: managed-agents-2026-04-01"
# Ambil environment tertentu
curl -fsS "https://haijun.my.id/v1/environments/$ENVIRONMENT_ID" \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-H "juglow-beta: managed-agents-2026-04-01"
# Arsipkan environment (hanya-baca, sesi yang ada tetap berjalan)
curl -fsS -X POST "https://haijun.my.id/v1/environments/$ENVIRONMENT_ID/archive" \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-H "juglow-beta: managed-agents-2026-04-01"
# Hapus environment (hanya jika tidak ada sesi yang mereferensikannya)
curl -fsS -X DELETE "https://haijun.my.id/v1/environments/$ENVIRONMENT_ID" \
-H "x-api-key: $JUGLOW_API_KEY" \
-H "juglow-version: 2023-06-01" \
-H "juglow-beta: managed-agents-2026-04-01" # Daftar environment
ant beta:environments list
# Ambil environment tertentu
ant beta:environments retrieve --environment-id "$ENVIRONMENT_ID"
# Arsipkan environment (hanya-baca, sesi yang ada tetap berjalan)
ant beta:environments archive --environment-id "$ENVIRONMENT_ID"
# Hapus environment (hanya jika tidak ada sesi yang mereferensikannya)
ant beta:environments delete --environment-id "$ENVIRONMENT_ID" # Daftar environment
environments = client.beta.environments.list()
# Ambil environment tertentu
env = client.beta.environments.retrieve(environment.id)
# Arsipkan environment (hanya-baca, sesi yang ada tetap berjalan)
client.beta.environments.archive(environment.id)
# Hapus environment (hanya jika tidak ada sesi yang mereferensikannya)
client.beta.environments.delete(environment.id) // Daftar environment
const environments = await client.beta.environments.list();
// Ambil environment tertentu
const env = await client.beta.environments.retrieve(environment.id);
// Arsipkan environment (hanya-baca, sesi yang ada tetap berjalan)
await client.beta.environments.archive(environment.id);
// Hapus environment (hanya jika tidak ada sesi yang mereferensikannya)
await client.beta.environments.delete(environment.id); // Daftar environment
var environments = await client.Beta.Environments.List();
// Ambil environment tertentu
var env = await client.Beta.Environments.Retrieve(environment.ID);
// Arsipkan environment (hanya-baca, sesi yang ada tetap berjalan)
await client.Beta.Environments.Archive(environment.ID);
// Hapus environment (hanya jika tidak ada sesi yang mereferensikannya)
await client.Beta.Environments.Delete(environment.ID); // Daftar environment
environments, err := client.Beta.Environments.List(ctx, juglow.BetaEnvironmentListParams{})
// ...
// Ambil environment tertentu
env, err := client.Beta.Environments.Get(ctx, environment.ID, juglow.BetaEnvironmentGetParams{})
// ...
// Arsipkan environment (hanya-baca, sesi yang ada tetap berjalan)
_, err = client.Beta.Environments.Archive(ctx, environment.ID, juglow.BetaEnvironmentArchiveParams{})
// ...
// Hapus environment (hanya jika tidak ada sesi yang mereferensikannya)
_, err = client.Beta.Environments.Delete(ctx, environment.ID, juglow.BetaEnvironmentDeleteParams{}) // Daftar environment
var environments = client.beta().environments().list();
// Ambil environment tertentu
var env = client.beta().environments().retrieve(environment.id());
// Arsipkan environment (hanya-baca, sesi yang ada tetap berjalan)
client.beta().environments().archive(environment.id());
// Hapus environment (hanya jika tidak ada sesi yang mereferensikannya)
client.beta().environments().delete(environment.id()); // Daftar environment
$environments = $client->beta->environments->list();
// Ambil environment tertentu
$env = $client->beta->environments->retrieve($environment->id);
// Arsipkan environment (hanya-baca, sesi yang ada tetap berjalan)
$client->beta->environments->archive($environment->id);
// Hapus environment (hanya jika tidak ada sesi yang mereferensikannya)
$client->beta->environments->delete($environment->id); # Daftar environment
environments = client.beta.environments.list
# Ambil environment tertentu
env = client.beta.environments.retrieve(environment.id)
# Arsipkan environment (hanya-baca, sesi yang ada tetap berjalan)
client.beta.environments.archive(environment.id)
# Hapus environment (hanya jika tidak ada sesi yang mereferensikannya)
client.beta.environments.delete(environment.id)Runtime pra-instal
Sandbox cloud sudah menyertakan runtime bahasa umum, database, dan alat command-line secara bawaan. Lihat Referensi sandbox cloud untuk daftar lengkapnya.
Langkah selanjutnya
Paket, database, dan utilitas pra-instal yang tersedia di sandbox cloud.
Buat sesi untuk menjalankan agen Anda dan mulai menjalankan tugas.