Dropstone Docs

Dropstone SDK

Client JS type-safe per il runtime dell'agente Dropstone. Le sessioni SDK ereditano la memoria cross-surface di Dropstone (Continuity) — una memoria persistente condivisa con CLI, chat e SDK.

L'SDK JS/TS di Dropstone fornisce un client type-safe per interagire con il runtime dell'agente Dropstone. Avvia dropstone serve come sottoprocesso e ti offre un client HTTP tipizzato puntato su di esso. Poiché esegue lo stesso agente locale usato dalla CLI, ogni sessione SDK eredita la memoria del tuo account — insegnagli una volta nella CLI, nella chat o nell'SDK e ogni superficie la conoscerà già (vedi Memoria (Continuity)).

Ti serve accesso API headless in CI?:

Per uso puramente programmatico (pipeline CI, automazione, serverless), preferisci l'API HTTP con una DROPSTONE_API_KEY. L'SDK in questa pagina è pensato per incorporare l'agente interattivo in un processo Node dove il binario CLI è installato accanto.

Vedi la pagina Server per come funziona l'API HTTP sottostante.


Installazione

Installa l'SDK da npm:

npm install @blankline/dropstone-sdk

Client API headless

Per pipeline CI, automazione e serverless non ti serve affatto la CLI. Usa il client headless, che parla direttamente con l'API HTTP di Dropstone con una chiave API:

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

// Legge DROPSTONE_API_KEY dall'ambiente automaticamente.
const dropstone = createDropstoneApi()

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

console.log(resp.choices[0].message.content)
console.log("Costo: $" + resp.usage?.cost) // importo addebitato, in USD

Ottieni una chiave API

  1. Accedi su dropstone.io/dashboard.
  2. Apri Impostazioni → API su dropstone.io/dashboard/settings e crea una chiave — ha questo formato dsk_live_<43 caratteri>.
  3. Impostala come variabile d'ambiente (oppure passa apiKey a createDropstoneApi):
export DROPSTONE_API_KEY=dsk_live_...

Note:

Tratta la tua chiave API come una password. Non committarla mai in git né incorporarla in un bundle frontend. Le richieste con chiave API vengono addebitate pay-per-use dal tuo saldo di credito prepagato — le quote dei piani non si applicano. Vedi Utilizzo e limiti.

Lo streaming funziona allo stesso modo e il client è compatibile con OpenAI — puoi puntare l'SDK OpenAI all'URL di base di Dropstone:

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

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

Vedi la pagina API HTTP per il riferimento completo.


Crea client

Crea un'istanza di dropstone:

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

const { client } = await createDropstone()

Questo avvia sia un server che un client. Ogni metodo SDK restituisce { data, request, response }, quindi accedi al payload tramite .data.

Opzioni

OpzioneTipoDescrizioneDefault
hostnamestringHostname del server127.0.0.1
portnumberPorta del server4096
signalAbortSignalSegnale di annullamentoundefined
timeoutnumberTimeout in ms per l'avvio5000
configConfigOggetto di configurazione{}

Config

Puoi passare un oggetto di configurazione per personalizzare il comportamento. L'istanza rileva comunque il tuo dropstone.json, ma puoi sovrascrivere o aggiungere configurazione 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 in esecuzione su ${dropstone.server.url}`)

dropstone.server.close()

Memoria (Continuity)

Dropstone mantiene una memoria persistente per account. La chiamiamo Continuity — una memoria cross-surface condivisa da CLI, chat, VS Code e SDK. Insegnale una volta ovunque e ogni superficie la conoscerà già.

Le sessioni che esegui tramite l'SDK usano la stessa memoria dell'account della CLI. Ciò che insegni alla CLI è già noto alle sessioni SDK, e ciò che una sessione SDK registra è disponibile di nuovo nella CLI e nella chat. A ogni turno, l'agente richiama automaticamente la memoria pertinente prima di rispondere, così non deve re-imparare ciò che già sa.

L'agente SDK può anche leggere e scrivere la memoria direttamente, con gli stessi strumenti della CLI:

StrumentoScopo
memory_recallRichiama le lezioni più pertinenti per l'attività corrente
record_lessonSalva una lezione duratura (una regola o un fatto)
list_lessonsMostra tutto ciò che ha imparato su di te
forget_lessonRimuovi una lezione

Note:

La memoria richiede l'accesso a Dropstone. Il server SDK legge lo stesso auth.json della CLI, quindi accedi una volta con dropstone e le sessioni SDK erediteranno la stessa memoria dell'account. Non viene memorizzato nulla se non hai effettuato l'accesso.

Esempio

