Skip to content

Commit 507f74d

Browse files
authored
Merge pull request #40 from thedadams/export-chat-state
feat: add ability to export chat state
2 parents 0e2a16c + accc470 commit 507f74d

File tree

3 files changed

+59
-7
lines changed

3 files changed

+59
-7
lines changed

src/gptscript.ts

+15-6
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export interface RunOpts {
99
chdir?: string
1010
subTool?: string
1111
workspace?: string
12+
chatState?: string
1213
}
1314

1415
function toArgs(opts: RunOpts): string[] {
@@ -174,7 +175,7 @@ export class Run {
174175
private req?: any
175176
private stderr?: string
176177
private callbacks: Record<string, ((f: Frame) => void)[]> = {}
177-
private chatState: string | undefined
178+
private chatState?: string
178179

179180
constructor(subCommand: string, path: string, content: string, opts: RunOpts, bin?: string, gptscriptURL?: string) {
180181
this.id = randomId("run-")
@@ -199,13 +200,17 @@ export class Run {
199200
run = new (this.constructor as any)(this.requestPath, this.filePath, this.content, this.opts, this.bin, this.gptscriptURL)
200201
}
201202

202-
run.chatState = this.chatState
203+
if (this.chatState) {
204+
run.chatState = this.chatState
205+
} else if (this.opts.chatState) {
206+
run.chatState = this.opts.chatState
207+
}
203208
run.opts.input = input
204209
if (run.gptscriptURL) {
205210
if (run.content !== "") {
206-
run.request({content: this.content, chatState: JSON.stringify(run.chatState)})
211+
run.request({content: this.content, chatState: run.chatState})
207212
} else {
208-
run.request({file: this.filePath, chatState: JSON.stringify(run.chatState)})
213+
run.request({file: this.filePath, chatState: run.chatState})
209214
}
210215
} else {
211216
run.exec()
@@ -216,7 +221,7 @@ export class Run {
216221

217222
exec(extraArgs: string[] = [], env: NodeJS.Dict<string> = process.env) {
218223
extraArgs.push(...toArgs(this.opts))
219-
extraArgs.push("--chat-state=" + (this.chatState ? JSON.stringify(this.chatState) : "null"))
224+
extraArgs.push("--chat-state=" + (this.chatState ? this.chatState : "null"))
220225
this.chatState = undefined
221226

222227
if (this.filePath) {
@@ -353,7 +358,7 @@ export class Run {
353358

354359
const out = data as ChatState
355360
if (out.done !== undefined && !out.done) {
356-
this.chatState = out.state
361+
this.chatState = JSON.stringify(out.state)
357362
this.state = RunState.Continue
358363
} else {
359364
this.state = RunState.Finished
@@ -637,6 +642,10 @@ export class Run {
637642
return JSON.parse(await this.text())
638643
}
639644

645+
public currentChatState(): string | undefined {
646+
return this.chatState
647+
}
648+
640649
public close(): void {
641650
if (this.process) {
642651
if (this.process.exitCode === null) {

tests/fixtures/global-tools.gpt

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Runbook 3
44

55
---
66
Name: tool_1
7-
Global Tools: sys.workspace.ls, sys.workspace.read, sys.workspace.write, github.com/gptscript-ai/knowledge, github.com/drpebcak/duckdb, github.com/gptscript-ai/browser, github.com/gptscript-ai/browser-search/google, github.com/gptscript-ai/browser-search/google-question-answerer
7+
Global Tools: sys.read, sys.write, github.com/gptscript-ai/knowledge, github.com/drpebcak/duckdb, github.com/gptscript-ai/browser, github.com/gptscript-ai/browser-search/google, github.com/gptscript-ai/browser-search/google-question-answerer
88

99
Say "Hello!"
1010

tests/gptscript.test.ts

+43
Original file line numberDiff line numberDiff line change
@@ -381,4 +381,47 @@ describe("gptscript module", () => {
381381
expect(run.state).toEqual(gptscript.RunState.Finished)
382382
expect(err).toEqual("")
383383
}, 60000)
384+
385+
test("nextChat on file providing chat state", async () => {
386+
let run = client.run(path.join(__dirname, "fixtures", "chat.gpt"), {disableCache: true})
387+
388+
run = run.nextChat("List the 3 largest of the Great Lakes by volume.")
389+
expect(await run.text()).toContain("Lake Superior")
390+
expect(run.err).toEqual("")
391+
expect(run.state).toEqual(gptscript.RunState.Continue)
392+
393+
run = client.run(path.join(__dirname, "fixtures", "chat.gpt"), {
394+
disableCache: true,
395+
input: "What is the total area of the third one in square miles?",
396+
chatState: run.currentChatState()
397+
})
398+
399+
expect(await run.text()).toContain("Lake Huron")
400+
expect(run.err).toEqual("")
401+
expect(run.state).toEqual(gptscript.RunState.Continue)
402+
}, 10000)
403+
404+
test("nextChat on tool providing chat state", async () => {
405+
const t = {
406+
chat: true,
407+
instructions: "You are a chat bot. Don't finish the conversation until I say 'bye'.",
408+
tools: ["sys.chat.finish"]
409+
}
410+
let run = client.evaluate(t as any, {disableCache: true})
411+
412+
run = run.nextChat("List the three largest states in the United States by area.")
413+
expect(await run.text()).toContain("California")
414+
expect(run.err).toEqual("")
415+
expect(run.state).toEqual(gptscript.RunState.Continue)
416+
417+
run = client.evaluate(t as any, {
418+
disableCache: true,
419+
input: "What is the capital of the second one?",
420+
chatState: run.currentChatState()
421+
})
422+
423+
expect(await run.text()).toContain("Austin")
424+
expect(run.err).toEqual("")
425+
expect(run.state).toEqual(gptscript.RunState.Continue)
426+
}, 10000)
384427
})

0 commit comments

Comments
 (0)