Skip to content

chore: make ToolDef fields optional for easier definition #51

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 33 additions & 25 deletions src/gptscript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -572,8 +572,10 @@ interface ChatState {

export type Arguments = string | Record<string, string>

export const ArgumentSchemaType = "object" as const

export interface ArgumentSchema {
type: "object"
type: typeof ArgumentSchemaType
properties?: Record<string, Property>
required?: string[]
}
Expand All @@ -584,8 +586,10 @@ export interface Program {
openAPICache: Record<string, any>
}

export const PropertyType = "string" as const

export interface Property {
type: "string"
type: typeof PropertyType
description: string
default?: string
}
Expand All @@ -599,26 +603,26 @@ export interface Repo {
}

export interface ToolDef {
name: string
description: string
maxTokens: number
modelName: string
modelProvider: boolean
jsonResponse: boolean
name?: string
description?: string
maxTokens?: number
modelName?: string
modelProvider?: boolean
jsonResponse?: boolean
temperature?: number
cache?: boolean
chat: boolean
chat?: boolean
internalPrompt?: boolean
arguments: ArgumentSchema
tools: string[]
globalTools: string[]
globalModelName: string
context: string[]
exportContext: string[]
export: string[]
agents: string[]
credentials: string[]
instructions: string
arguments?: ArgumentSchema
tools?: string[]
globalTools?: string[]
globalModelName?: string
context?: string[]
exportContext?: string[]
export?: string[]
agents?: string[]
credentials?: string[]
instructions?: string
}

export interface ToolReference {
Expand All @@ -628,13 +632,15 @@ export interface ToolReference {
toolID: string
}

export const ToolType = "tool" as const

export interface Tool extends ToolDef {
id: string
type: "tool"
toolMapping: Record<string, ToolReference[]>
localTools: Record<string, string>
source: SourceRef
workingDir: string
type: typeof ToolType
toolMapping?: Record<string, ToolReference[]>
localTools?: Record<string, string>
source?: SourceRef
workingDir?: string
}

export interface SourceRef {
Expand All @@ -643,9 +649,11 @@ export interface SourceRef {
repo?: Repo
}

export const TextType = "text" as const

export interface Text {
id: string
type: "text"
type: typeof TextType
format: string
content: string
}
Expand Down
47 changes: 27 additions & 20 deletions tests/gptscript.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as gptscript from "../src/gptscript"
import {ArgumentSchemaType, PropertyType, ToolType} from "../src/gptscript"
import path from "path"
import {fileURLToPath} from "url"

Expand Down Expand Up @@ -45,7 +46,7 @@ describe("gptscript module", () => {
instructions: "who was the president of the united states in 1928?"
}

const run = await g.evaluate(t as any)
const run = await g.evaluate(t)
expect(run).toBeDefined()
expect(await run.text()).toContain("Calvin Coolidge")
})
Expand All @@ -60,7 +61,7 @@ describe("gptscript module", () => {
disableCache: true,
}

const run = await g.evaluate(t as any, opts)
const run = await g.evaluate(t, opts)
run.on(gptscript.RunEventType.CallProgress, (data: gptscript.CallFrame) => {
for (let output of data.output) out += `system: ${output.content}`
})
Expand All @@ -80,7 +81,7 @@ describe("gptscript module", () => {
context: [path.join(__dirname, "fixtures", "acorn-labs-context.gpt")]
}

const run = await g.evaluate(t as any, {disableCache: true})
const run = await g.evaluate(t, {disableCache: true})
out = await run.text()
err = run.err

Expand Down Expand Up @@ -167,13 +168,18 @@ describe("gptscript module", () => {
name: "ask",
description: "This tool is used to ask a question",
arguments: {
type: "object",
question: "The question to ask"
type: ArgumentSchemaType,
properties: {
question: {
type: PropertyType,
description: "The question to ask",
}
}
},
instructions: "${question}"
}

const response = await (await g.evaluate([t0 as any, t1 as any])).text()
const response = await (await g.evaluate([t0, t1])).text()
expect(response).toBeDefined()
expect(response).toContain("Calvin Coolidge")
}, 30000)
Expand All @@ -182,11 +188,11 @@ describe("gptscript module", () => {
const t0 = {
tools: ["ask"],
instructions: "Only use the ask tool to ask who was the president of the united states in 1928?"
} as any
}
const t1 = {
name: "other",
instructions: "Who was the president of the united states in 1986?"
} as any
}
const t2 = {
name: "ask",
description: "This tool is used to ask a question",
Expand All @@ -195,7 +201,7 @@ describe("gptscript module", () => {
question: "The question to ask"
},
instructions: "${question}"
} as any
}

const response = await (await g.evaluate([t0, t1, t2], {subTool: "other"})).text()
expect(response).toBeDefined()
Expand Down Expand Up @@ -246,21 +252,22 @@ describe("gptscript module", () => {

test("format tool", async () => {
const tool = {
type: "tool",
id: "my-tool",
type: ToolType,
tools: ["sys.write", "sys.read"],
instructions: "This is a test",
arguments: {
type: "object",
type: ArgumentSchemaType,
properties: {
text: {
type: "string",
type: PropertyType,
description: "The text to write"
}
}
}
}

const response = await g.stringify([tool as any])
const response = await g.stringify([tool])
expect(response).toBeDefined()
expect(response).toContain("Tools: sys.write, sys.read")
expect(response).toContain("This is a test")
Expand All @@ -277,7 +284,7 @@ describe("gptscript module", () => {
const opts = {
disableCache: true,
}
let run = await g.evaluate(t as any, opts)
let run = await g.evaluate(t, opts)

const inputs = [
"List the three largest states in the United States by area.",
Expand Down Expand Up @@ -375,14 +382,14 @@ describe("gptscript module", () => {
instructions: "You are a chat bot. Don't finish the conversation until I say 'bye'.",
tools: ["sys.chat.finish"]
}
let run = await g.evaluate(t as any, {disableCache: true})
let run = await g.evaluate(t, {disableCache: true})

run = run.nextChat("List the three largest states in the United States by area.")
expect(await run.text()).toContain("California")
expect(run.err).toEqual("")
expect(run.state).toEqual(gptscript.RunState.Continue)

run = await g.evaluate(t as any, {
run = await g.evaluate(t, {
disableCache: true,
input: "What is the capital of the second one?",
chatState: run.currentChatState()
Expand All @@ -399,7 +406,7 @@ describe("gptscript module", () => {
instructions: "List the files in the current working directory.",
tools: ["sys.exec"]
}
const run = await g.evaluate(t as any, {confirm: true})
const run = await g.evaluate(t, {confirm: true})
run.on(gptscript.RunEventType.CallConfirm, async (data: gptscript.CallFrame) => {
expect(data.input).toContain(`"ls"`)
confirmFound = true
Expand All @@ -417,7 +424,7 @@ describe("gptscript module", () => {
instructions: "List the files in the current working directory.",
tools: ["sys.exec"]
}
const run = await g.evaluate(t as any, {confirm: true})
const run = await g.evaluate(t, {confirm: true})
run.on(gptscript.RunEventType.CallConfirm, async (data: gptscript.CallFrame) => {
expect(data.input).toContain(`"ls"`)
confirmFound = true
Expand All @@ -435,7 +442,7 @@ describe("gptscript module", () => {
instructions: "Use the sys.prompt user to ask the user for 'first name' which is not sensitive. After you get their first name, say hello.",
tools: ["sys.prompt"]
}
const run = await g.evaluate(t as any, {prompt: true})
const run = await g.evaluate(t, {prompt: true})
run.on(gptscript.RunEventType.Prompt, async (data: gptscript.PromptFrame) => {
expect(data.message).toContain("first name")
expect(data.fields.length).toEqual(1)
Expand All @@ -457,7 +464,7 @@ describe("gptscript module", () => {
instructions: "Use the sys.prompt user to ask the user for 'first name' which is not sensitive. After you get their first name, say hello.",
tools: ["sys.prompt"]
}
const run = await g.evaluate(t as any)
const run = await g.evaluate(t)
run.on(gptscript.RunEventType.Prompt, async (data: gptscript.PromptFrame) => {
promptFound = true
})
Expand Down