From b593a0ff6b55b4378c2c33fdca5b14bf82467a92 Mon Sep 17 00:00:00 2001 From: Nick Hale <4175918+njhale@users.noreply.github.com> Date: Tue, 13 Aug 2024 23:56:32 -0400 Subject: [PATCH] feat: add load method Add a method to load a set of tool definitions into a program. Signed-off-by: Nick Hale <4175918+njhale@users.noreply.github.com> --- src/gptscript.ts | 70 ++++++++++++++++++++++++++++++++++++++++- tests/gptscript.test.ts | 10 +++--- 2 files changed, 74 insertions(+), 6 deletions(-) diff --git a/src/gptscript.ts b/src/gptscript.ts index 5cbcd16..393752c 100644 --- a/src/gptscript.ts +++ b/src/gptscript.ts @@ -188,7 +188,7 @@ export class GPTScript { return parseBlocksFromNodes((await r.json()).nodes) } - async parseTool(toolContent: string): Promise { + async parseContent(toolContent: string): Promise { if (!this.ready) { this.ready = await this.testGPTScriptURL(20) } @@ -252,6 +252,70 @@ export class GPTScript { } } + /** + * Loads a file into a Program. + * + * @param {string} fileName - The name of the file to load. + * @param {boolean} [disableCache] - Whether to disable the cache. + * @param {string} [subTool] - The sub-tool to use. + * @return {Promise} The loaded program. + */ + async load( + fileName: string, + disableCache?: boolean, + subTool?: string + ): Promise { + return this._load({ file: fileName, disableCache, subTool }); + } + + /** + * Loads content into a Program. + * + * @param {string} content - The content to load. + * @param {boolean} [disableCache] - Whether to disable the cache. + * @param {string} [subTool] - The sub-tool to use. + * @return {Promise} The loaded program. + */ + async loadContent( + content: string, + disableCache?: boolean, + subTool?: string + ): Promise { + return this._load({ content, disableCache, subTool }); + } + + /** + * Loads tools into a Program. + * + * @param {ToolDef[]} toolDefs - The tools to load. + * @param {boolean} [disableCache] - Whether to disable the cache. + * @param {string} [subTool] - The sub-tool to use. + * @return {Promise} The loaded program. + */ + async loadTools( + toolDefs: ToolDef[], + disableCache?: boolean, + subTool?: string + ): Promise { + return this._load({ toolDefs, disableCache, subTool }); + } + + /** + * Helper method to handle the common logic for loading. + * + * @param {any} payload - The payload to send in the request. + * @return {Promise} The loaded program. + */ + private async _load(payload: any): Promise { + if (!this.ready) { + this.ready = await this.testGPTScriptURL(20); + } + const r: Run = new RunSubcommand("load", payload.toolDefs || [], {}, GPTScript.serverURL); + + r.request(payload); + return (await r.json()) as LoadResponse; + } + private async testGPTScriptURL(count: number): Promise { while (count > 0) { try { @@ -812,6 +876,10 @@ export interface PromptResponse { responses: Record } +export interface LoadResponse { + program: Program; +} + export function getEnv(key: string, def: string = ""): string { let v = process.env[key] || "" if (v == "") { diff --git a/tests/gptscript.test.ts b/tests/gptscript.test.ts index f176bed..cdac726 100644 --- a/tests/gptscript.test.ts +++ b/tests/gptscript.test.ts @@ -258,21 +258,21 @@ describe("gptscript module", () => { test("parse string tool", async () => { const tool = "How much wood would a woodchuck chuck if a woodchuck could chuck wood?" - const response = await g.parseTool(tool) + const response = await g.parseContent(tool) expect(response).toBeDefined() expect(response).toHaveLength(1) expect((response[0] as gptscript.Tool).instructions).toEqual(tool) }, 30000) test("parse empty string tool", async () => { - const response = await g.parseTool("") + const response = await g.parseContent("") expect(response).toBeDefined() expect(response).toHaveLength(0) }, 30000) test("parse string tool with text node", async () => { const tool = "How much wood would a woodchuck chuck if a woodchuck could chuck wood?\n---\n!markdown\nThis is a text node" - const response = await g.parseTool(tool) + const response = await g.parseContent(tool) expect(response).toBeDefined() expect(response).toHaveLength(2) expect((response[0] as gptscript.Tool).instructions).toEqual("How much wood would a woodchuck chuck if a woodchuck could chuck wood?") @@ -281,7 +281,7 @@ describe("gptscript module", () => { test("parse string tool global tools", async () => { const tool = "Global Tools: acorn, do-work\nHow much wood would a woodchuck chuck if a woodchuck could chuck wood?" - const response = await g.parseTool(tool) + const response = await g.parseContent(tool) expect(response).toBeDefined() expect(response).toHaveLength(1) expect((response[0] as gptscript.Tool).instructions).toEqual("How much wood would a woodchuck chuck if a woodchuck could chuck wood?") @@ -290,7 +290,7 @@ describe("gptscript module", () => { test("parse string tool first line shebang", async () => { const tool = "\n#!/usr/bin/env python\nHow much wood would a woodchuck chuck if a woodchuck could chuck wood?" - const response = await g.parseTool(tool) + const response = await g.parseContent(tool) expect(response).toBeDefined() expect(response).toHaveLength(1) expect((response[0] as gptscript.Tool).instructions).toEqual("#!/usr/bin/env python\nHow much wood would a woodchuck chuck if a woodchuck could chuck wood?")