Dropstone Docs

SDK Dropstone

Klien JS yang aman terhadap tipe untuk runtime agen Dropstone. Sesi SDK mewarisi memori lintas-permukaan Dropstone (Continuity) — satu memori persisten yang dibagikan dengan CLI, chat, dan SDK.

SDK JS/TS Dropstone menyediakan klien yang aman terhadap tipe untuk berinteraksi dengan runtime agen Dropstone. SDK ini menjalankan dropstone serve sebagai subproses dan memberi Anda klien HTTP bertipe yang mengarah ke sana. Karena SDK menjalankan agen lokal yang sama dengan yang digunakan CLI, setiap sesi SDK mewarisi memori akun Anda — ajari sekali di CLI, chat, atau SDK dan setiap permukaan sudah mengetahuinya (lihat Memori (Continuity)).

Butuh akses API tanpa antarmuka di CI?:

Untuk penggunaan programatik murni (pipeline CI, otomatisasi, serverless), gunakan HTTP API dengan DROPSTONE_API_KEY. SDK di halaman ini ditujukan untuk menyematkan agen interaktif dalam proses Node tempat biner CLI terpasang di sampingnya.

Lihat halaman Server untuk cara kerja HTTP API yang mendasarinya.


Instalasi

Instal SDK dari npm:

npm install @blankline/dropstone-sdk

Klien API tanpa antarmuka

Untuk pipeline CI, otomatisasi, dan serverless, Anda tidak memerlukan CLI sama sekali. Gunakan klien tanpa antarmuka, yang berbicara langsung ke HTTP API Dropstone dengan kunci API:

import { createDropstoneApi } from "@blankline/dropstone-sdk"

// Membaca DROPSTONE_API_KEY dari lingkungan secara otomatis.
const dropstone = createDropstoneApi()

const resp = await dropstone.chat.completions.create({
  model: "dropstone-fast", // atau "dropstone-pro" / "dropstone-heavy"
  messages: [{ role: "user", content: "Tulis haiku tentang debugging." }],
})

console.log(resp.choices[0].message.content)
console.log("Biaya: $" + resp.usage?.cost) // jumlah yang ditagih, dalam USD

Dapatkan kunci API

  1. Masuk di dropstone.io/dashboard.
  2. Buka Pengaturan → API di dropstone.io/dashboard/settings dan buat kunci — bentuknya seperti dsk_live_<43 karakter>.
  3. Atur sebagai variabel lingkungan (atau teruskan apiKey ke createDropstoneApi):
export DROPSTONE_API_KEY=dsk_live_...

Note:

Perlakukan kunci API Anda seperti kata sandi. Jangan pernah mengirimkannya ke git atau menyematkannya dalam bundel frontend. Permintaan dengan kunci API ditagih sesuai pemakaian dari saldo kredit prabayar Anda — tunjangan paket tidak berlaku. Lihat Penggunaan & batas.

Streaming bekerja dengan cara yang sama, dan klien ini kompatibel dengan OpenAI — Anda dapat mengarahkan OpenAI SDK ke URL dasar Dropstone sebagai gantinya:

const stream = await dropstone.chat.completions.create({
  model: "dropstone-fast",
  stream: true,
  messages: [{ role: "user", content: "Hitung sampai 5." }],
})

for await (const chunk of stream) {
  process.stdout.write(chunk.choices?.[0]?.delta?.content ?? "")
}

Lihat halaman HTTP API untuk referensi lengkap.


Buat klien

Buat instance dropstone:

import { createDropstone } from "@blankline/dropstone-sdk"

const { client } = await createDropstone()

Ini memulai server dan klien sekaligus. Setiap metode SDK mengembalikan { data, request, response }, jadi akses payload melalui .data.

Secara default, server masuk sebagai siapa pun yang menjalankan dropstone auth login di mesin tersebut. Di host tanpa pengawasan tidak ada akun seperti itu, jadi teruskan kunci API dan daftar izin eksplisit melalui config:

const { client } = await createDropstone({
  config: {
    provider: {
      dropstone: {
        options: {
          apiKey: process.env.DROPSTONE_API_KEY,
          baseURL: "https://api.dropstone.io/api/v1",
        },
      },
    },
    permission: { "*": "deny", read: "allow", edit: "allow", glob: "allow", grep: "allow", bash: "allow" },
  },
})

