Haijun Platform Docs
EN

Anda dapat menyediakan file untuk agen Anda dengan mengunggahnya melalui Files API dan me-mount-nya di sandbox sesi.

Mengunggah file

Pertama, unggah file menggunakan Files API:

bash
  file=$(curl --fail-with-body -sS "${auth[@]}" \
    "${base_url}/files" \
    -F file=@data.csv)
  FILE_ID=$(jq -er '.id' <<<"${file}")
bash
  FILE_ID=$(ant files upload --file data.csv --transform id --raw-output)
python
  file = client.files.upload(file=Path("data.csv"))
  print(f"File ID: {file.id}")
typescript
  const file = await client.files.upload({
    file: await toFile(readFile("data.csv"), "data.csv", { type: "text/csv" }),
  });
  console.log(`File ID: ${file.id}`);
csharp
  await using var stream = File.OpenRead(csvPath);
  var file = await client.Files.Upload(new() { File = stream });
  Console.WriteLine($"File ID: {file.ID}");
go
  csvFile, err := os.Open("data.csv")
  if err != nil {
  	panic(err)
  }
  defer csvFile.Close()

  file, err := client.Files.Upload(ctx, juglow.FileUploadParams{
  	File: csvFile,
  })
  if err != nil {
  	panic(err)
  }
  fmt.Printf("File ID: %s\n", file.ID)
java
  var file = client.files().upload(
      FileUploadParams.builder().file(dataCsv).build()
  );
  IO.println("File ID: " + file.id());
php
  $file = $client->files->upload(
      file: FileParam::fromResource(fopen($csvPath, 'r'), filename: 'data.csv', contentType: 'text/csv'),
  );
  echo "File ID: {$file->id}\n";
ruby
  file = client.files.upload(file: Pathname(csv_path))
  puts "File ID: #{file.id}"

Me-mount file dalam sesi

Mount file yang telah diunggah ke dalam sandbox dengan menambahkannya ke array resources saat membuat sesi:

Tip: mount_path bersifat opsional, tetapi pastikan file yang diunggah memiliki nama yang deskriptif agar agen dapat mengidentifikasinya.

bash
  jq -n \
    --arg agent_id "${AGENT_ID}" \
    --arg environment_id "${ENVIRONMENT_ID}" \
    --arg file_id "${FILE_ID}" \
    '{
      agent: $agent_id,
      environment_id: $environment_id,
      resources: [
        {
          type: "file",
          file_id: $file_id,
          mount_path: "/data.csv"
        }
      ]
    }' | curl --fail-with-body -sS "${auth[@]}" "${base_url}/sessions" --json @-
bash
  ant beta:sessions create \
    --agent "$AGENT_ID" \
    --environment-id "$ENVIRONMENT_ID" <<EOF
  resources:
    - type: file
      file_id: $FILE_ID
      mount_path: /data.csv
  EOF
python
  session = client.beta.sessions.create(
      agent=agent.id,
      environment_id=environment.id,
      resources=[
          {
              "type": "file",
              "file_id": file.id,
              "mount_path": "/data.csv",
          },
      ],
  )
typescript
  const session = await client.beta.sessions.create({
    agent: agent.id,
    environment_id: environment.id,
    resources: [
      {
        type: "file",
        file_id: file.id,
        mount_path: "/data.csv",
      },
    ],
  });
csharp
  var session = await client.Beta.Sessions.Create(new()
  {
      Agent = agent.ID,
      EnvironmentID = environment.ID,
      Resources =
      [
          new BetaManagedAgentsFileResourceParams
          {
              Type = "file",
              FileID = file.ID,
              MountPath = "/data.csv",
          },
      ],
  });
go
  session, err := client.Beta.Sessions.New(ctx, juglow.BetaSessionNewParams{
  	Agent: juglow.BetaSessionNewParamsAgentUnion{
  		OfString: juglow.String(agent.ID),
  	},
  	EnvironmentID: environment.ID,
  	Resources: []juglow.BetaSessionNewParamsResourceUnion{{
  		OfFile: &juglow.BetaManagedAgentsFileResourceParams{
  			Type:      juglow.BetaManagedAgentsFileResourceParamsTypeFile,
  			FileID:    file.ID,
  			MountPath: juglow.String("/data.csv"),
  		},
  	}},
  })
  if err != nil {
  	panic(err)
  }