Dichiara una preferenza dal codice e verrà registrata nello stesso modo in cui avverrebbe nella CLI — visibile in seguito nella CLI e nella chat:

const { client } = await createDropstone()

const session = await client.session.create({ body: { title: "Insegna memoria" } })

await client.session.prompt({
  path: { id: session.data.id },
  body: {
    parts: [{ type: "text", text: "Ricorda questo come regola fissa: usa sempre bun, non npm." }],
  },
})

Continuity vs AGENTS.md

AGENTS.md è un file di progetto che committi in Git per le convenzioni del team — stabile, limitato al repository e condiviso con chiunque lo cloni. Continuity è la tua memoria privata dell'account: ciò che insegni nella CLI, nella chat o nell'SDK segue il tuo account attraverso superfici e progetti. Risolvono problemi diversi e funzionano meglio insieme — regole di progetto in AGENTS.md, memoria personale cross-surface in Continuity. Vedi Regole e Memoria.

Cosa viene ricordato

La memoria memorizza solo le regole e i fatti che le insegni esplicitamente — preferenze, convenzioni e correzioni che vale la pena portare tra le sessioni. È distinta dal contesto effimero di una singola sessione, che non viene conservato dopo la fine della sessione.

Vedi la pagina Memoria per come Dropstone decide cosa conservare.


Solo client

Se hai già un'istanza in esecuzione di dropstone, puoi creare un'istanza client per connetterti ad essa:

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

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

Opzioni

OpzioneTipoDescrizioneDefault
baseUrlstringURL del serverhttp://localhost:4096
fetchfunctionImplementazione fetch personalizzataglobalThis.fetch
parseAsstringMetodo di parsing della rispostaauto
responseStylestringStile di ritorno: data o fieldsfields
throwOnErrorbooleanLancia errori invece di restituirlifalse

Tipi

L'SDK include definizioni TypeScript per tutti i tipi API. Importali direttamente:

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

Tutti i tipi sono generati dalla specifica OpenAPI del server, quindi i nomi che vedi in TypeScript corrispondono uno-a-uno alle forme di richiesta e risposta del server.


Errori

L'SDK può lanciare errori che puoi catturare e gestire:

try {
  await client.session.get({ path: { id: "invalid-id" } })
} catch (error) {
  console.error("Impossibile ottenere la sessione:", (error as Error).message)
}

Output strutturato

Puoi richiedere output JSON strutturato dal modello specificando un format con uno schema JSON. Il modello userà uno strumento StructuredOutput per restituire JSON validato che corrisponde al tuo schema.

Utilizzo di base

const result = await client.session.prompt({
  path: { id: sessionId },
  body: {
    parts: [{ type: "text", text: "Ricerca Dropstone e fornisci informazioni sull'azienda" }],
    format: {
      type: "json_schema",
      schema: {
        type: "object",
        properties: {
          company: { type: "string", description: "Nome dell'azienda" },
          founded: { type: "number", description: "Anno di fondazione" },
          products: {
            type: "array",
            items: { type: "string" },
            description: "Prodotti principali",
          },
        },
        required: ["company", "founded"],
      },
    },
  },
})

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

Tipi di formato di output

TipoDescrizione
textDefault. Risposta testuale standard (nessun output strutturato)
json_schemaRestituisce JSON validato che corrisponde allo schema fornito

Formato schema JSON

Quando usi type: 'json_schema', fornisci:

CampoTipoDescrizione
type'json_schema'Obbligatorio. Specifica la modalità schema JSON
schemaobjectObbligatorio. Oggetto schema JSON che definisce la struttura dell'output
retryCountnumberOpzionale. Numero di tentativi di validazione (default: 2)

Gestione degli errori

Se il modello non riesce a produrre output strutturato valido dopo tutti i tentativi, la risposta includerà un StructuredOutputError:

if (result.data.info.error?.name === "StructuredOutputError") {
  console.error("Impossibile produrre output strutturato:", result.data.info.error.message)
  console.error("Tentativi:", result.data.info.error.retries)
}

Best practice

  1. Fornisci descrizioni chiare nelle proprietà dello schema per aiutare il modello a capire quali dati estrarre
  2. Usa required per specificare quali campi devono essere presenti
  3. Mantieni gli schemi mirati - schemi annidati complessi possono essere più difficili da compilare correttamente per il modello
  4. Imposta un retryCount appropriato - aumentalo per schemi complessi, diminuiscilo per quelli semplici

API

L'SDK espone tutte le API del server tramite un client type-safe.


Global

MetodoDescrizioneRisposta
global.health()Controlla salute e versione del server{ healthy: true, version: string }

Esempi

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