Kedua bagian diperlukan. Kunci API ditolak di /v1, dan agen build default bertanya sebelum setiap panggilan alat, jadi tanpa daftar izin, proses menunggu persetujuan yang tidak bisa diberikan siapa pun dan menggantung alih-alih gagal. Mengirim "agent": "accept all" pada prompt adalah alternatif untuk daftar izin. Lihat Server dan Izin.

Opsi

OpsiTipeDeskripsiDefault
hostnamestringNama host server127.0.0.1
portnumberPort server4096
signalAbortSignalSinyal pembatalan untuk pembatalanundefined
timeoutnumberWaktu tunggu dalam ms untuk mulai server5000
configConfigObjek konfigurasi{}

Konfigurasi

Anda dapat meneruskan objek konfigurasi untuk menyesuaikan perilaku. Instance tetap mengambil dropstone.json Anda, tetapi Anda dapat menimpa atau menambahkan konfigurasi secara inline:

import { createDropstone } from "@blankline/dropstone-sdk"

const dropstone = await createDropstone({
  hostname: "127.0.0.1",
  port: 4096,
  config: {
    model: "dropstone/dropstone-pro",
  },
})

console.log(`Server berjalan di ${dropstone.server.url}`)

dropstone.server.close()

Memori (Continuity)

Dropstone menyimpan satu memori persisten per akun. Kami menyebutnya Continuity — memori lintas-permukaan yang dibagikan oleh CLI, chat, VS Code, dan SDK. Ajari sekali di mana saja dan setiap permukaan sudah mengetahuinya.

Sesi yang Anda jalankan melalui SDK menggunakan memori akun yang sama dengan CLI. Apa yang Anda ajarkan ke CLI sudah diketahui oleh sesi SDK, dan apa yang dicatat sesi SDK tersedia kembali di CLI dan chat. Pada setiap giliran, agen secara otomatis mengingat kembali memori yang relevan sebelum menjawab, sehingga tidak perlu mempelajari ulang apa yang sudah diketahuinya.

Agen SDK juga dapat membaca dan menulis memori secara langsung, dengan alat yang sama seperti CLI:

AlatTujuan
memory_recallMengingat kembali pelajaran yang paling relevan untuk tugas saat ini
record_lessonMenyimpan pelajaran yang tahan lama (aturan atau fakta)
list_lessonsMenampilkan semua yang telah dipelajari tentang Anda
forget_lessonMenghapus pelajaran

Note:

Memori memerlukan masuk ke Dropstone. Server SDK membaca auth.json yang sama dengan CLI, jadi masuk sekali dengan dropstone dan sesi SDK mewarisi memori akun yang sama. Tidak ada yang disimpan jika Anda tidak masuk.

Contoh

Nyatakan preferensi dari kode dan itu dicatat dengan cara yang sama seperti di CLI — terlihat di CLI dan chat setelahnya:

const { client } = await createDropstone()

const session = await client.session.create({ body: { title: "Ajari memori" } })

await client.session.prompt({
  path: { id: session.data.id },
  body: {
    parts: [{ type: "text", text: "Ingat ini sebagai aturan tetap: selalu gunakan bun, bukan npm." }],
  },
})

Continuity vs AGENTS.md

AGENTS.md adalah file proyek yang Anda kirim ke Git untuk konvensi tim — stabil, terbatas pada repositori, dan dibagikan dengan siapa pun yang mengkloningnya. Continuity adalah memori akun pribadi Anda: apa yang Anda ajarkan di CLI, chat, atau SDK mengikuti akun Anda di berbagai permukaan dan proyek. Keduanya memecahkan masalah yang berbeda dan bekerja paling baik bersama — aturan proyek di AGENTS.md, memori pribadi lintas-permukaan di Continuity. Lihat Aturan dan Memori.

Apa yang diingat

Memori hanya menyimpan aturan dan fakta yang secara eksplisit Anda ajarkan — preferensi, konvensi, dan koreksi yang layak dibawa antar sesi. Ini berbeda dari konteks sementara satu sesi, yang tidak disimpan setelah sesi berakhir.

Lihat halaman Memori untuk cara Dropstone memutuskan apa yang disimpan.


Klien saja

Jika Anda sudah memiliki instance dropstone yang berjalan, Anda dapat membuat instance klien untuk terhubung ke sana:

import { createDropstoneClient } from "@blankline/dropstone-sdk"

const client = createDropstoneClient({
  baseUrl: "http://localhost:4096",
})

Opsi