java
  var session = client.beta().sessions().create(
      SessionCreateParams.builder()
          .agent(agent.id())
          .environmentId(environment.id())
          .addResource(
              BetaManagedAgentsFileResourceParams.builder()
                  .type(BetaManagedAgentsFileResourceParams.Type.FILE)
                  .fileId(file.id())
                  .mountPath("/data.csv")
                  .build()
          )
          .build()
  );
php
  $session = $client->beta->sessions->create(
      agent: $agent->id,
      environmentID: $environment->id,
      resources: [
          BetaManagedAgentsFileResourceParams::with(
              type: 'file',
              fileID: $file->id,
              mountPath: '/data.csv',
          ),
      ],
  );
ruby
  session = client.beta.sessions.create(
    agent: agent.id,
    environment_id: environment.id,
    resources: [
      {
        type: "file",
        file_id: file.id,
        mount_path: "/data.csv"
      }
    ]
  )

Dengan mount_path di atas, agen membaca file di /mnt/session/uploads/data.csv (lihat Path file).

Sebuah file_id baru dibuat yang mereferensikan instance file tersebut di dalam sesi. Salinan ini tidak dihitung terhadap batas penyimpanan Anda.

Beberapa file

Mount beberapa file dengan menambahkan entri ke array resources:

bash
  curl -fsSL 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" \
    -d '{
      "agent": "agent_01J8XkN5uT3vHpLqRfWdY2",
      "environment_id": "env_01K2mPsT7hNwR4jXuLvCqD8",
      "resources": [
        {
          "type": "file",
          "file_id": "file_011CNha8iCJcU1wXNR6q4V8w",
          "mount_path": "/data.csv"
        },
        {
          "type": "file",
          "file_id": "file_011CPMxVD3fHLUhvTqtsQA5w",
          "mount_path": "/config.json"
        },
        {
          "type": "file",
          "file_id": "file_011CRb3kQ7tWx9ZsLmDe2Vh4",
          "mount_path": "/src/main.py"
        }
      ]
    }'
bash
  ant beta:sessions create \
    --agent agent_01J8XkN5uT3vHpLqRfWdY2 \
    --environment-id env_01K2mPsT7hNwR4jXuLvCqD8 <<YAML
  resources:
    - type: file
      file_id: file_011CNha8iCJcU1wXNR6q4V8w
      mount_path: /data.csv
    - type: file
      file_id: file_011CPMxVD3fHLUhvTqtsQA5w
      mount_path: /config.json
    - type: file
      file_id: file_011CRb3kQ7tWx9ZsLmDe2Vh4
      mount_path: /src/main.py
  YAML
python
  resources = [
      {"type": "file", "file_id": "file_abc123", "mount_path": "/data.csv"},
      {"type": "file", "file_id": "file_def456", "mount_path": "/config.json"},
      {"type": "file", "file_id": "file_ghi789", "mount_path": "/src/main.py"},
  ]
typescript
  resources: [
    { type: "file", file_id: "file_abc123", mount_path: "/data.csv" },
    { type: "file", file_id: "file_def456", mount_path: "/config.json" },
    { type: "file", file_id: "file_ghi789", mount_path: "/src/main.py" }
  ]
csharp
  using Juglow.Models.Beta.Sessions;

  var resources = new[]
  {
      new BetaManagedAgentsFileResourceParams { Type = BetaManagedAgentsFileResourceParamsType.File, FileID = "file_abc123", MountPath = "/data.csv" },
      new BetaManagedAgentsFileResourceParams { Type = BetaManagedAgentsFileResourceParamsType.File, FileID = "file_def456", MountPath = "/config.json" },
      new BetaManagedAgentsFileResourceParams { Type = BetaManagedAgentsFileResourceParamsType.File, FileID = "file_ghi789", MountPath = "/src/main.py" },
  };
go
  resources := []juglow.BetaSessionNewParamsResourceUnion{
  	{OfFile: &juglow.BetaManagedAgentsFileResourceParams{Type: "file", FileID: "file_abc123", MountPath: juglow.String("/data.csv")}},
  	{OfFile: &juglow.BetaManagedAgentsFileResourceParams{Type: "file", FileID: "file_def456", MountPath: juglow.String("/config.json")}},
  	{OfFile: &juglow.BetaManagedAgentsFileResourceParams{Type: "file", FileID: "file_ghi789", MountPath: juglow.String("/src/main.py")}},
  }