App

MetodoDescrizioneRisposta
app.log()Scrivi una voce di logboolean
app.agents()Elenca tutti gli agenti disponibiliAgent[]

Esempi

// Scrivi una voce di log
await client.app.log({
  body: {
    service: "my-app",
    level: "info",
    message: "Operazione completata",
  },
})

// Elenca gli agenti disponibili
const agents = await client.app.agents()

Project

MetodoDescrizioneRisposta
project.list()Elenca tutti i progettiProject[]
project.current()Ottieni il progetto correnteProject

Esempi

// Elenca tutti i progetti
const projects = await client.project.list()

// Ottieni il progetto corrente
const currentProject = await client.project.current()

Path

MetodoDescrizioneRisposta
path.get()Ottieni il percorso correntePath

Esempi

// Ottieni informazioni sul percorso corrente
const pathInfo = await client.path.get()

Config

MetodoDescrizioneRisposta
config.get()Ottieni info di configurazioneConfig

Esempi

const config = await client.config.get()

Sessions

MetodoDescrizioneNote
session.list()Elenca le sessioniRestituisce Session[]
session.get({ path })Ottieni sessioneRestituisce Session
session.children({ path })Elenca le sessioni figlieRestituisce Session[]
session.create({ body })Crea sessioneRestituisce Session
session.delete({ path })Elimina sessioneRestituisce boolean
session.update({ path, body })Aggiorna proprietà della sessioneRestituisce Session
session.init({ path, body })Analizza l'app e crea AGENTS.mdRestituisce boolean
session.abort({ path })Interrompi una sessione in esecuzioneRestituisce boolean
session.summarize({ path, body })Riepiloga la sessioneRestituisce boolean
session.messages({ path })Elenca i messaggi in una sessioneRestituisce { info: Message, parts: Part[]}[]
session.message({ path })Ottieni dettagli del messaggioRestituisce { info: Message, parts: Part[]}
session.prompt({ path, body })Invia messaggio di promptbody.noReply: true restituisce UserMessage (solo contesto). Il default restituisce AssistantMessage con risposta AI. Supporta body.outputFormat per output strutturato
session.command({ path, body })Invia comando alla sessioneRestituisce { info: AssistantMessage, parts: Part[]}
session.shell({ path, body })Esegui un comando shellRestituisce AssistantMessage
session.revert({ path, body })Annulla un messaggioRestituisce Session
session.unrevert({ path })Ripristina messaggi annullatiRestituisce Session
postSessionByIdPermissionsByPermissionId({ path, body })Rispondi a una richiesta di permessoRestituisce boolean

Esempi

// Crea e gestisci sessioni
const session = await client.session.create({
  body: { title: "La mia sessione" },
})

const sessions = await client.session.list()

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

// Inietta contesto senza attivare la risposta AI (utile per i plugin)
await client.session.prompt({
  path: { id: session.data.id },
  body: {
    noReply: true,
    parts: [{ type: "text", text: "Sei un assistente utile." }],
  },
})

Files

MetodoDescrizioneRisposta
find.text({ query })Cerca testo nei fileArray di oggetti di corrispondenza con path, lines, line_number, absolute_offset, submatches
find.files({ query })Trova file e directory per nomestring[] (percorsi)
find.symbols({ query })Trova simboli del workspaceSymbol[]
file.read({ query })Leggi un file{ type: "raw" | "patch", content: string }
file.status({ query? })Ottieni stato per file tracciatiFile[]

find.files supporta alcuni campi di query opzionali:

  • type: "file" o "directory"
  • directory: sovrascrivi la radice del progetto per la ricerca
  • limit: massimo risultati (1–200)

Esempi

// Cerca e leggi 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

MetodoDescrizioneRisposta
auth.set({ ... })Imposta le credenziali di autenticazioneboolean

Esempi

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

Events

MetodoDescrizioneRisposta
event.subscribe()Stream di eventi server-sentStream di eventi server-sent

Esempi

// Ascolta eventi in tempo reale
const events = await client.event.subscribe()
for await (const event of events.stream) {
  console.log("Evento:", event.type, event.properties)
}

API v2

L'SDK include una superficie v1 stabile (usata negli esempi precedenti) e una superficie v2 che rispecchia il contratto più recente Effect HttpApi. Preferisci v2 per le nuove integrazioni:

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

const { client, server } = await createDropstone()
// v2 espone una gerarchia di risorse più ricca: workspace, worktree, file, find, ecc.
const files = await client.file.list({ path: "src" })

La superficie v1 è mantenuta per compatibilità all'indietro. I nuovi endpoint arrivano solo su v2.

Ctrl+I