Benutzerdefinierte Tools
Erstellen Sie Tools, die das LLM in Dropstone aufrufen kann.
Benutzerdefinierte Tools sind Funktionen, die Sie erstellen und die das LLM während Gesprächen aufrufen kann. Sie funktionieren zusammen mit Dropstones integrierten Tools wie read, write und bash.
Ein Tool erstellen
Tools werden als TypeScript- oder JavaScript-Dateien definiert. Die Tool-Definition selbst ist TS/JS, aber die Arbeit, die es verrichtet, kann in jeder Sprache implementiert werden: Shell-Skripte, Python, Go, alles, das Sie aus Buns Shell-Helfern spawnen können.
Speicherort
Sie können definiert werden:
- Lokal, indem Sie sie im
.dropstone/tools/-Verzeichnis Ihres Projekts platzieren. - Oder global, indem Sie sie in
~/.config/dropstone/tools/platzieren.
Struktur
Der einfachste Weg, Tools zu erstellen, ist die Verwendung des tool()-Helfers, der Typsicherheit und Validierung bietet.
import { tool } from "@blankline/dropstone-plugin"
export default tool({
description: "Query the project database",
args: {
query: tool.schema.string().describe("SQL query to execute"),
},
async execute(args) {
// Your database logic here
return `Executed query: ${args.query}`
},
})
Der Dateiname wird zum Tool-Namen. Das Obige erstellt ein database-Tool.
Mehrere Tools pro Datei
Sie können auch mehrere Tools aus einer einzelnen Datei exportieren. Jeder Export wird zu einem separaten Tool mit dem Namen <filename>_<exportname>:
import { tool } from "@blankline/dropstone-plugin"
export const add = tool({
description: "Add two numbers",
args: {
a: tool.schema.number().describe("First number"),
b: tool.schema.number().describe("Second number"),
},
async execute(args) {
return args.a + args.b
},
})
export const multiply = tool({
description: "Multiply two numbers",
args: {
a: tool.schema.number().describe("First number"),
b: tool.schema.number().describe("Second number"),
},
async execute(args) {
return args.a * args.b
},
})
Dies erstellt zwei Tools: math_add und math_multiply.
Namenskollisionen mit integrierten Tools
Benutzerdefinierte Tools werden nach Tool-Name indiziert. Wenn ein benutzerdefiniertes Tool denselben Namen wie ein integriertes Tool verwendet, hat das benutzerdefinierte Tool Vorrang.
Beispielsweise ersetzt diese Datei das integrierte bash-Tool:
import { tool } from "@blankline/dropstone-plugin"
export default tool({
description: "Restricted bash wrapper",
args: {
command: tool.schema.string(),
},
async execute(args) {
return `blocked: ${args.command}`
},
})
Note:
Bevorzugen Sie eindeutige Namen, es sei denn, Sie möchten ein integriertes Tool absichtlich ersetzen. Wenn Sie ein integriertes Tool deaktivieren möchten, ohne es zu überschreiben, verwenden Sie Berechtigungen.
Argumente
Sie können tool.schema verwenden, das einfach Zod ist, um Argumenttypen zu definieren.
args: {
query: tool.schema.string().describe("SQL query to execute")
}
Sie können auch Zod direkt importieren und ein einfaches Objekt zurückgeben:
import { z } from "zod"
export default {
description: "Tool description",
args: {
param: z.string().describe("Parameter description"),
},
async execute(args, context) {
// Tool implementation
return "result"
},
}
Kontext
Tools erhalten Kontext über die aktuelle Sitzung:
import { tool } from "@blankline/dropstone-plugin"
export default tool({
description: "Get project information",
args: {},
async execute(args, context) {
// Access context information
const { agent, sessionID, messageID, directory, worktree } = context
return `Agent: ${agent}, Session: ${sessionID}, Message: ${messageID}, Directory: ${directory}, Worktree: ${worktree}`
},
})
Verwenden Sie context.directory für das Arbeitsverzeichnis der Sitzung.
Verwenden Sie context.worktree für das Git-Worktree-Root.
Beispiele
Ein Tool in Python schreiben
Sie können Ihre Tools in jeder Sprache schreiben, die Sie möchten. Hier ist ein Beispiel, das zwei Zahlen mit Python addiert.
Erstellen Sie zunächst das Tool als Python-Skript:
import sys
a = int(sys.argv[1])
b = int(sys.argv[2])
print(a + b)
Erstellen Sie dann die Tool-Definition, die es aufruft:
import { tool } from "@blankline/dropstone-plugin"
import path from "path"
export default tool({
description: "Add two numbers using Python",
args: {
a: tool.schema.number().describe("First number"),
b: tool.schema.number().describe("Second number"),
},
async execute(args, context) {
const script = path.join(context.worktree, ".dropstone/tools/add.py")
const result = await Bun.$`python3 ${script} ${args.a} ${args.b}`.text()
return result.trim()
},
})
Hier verwenden wir das Bun.$-Dienstprogramm, um das Python-Skript auszuführen.