java
  import com.juglow.models.beta.sessions.*;
  import java.util.List;

  var resources = List.of(
      BetaManagedAgentsFileResourceParams.builder()
          .type(BetaManagedAgentsFileResourceParams.Type.FILE).fileId("file_abc123").mountPath("/data.csv").build(),
      BetaManagedAgentsFileResourceParams.builder()
          .type(BetaManagedAgentsFileResourceParams.Type.FILE).fileId("file_def456").mountPath("/config.json").build(),
      BetaManagedAgentsFileResourceParams.builder()
          .type(BetaManagedAgentsFileResourceParams.Type.FILE).fileId("file_ghi789").mountPath("/src/main.py").build()
  );
php
  $resources = [
      ['type' => 'file', 'fileID' => 'file_abc123', 'mountPath' => '/data.csv'],
      ['type' => 'file', 'fileID' => 'file_def456', 'mountPath' => '/config.json'],
      ['type' => 'file', 'fileID' => 'file_ghi789', 'mountPath' => '/src/main.py'],
  ];
ruby
  resources = [
    {type: "file", file_id: "file_abc123", mount_path: "/data.csv"},
    {type: "file", file_id: "file_def456", mount_path: "/config.json"},
    {type: "file", file_id: "file_ghi789", mount_path: "/src/main.py"}
  ]

Maksimal 500 file didukung per sesi.

Mengelola file pada sesi yang sedang berjalan

Anda dapat menambahkan atau menghapus file dari sesi setelah pembuatan menggunakan API resources sesi. Setiap resource memiliki id yang dikembalikan saat ditambahkan (atau didaftarkan), yang Anda gunakan untuk penghapusan.

bash
  jq -n --arg file_id "${FILE_ID}" '{type: "file", file_id: $file_id}' \
    | curl --fail-with-body -sS "${auth[@]}" \
        "${base_url}/sessions/${SESSION_ID}/resources" --json @-
bash
  ant beta:sessions:resources add \
    --session-id "$SESSION_ID" \
    --type file \
    --file-id "$FILE_ID"
python
  resource = client.beta.sessions.resources.add(
      session.id,
      type="file",
      file_id=file.id,
  )
  print(resource.id)  # "sesrsc_01ABC..."
typescript
  const resource = await client.beta.sessions.resources.add(session.id, {
    type: "file",
    file_id: file.id,
  });
  if (resource.type !== "file") {
    throw new Error(`Unexpected resource type: ${resource.type}`);
  }
  console.log(resource.id); // "sesrsc_01ABC..."
csharp
  var resource = await client.Beta.Sessions.Resources.Add(session.ID, new()
  {
      Type = "file",
      FileID = file.ID,
  });
  Console.WriteLine(resource.ID);  // "sesrsc_01ABC..."
go
  resource, err := client.Beta.Sessions.Resources.Add(ctx, session.ID, juglow.BetaSessionResourceAddParams{
  	BetaManagedAgentsFileResourceParams: juglow.BetaManagedAgentsFileResourceParams{
  		Type:   juglow.BetaManagedAgentsFileResourceParamsTypeFile,
  		FileID: file.ID,
  	},
  })
  if err != nil {
  	panic(err)
  }
  fmt.Println(resource.ID) // "sesrsc_01ABC..."
java
  var resource = client.beta().sessions().resources().add(
      session.id(),
      ResourceAddParams.builder()
          .betaManagedAgentsFileResourceParams(
              BetaManagedAgentsFileResourceParams.builder()
                  .type(BetaManagedAgentsFileResourceParams.Type.FILE)
                  .fileId(file.id())
                  .build()
          )
          .build()
  );
  IO.println(resource.id()); // "sesrsc_01ABC..."
php
  $resource = $client->beta->sessions->resources->add(
      $session->id,
      type: 'file',
      fileID: $file->id,
  );
  echo "{$resource->id}\n";  // "sesrsc_01ABC..."
ruby
  resource = client.beta.sessions.resources.add(
    session.id,
    type: "file",
    file_id: file.id
  )
  puts resource.id # "sesrsc_01ABC..."

Daftarkan semua resource pada sesi dengan resources.list. Untuk menghapus file, panggil resources.delete dengan ID resource:

bash
  curl --fail-with-body -sS "${auth[@]}" \
    "${base_url}/sessions/${SESSION_ID}/resources"

  curl --fail-with-body -sS "${auth[@]}" -X DELETE \
    "${base_url}/sessions/${SESSION_ID}/resources/${RESOURCE_ID}" >/dev/null