OpsiTipeDeskripsiDefault
baseUrlstringURL serverhttp://localhost:4096
fetchfunctionImplementasi fetch kustomglobalThis.fetch
parseAsstringMetode penguraian responsauto
responseStylestringGaya pengembalian: data atau fieldsfields
throwOnErrorbooleanLempar kesalahan alih-alih mengembalikanfalse

Tipe

SDK menyertakan definisi TypeScript untuk semua tipe API. Impor langsung:

import type { Session, Message, Part } from "@blankline/dropstone-sdk"

Semua tipe dihasilkan dari spesifikasi OpenAPI server, jadi nama yang Anda lihat di TypeScript dipetakan satu-ke-satu ke bentuk permintaan dan respons server.


Kesalahan

SDK dapat melempar kesalahan yang dapat Anda tangkap dan tangani:

try {
  await client.session.get({ path: { id: "invalid-id" } })
} catch (error) {
  console.error("Gagal mendapatkan sesi:", (error as Error).message)
}

Output Terstruktur

Anda dapat meminta output JSON terstruktur dari model dengan menentukan format dengan skema JSON. Model akan menggunakan alat StructuredOutput untuk mengembalikan JSON tervalidasi yang cocok dengan skema Anda.

Penggunaan Dasar

const result = await client.session.prompt({
  path: { id: sessionId },
  body: {
    parts: [{ type: "text", text: "Riset Dropstone dan berikan info perusahaan" }],
    format: {
      type: "json_schema",
      schema: {
        type: "object",
        properties: {
          company: { type: "string", description: "Nama perusahaan" },
          founded: { type: "number", description: "Tahun didirikan" },
          products: {
            type: "array",
            items: { type: "string" },
            description: "Produk utama",
          },
        },
        required: ["company", "founded"],
      },
    },
  },
})

// Akses output terstruktur
console.log(result.data.info.structured_output)
// { company: "Dropstone", founded: 2024, products: ["Dropstone CLI"] }

Tipe Format Output

TipeDeskripsi
textDefault. Respons teks standar (tanpa output terstruktur)
json_schemaMengembalikan JSON tervalidasi yang cocok dengan skema yang diberikan

Format Skema JSON

Saat menggunakan type: 'json_schema', berikan:

BidangTipeDeskripsi
type'json_schema'Wajib. Menentukan mode skema JSON
schemaobjectWajib. Objek Skema JSON yang mendefinisikan struktur output
retryCountnumberOpsional. Jumlah percobaan validasi (default: 2)

Penanganan Kesalahan

Jika model gagal menghasilkan output terstruktur yang valid setelah semua percobaan, respons akan menyertakan StructuredOutputError:

if (result.data.info.error?.name === "StructuredOutputError") {
  console.error("Gagal menghasilkan output terstruktur:", result.data.info.error.message)
  console.error("Percobaan:", result.data.info.error.retries)
}

Praktik Terbaik

  1. Berikan deskripsi yang jelas di properti skema Anda untuk membantu model memahami data apa yang harus diekstrak
  2. Gunakan required untuk menentukan bidang mana yang harus ada
  3. Jaga skema tetap fokus - skema bersarang yang kompleks mungkin lebih sulit diisi dengan benar oleh model
  4. Atur retryCount yang sesuai - tingkatkan untuk skema kompleks, kurangi untuk yang sederhana

API

SDK mengekspos semua API server melalui klien yang aman terhadap tipe.


Global

MetodeDeskripsiRespons
global.health()Periksa kesehatan dan versi server{ healthy: true, version: string }

Contoh

const health = await client.global.health()
console.log(health.data.version)

App

MetodeDeskripsiRespons
app.log()Tulis entri logboolean
app.agents()Daftar semua agen yang tersediaAgent[]

Contoh

// Tulis entri log
await client.app.log({
  body: {
    service: "my-app",
    level: "info",
    message: "Operasi selesai",
  },
})

// Daftar agen yang tersedia
const agents = await client.app.agents()

Proyek

MetodeDeskripsiRespons
project.list()Daftar semua proyekProject[]
project.current()Dapatkan proyek saat iniProject

Contoh

// Daftar semua proyek
const projects = await client.project.list()

// Dapatkan proyek saat ini
const currentProject = await client.project.current()

Path

MetodeDeskripsiRespons
path.get()Dapatkan path saat iniPath

Contoh

// Dapatkan informasi path saat ini
const pathInfo = await client.path.get()

Konfigurasi

MetodeDeskripsiRespons
config.get()Dapatkan info konfigurasiConfig

Contoh

const config = await client.config.get()

Sesi

