Skip to content

Commit 96d3724

Browse files
authored
feat: add dataset functions (#95)
Signed-off-by: Grant Linville <[email protected]>
1 parent 106e628 commit 96d3724

File tree

2 files changed

+185
-1
lines changed

2 files changed

+185
-1
lines changed

src/gptscript.ts

+105
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export interface GlobalOpts {
1212
BaseURL?: string
1313
DefaultModel?: string
1414
DefaultModelProvider?: string
15+
DatasetToolRepo?: string
1516
Env?: string[]
1617
}
1718

@@ -390,6 +391,84 @@ export class GPTScript {
390391
await r.text()
391392
}
392393

394+
// Dataset methods
395+
396+
async listDatasets(workspace: string): Promise<Array<DatasetMeta>> {
397+
if (workspace == "") {
398+
workspace = process.env.GPTSCRIPT_WORKSPACE_DIR ?? ""
399+
}
400+
401+
const r: Run = new RunSubcommand("datasets", "", {URL: this.opts.URL, Token: this.opts.Token})
402+
r.request({input: "{}", workspace: workspace, datasetToolRepo: this.opts.DatasetToolRepo ?? ""})
403+
const result = await r.text()
404+
return JSON.parse(result) as Array<DatasetMeta>
405+
}
406+
407+
async createDataset(workspace: string, name: string, description: string): Promise<Dataset> {
408+
if (workspace == "") {
409+
workspace = process.env.GPTSCRIPT_WORKSPACE_DIR ?? ""
410+
}
411+
412+
const r: Run = new RunSubcommand("datasets/create", "", {URL: this.opts.URL, Token: this.opts.Token})
413+
r.request({
414+
input: JSON.stringify({datasetName: name, datasetDescription: description}),
415+
workspace: workspace,
416+
datasetToolRepo: this.opts.DatasetToolRepo ?? ""
417+
})
418+
const result = await r.text()
419+
return JSON.parse(result) as Dataset
420+
}
421+
422+
async addDatasetElement(workspace: string, datasetID: string, elementName: string, elementDescription: string, elementContent: string): Promise<DatasetElementMeta> {
423+
if (workspace == "") {
424+
workspace = process.env.GPTSCRIPT_WORKSPACE_DIR ?? ""
425+
}
426+
427+
const r: Run = new RunSubcommand("datasets/add-element", "", {URL: this.opts.URL, Token: this.opts.Token})
428+
r.request({
429+
input: JSON.stringify({
430+
datasetID,
431+
elementName,
432+
elementDescription,
433+
elementContent
434+
}),
435+
workspace: workspace,
436+
datasetToolRepo: this.opts.DatasetToolRepo ?? ""
437+
})
438+
const result = await r.text()
439+
return JSON.parse(result) as DatasetElementMeta
440+
}
441+
442+
async listDatasetElements(workspace: string, datasetID: string): Promise<Array<DatasetElementMeta>> {
443+
if (workspace == "") {
444+
workspace = process.env.GPTSCRIPT_WORKSPACE_DIR ?? ""
445+
}
446+
447+
const r: Run = new RunSubcommand("datasets/list-elements", "", {URL: this.opts.URL, Token: this.opts.Token})
448+
r.request({
449+
input: JSON.stringify({datasetID}),
450+
workspace: workspace,
451+
datasetToolRepo: this.opts.DatasetToolRepo ?? ""
452+
})
453+
const result = await r.text()
454+
return JSON.parse(result) as Array<DatasetElementMeta>
455+
}
456+
457+
async getDatasetElement(workspace: string, datasetID: string, elementName: string): Promise<DatasetElement> {
458+
if (workspace == "") {
459+
workspace = process.env.GPTSCRIPT_WORKSPACE_DIR ?? ""
460+
}
461+
462+
const r: Run = new RunSubcommand("datasets/get-element", "", {URL: this.opts.URL, Token: this.opts.Token})
463+
r.request({
464+
input: JSON.stringify({datasetID, element: elementName}),
465+
workspace: workspace,
466+
datasetToolRepo: this.opts.DatasetToolRepo ?? ""
467+
})
468+
const result = await r.text()
469+
return JSON.parse(result) as DatasetElement
470+
}
471+
393472
/**
394473
* Helper method to handle the common logic for loading.
395474
*
@@ -1103,3 +1182,29 @@ function jsonToCredential(cred: string): Credential {
11031182
refreshToken: c.refreshToken
11041183
}
11051184
}
1185+
1186+
// Dataset types
1187+
1188+
export interface DatasetElementMeta {
1189+
name: string
1190+
description: string
1191+
}
1192+
1193+
export interface DatasetElement {
1194+
name: string
1195+
description: string
1196+
contents: string
1197+
}
1198+
1199+
export interface DatasetMeta {
1200+
id: string
1201+
name: string
1202+
description: string
1203+
}
1204+
1205+
export interface Dataset {
1206+
id: string
1207+
name: string
1208+
description: string
1209+
elements: Record<string, DatasetElementMeta>
1210+
}

tests/gptscript.test.ts

+80-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as gptscript from "../src/gptscript"
22
import {
33
ArgumentSchemaType,
4-
CredentialType,
4+
CredentialType, Dataset,
55
getEnv,
66
PropertyType,
77
RunEventType,
@@ -13,6 +13,7 @@ import path from "path"
1313
import {fileURLToPath} from "url"
1414
import * as fs from "node:fs"
1515
import {randomBytes} from "node:crypto"
16+
import {tmpdir} from "node:os";
1617

1718
let gFirst: gptscript.GPTScript
1819
let g: gptscript.GPTScript
@@ -885,4 +886,82 @@ describe("gptscript module", () => {
885886
throw new Error("failed to verify deletion: " + e)
886887
}
887888
}, 20000)
889+
890+
test("dataset operations", async () => {
891+
const datasetName = "test-" + randomBytes(10).toString("hex")
892+
const workspace = fs.mkdtempSync(path.join(tmpdir(), "node-gptscript-"))
893+
let datasetID: string
894+
895+
// Create
896+
try {
897+
const dataset = await g.createDataset(workspace, datasetName, "a test dataset")
898+
expect(dataset).toBeDefined()
899+
expect(dataset.name).toEqual(datasetName)
900+
expect(dataset.description).toEqual("a test dataset")
901+
expect(dataset.id.length).toBeGreaterThan(0)
902+
expect(dataset.elements).toEqual({})
903+
datasetID = dataset.id
904+
} catch (e) {
905+
throw new Error("failed to create dataset: " + e)
906+
}
907+
908+
// Add elements
909+
try {
910+
const e1 = await g.addDatasetElement(
911+
workspace,
912+
datasetID,
913+
"element1",
914+
"",
915+
"this is element 1 contents"
916+
)
917+
expect(e1.name).toEqual("element1")
918+
expect(e1.description).toEqual("")
919+
920+
const e2 = await g.addDatasetElement(
921+
workspace,
922+
datasetID,
923+
"element2",
924+
"a description",
925+
"this is element 2 contents"
926+
)
927+
expect(e2.name).toEqual("element2")
928+
expect(e2.description).toEqual("a description")
929+
} catch (e) {
930+
throw new Error("failed to add elements: " + e)
931+
}
932+
933+
// Get elements
934+
try {
935+
const e1 = await g.getDatasetElement(workspace, datasetID, "element1")
936+
expect(e1.name).toEqual("element1")
937+
expect(e1.description).toBeUndefined()
938+
expect(e1.contents).toEqual("this is element 1 contents")
939+
940+
const e2 = await g.getDatasetElement(workspace, datasetID, "element2")
941+
expect(e2.name).toEqual("element2")
942+
expect(e2.description).toEqual("a description")
943+
expect(e2.contents).toEqual("this is element 2 contents")
944+
} catch (e) {
945+
throw new Error("failed to get elements: " + e)
946+
}
947+
948+
// List the elements in the dataset
949+
try {
950+
const elements = await g.listDatasetElements(workspace, datasetID)
951+
expect(elements.length).toEqual(2)
952+
expect(elements.map(e => e.name)).toContain("element1")
953+
expect(elements.map(e => e.name)).toContain("element2")
954+
} catch (e) {
955+
throw new Error("failed to list elements: " + e)
956+
}
957+
958+
// List datasets
959+
try {
960+
const datasets = await g.listDatasets(workspace)
961+
expect(datasets.length).toBeGreaterThan(0)
962+
expect(datasets.map(d => d.name)).toContain(datasetName)
963+
} catch (e) {
964+
throw new Error("failed to list datasets: " + e)
965+
}
966+
}, 20000)
888967
})

0 commit comments

Comments
 (0)