bash
  ant beta:sessions:resources list --session-id "$SESSION_ID"

  ant beta:sessions:resources delete \
    --session-id "$SESSION_ID" \
    --resource-id "$RESOURCE_ID"
python
  listed = client.beta.sessions.resources.list(session.id)
  for entry in listed.data:
      print(entry.id, entry.type)

  client.beta.sessions.resources.delete(resource.id, session_id=session.id)
typescript
  const listed = await client.beta.sessions.resources.list(session.id);
  for (const entry of listed.data) {
    if (entry.type !== "memory_store") {
      console.log(entry.id, entry.type);
    }
  }

  await client.beta.sessions.resources.delete(resource.id, {
    session_id: session.id,
  });
csharp
  var listed = await client.Beta.Sessions.Resources.List(session.ID);
  await foreach (var entry in listed.Paginate())
  {
      var type = entry.Match<string>(repo => repo.Type, fileRes => fileRes.Type, memoryStore => memoryStore.Type);
      Console.WriteLine($"{entry.ID} {type}");
  }

  await client.Beta.Sessions.Resources.Delete(resource.ID, new() { SessionID = session.ID });
go
  listed, err := client.Beta.Sessions.Resources.List(ctx, session.ID, juglow.BetaSessionResourceListParams{})
  if err != nil {
  	panic(err)
  }
  for _, entry := range listed.Data {
  	fmt.Println(entry.ID, entry.Type)
  }

  if _, err := client.Beta.Sessions.Resources.Delete(ctx, resource.ID, juglow.BetaSessionResourceDeleteParams{
  	SessionID: session.ID,
  }); err != nil {
  	panic(err)
  }
java
  var listed = client.beta().sessions().resources().list(session.id());
  for (var entry : listed.data()) {
      switch (entry.type().value()) {
          case FILE -> {
              var fileResource = entry.asFile();
              IO.println(fileResource.id() + " " + fileResource.type());
          }
          case GITHUB_REPOSITORY -> {
              var repoResource = entry.asGitHubRepository();
              IO.println(repoResource.id() + " " + repoResource.type());
          }
      }
  }

  client.beta().sessions().resources().delete(
      resource.id(),
      ResourceDeleteParams.builder().sessionId(session.id()).build()
  );
php
  $listed = $client->beta->sessions->resources->list($session->id);
  foreach ($listed->data as $entry) {
      echo "{$entry->id} {$entry->type}\n";
  }

  $client->beta->sessions->resources->delete($resource->id, sessionID: $session->id);
ruby
  listed = client.beta.sessions.resources.list(session.id)
  listed.data.each { puts "#{it.id} #{it.type}" }

  client.beta.sessions.resources.delete(resource.id, session_id: session.id)

Mendaftarkan dan mengunduh file sesi

Gunakan Files API untuk mendaftarkan file yang dicakup ke suatu sesi dan mengunduhnya. File yang ditulis agen ke /mnt/session/outputs/ muncul dalam daftar tidak lama setelah agen selesai menulisnya, terkadang beberapa detik setelah sesi menjadi idle. Jika file output yang Anda harapkan tidak ada, daftarkan lagi setelah jeda singkat; setelah file tersebut muncul dalam daftar, pengunggahannya telah selesai.

Pemfilteran berdasarkan scope_id memerlukan header beta managed-agents-2026-04-01, sehingga contoh daftar menggunakan namespace files beta dan meneruskan header tersebut secara eksplisit.

bash
  # Daftar file yang terkait dengan sebuah sesi
  curl -fsSL "https://haijun.my.id/v1/files?scope_id=sesn_abc123" \
    -H "x-api-key: $JUGLOW_API_KEY" \
    -H "juglow-version: 2023-06-01" \
    -H "juglow-beta: managed-agents-2026-04-01"

  # Unduh sebuah file
  curl -fsSL "https://haijun.my.id/v1/files/$FILE_ID/content" \
    -H "x-api-key: $JUGLOW_API_KEY" \
    -H "juglow-version: 2023-06-01" \
    -o output.txt
bash
  # Daftar file yang terkait dengan sebuah sesi
  ant beta:files list --scope-id sesn_abc123 --beta managed-agents-2026-04-01

  # Unduh sebuah file
  ant files download --file-id "$FILE_ID" --output output.txt
python
  # Daftar file yang terkait dengan sebuah sesi
  files = client.beta.files.list(
      scope_id="sesn_abc123",
      betas=["managed-agents-2026-04-01"],
  )
  for file in files:
      print(file.id, file.filename)

  # Unduh sebuah file
  content = client.files.download(files.data[0].id)
  content.write_to_file("output.txt")