MetodeDeskripsiCatatan
session.list()Daftar sesiMengembalikan Session[]
session.get({ path })Dapatkan sesiMengembalikan Session
session.children({ path })Daftar sesi anakMengembalikan Session[]
session.create({ body })Buat sesiMengembalikan Session
session.delete({ path })Hapus sesiMengembalikan boolean
session.update({ path, body })Perbarui properti sesiMengembalikan Session
session.init({ path, body })Analisis aplikasi dan buat AGENTS.mdMengembalikan boolean
session.abort({ path })Batalkan sesi yang berjalanMengembalikan boolean
session.summarize({ path, body })Ringkas sesiMengembalikan boolean
session.messages({ path })Daftar pesan dalam sesiMengembalikan { info: Message, parts: Part[]}[]
session.message({ path })Dapatkan detail pesanMengembalikan { info: Message, parts: Part[]}
session.prompt({ path, body })Kirim pesan promptbody.noReply: true mengembalikan UserMessage (hanya konteks). Default mengembalikan AssistantMessage dengan respons AI. Mendukung body.outputFormat untuk output terstruktur
session.command({ path, body })Kirim perintah ke sesiMengembalikan { info: AssistantMessage, parts: Part[]}
session.shell({ path, body })Jalankan perintah shellMengembalikan AssistantMessage
session.revert({ path, body })Kembalikan pesanMengembalikan Session
session.unrevert({ path })Pulihkan pesan yang dikembalikanMengembalikan Session
postSessionByIdPermissionsByPermissionId({ path, body })Tanggapi permintaan izinMengembalikan boolean

Contoh

// Buat dan kelola sesi
const session = await client.session.create({
  body: { title: "Sesi saya" },
})

const sessions = await client.session.list()

// Kirim pesan prompt
const result = await client.session.prompt({
  path: { id: session.data.id },
  body: {
    model: { providerID: "dropstone", modelID: "dropstone-pro" },
    parts: [{ type: "text", text: "Halo!" }],
  },
})

// Suntikkan konteks tanpa memicu respons AI (berguna untuk plugin)
await client.session.prompt({
  path: { id: session.data.id },
  body: {
    noReply: true,
    parts: [{ type: "text", text: "Anda adalah asisten yang membantu." }],
  },
})

File

MetodeDeskripsiRespons
find.text({ query })Cari teks dalam fileArray objek kecocokan dengan path, lines, line_number, absolute_offset, submatches
find.files({ query })Temukan file dan direktori berdasarkan namastring[] (path)
find.symbols({ query })Temukan simbol ruang kerjaSymbol[]
file.read({ query })Baca file{ type: "raw" | "patch", content: string }
file.status({ query? })Dapatkan status untuk file yang dilacakFile[]

find.files mendukung beberapa bidang kueri opsional:

  • type: "file" atau "directory"
  • directory: timpa akar proyek untuk pencarian
  • limit: hasil maksimal (1–200)

Contoh

// Cari dan baca file
const textResults = await client.find.text({
  query: { pattern: "function.*dropstone" },
})

const files = await client.find.files({
  query: { query: "*.ts", type: "file" },
})

const directories = await client.find.files({
  query: { query: "packages", type: "directory", limit: 20 },
})

const content = await client.file.read({
  query: { path: "src/index.ts" },
})

Auth

MetodeDeskripsiRespons
auth.set({ ... })Atur kredensial autentikasiboolean

Contoh

await client.auth.set({
  path: { id: "dropstone" },
  body: { type: "api", key: "kunci-api-dropstone-anda" },
})

Peristiwa

MetodeDeskripsiRespons
event.subscribe()Aliran peristiwa yang dikirim serverAliran peristiwa yang dikirim server

Contoh

// Dengarkan peristiwa waktu nyata
const events = await client.event.subscribe()
for await (const event of events.stream) {
  console.log("Peristiwa:", event.type, event.properties)
}

API v2

SDK menyediakan permukaan v1 yang stabil (digunakan dalam contoh di atas) dan permukaan v2 yang mencerminkan kontrak Effect HttpApi yang lebih baru. Pilih v2 untuk integrasi baru:

import { createDropstone } from "@blankline/dropstone-sdk/v2"

const { client, server } = await createDropstone()
// v2 mengekspos hierarki sumber daya yang lebih kaya: workspace, worktree, file, find, dll.
const files = await client.file.list({ path: "src" })

Permukaan v1 dipertahankan untuk kompatibilitas mundur. Titik akhir baru hanya tersedia di v2.

Ctrl+I