typescript
  import { writeFile } from "node:fs/promises";

  // Daftar file yang terkait dengan sebuah sesi
  const files = await client.beta.files.list({
    scope_id: "sesn_abc123",
    betas: ["managed-agents-2026-04-01"]
  });
  for (const file of files.data) {
    console.log(file.id, file.filename);
  }

  // Unduh sebuah file
  const content = await client.files.download(files.data[0].id);
  await writeFile("output.txt", new Uint8Array(await content.arrayBuffer()));
csharp
  // Daftar file yang terkait dengan sebuah sesi
  var files = await client.Beta.Files.List(new()
  {
      ScopeID = "sesn_abc123",
      Betas = ["managed-agents-2026-04-01"],
  });

  // Unduh sebuah file
  using var content = await client.Files.Download(files.Items[0].ID);
  await using var output = File.Create("output.txt");
  await (await content.ReadAsStream()).CopyToAsync(output);
go
  // Daftar file yang terkait dengan sesi
  files, err := client.Beta.Files.List(ctx, juglow.BetaFileListParams{
  	ScopeID: juglow.String("sesn_abc123"),
  	Betas:   []juglow.JuglowBeta{"managed-agents-2026-04-01"},
  })
  if err != nil {
  	panic(err)
  }

  // Unduh file
  resp, err := client.Files.Download(ctx, files.Data[0].ID, juglow.FileDownloadParams{})
  if err != nil {
  	panic(err)
  }
  defer resp.Body.Close()
  out, err := os.Create("output.txt")
  if err != nil {
  	panic(err)
  }
  defer out.Close()
  if _, err := io.Copy(out, resp.Body); err != nil {
  	panic(err)
  }
java
  // Daftar file yang terkait dengan sebuah sesi
  var files = client.beta().files().list(FileListParams.builder()
      .scopeId("sesn_abc123")
      .addBeta(JuglowBeta.of("managed-agents-2026-04-01"))
      .build());

  // Unduh sebuah file
  try (HttpResponse response = client.files().download(files.data().get(0).id())) {
      try (InputStream body = response.body()) {
          Files.copy(body, Path.of("output.txt"), StandardCopyOption.REPLACE_EXISTING);
      }
  }
php
  // Daftar file yang terkait dengan sebuah sesi
  $files = $client->beta->files->list(
      scopeID: 'sesn_abc123',
      betas: ['managed-agents-2026-04-01'],
  );
  foreach ($files->getItems() as $file) {
      echo "{$file->id} {$file->filename}\n";
  }

  // Unduh sebuah file
  $content = $client->files->download($files->getItems()[0]->id);
  file_put_contents('output.txt', $content);
ruby
  # Daftar file yang terkait dengan sebuah sesi
  files = client.beta.files.list(
    scope_id: "sesn_abc123",
    betas: ["managed-agents-2026-04-01"]
  )

  # Unduh sebuah file
  content = client.files.download(files.data[0].id)
  File.binwrite("output.txt", content.read)

Jenis file yang didukung

Agen dapat bekerja dengan jenis file apa pun, termasuk:

  • Kode sumber (.py, .js, .ts, .go, .rs, dan lainnya)
  • File data (.csv, .json, .xml, .yaml)
  • Dokumen (.txt, .md)
  • Arsip (.zip, .tar.gz) - agen dapat mengekstraknya menggunakan bash
  • File biner - agen dapat memprosesnya dengan alat yang sesuai

Path file

Note: File yang di-mount di sandbox adalah salinan read-only (hanya-baca). Agen dapat membacanya tetapi tidak dapat memodifikasi file asli yang diunggah. Untuk bekerja dengan versi yang dimodifikasi, agen menulis ke path baru di dalam sandbox.

  • Path yang Anda tentukan berakar di bawah direktori uploads sesi: mount_path berupa /data.csv menempatkan file di /mnt/session/uploads/data.csv di dalam sandbox
  • Jika Anda menghilangkan mount_path, file ditempatkan di /mnt/session/uploads/
  • Direktori induk dibuat secara otomatis
  • Path harus absolut (dimulai dengan /)
On this page
Mengunggah fileMe-mount file dalam sesiBeberapa fileMengelola file pada sesi yang sedang berjalanMendaftarkan dan mengunduh file sesiJenis file yang didukungPath file