Skip to content
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

feat: add load methods #49

Merged
merged 1 commit into from
Aug 30, 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
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ from gptscript.gptscript import GPTScript

async def parse_tool_example():
gptscript = GPTScript()
tools = await gptscript.parse_tool("Instructions: Say hello!")
tools = await gptscript.parse_content("Instructions: Say hello!")
print(tools)
gptscript.close()
```
Expand All @@ -155,7 +155,7 @@ from gptscript.gptscript import GPTScript

async def fmt_example():
gptscript = GPTScript()
tools = await gptscript.parse_tool("Instructions: Say hello!")
tools = await gptscript.parse_content("Instructions: Say hello!")
print(tools)

contents = gptscript.fmt(tools)
Expand Down
2 changes: 1 addition & 1 deletion gptscript/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from gptscript.gptscript import GPTScript
from gptscript.confirm import AuthResponse
from gptscript.frame import RunFrame, CallFrame, PromptFrame
from gptscript.frame import RunFrame, CallFrame, PromptFrame, Program
from gptscript.opts import GlobalOptions
from gptscript.prompt import PromptResponse
from gptscript.run import Run, RunBasicCommand, Options
Expand Down
9 changes: 6 additions & 3 deletions gptscript/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,12 @@ def __init__(self,
self.name = name
self.entryToolId = entryToolId
self.toolSet = toolSet
for tool in toolSet:
if isinstance(self.toolSet[tool], dict):
self.toolSet[tool] = Tool(**self.toolSet[tool])
if self.toolSet is None:
self.toolSet = {}
else:
for tool in toolSet:
if isinstance(self.toolSet[tool], dict):
self.toolSet[tool] = Tool(**self.toolSet[tool])


class RunFrame:
Expand Down
34 changes: 29 additions & 5 deletions gptscript/gptscript.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import requests

from gptscript.confirm import AuthResponse
from gptscript.frame import RunFrame, CallFrame, PromptFrame
from gptscript.frame import RunFrame, CallFrame, PromptFrame, Program
from gptscript.opts import GlobalOptions
from gptscript.prompt import PromptResponse
from gptscript.run import Run, RunBasicCommand, Options
Expand Down Expand Up @@ -90,7 +90,7 @@ def evaluate(
opts.merge_global_opts(self.opts),
self._server_url,
event_handlers=event_handlers,
).next_chat("" if opts is None else opts.input)
).next_chat(opts.input)

def run(
self, tool_path: str,
Expand All @@ -104,7 +104,31 @@ def run(
opts.merge_global_opts(self.opts),
self._server_url,
event_handlers=event_handlers,
).next_chat("" if opts is None else opts.input)
).next_chat(opts.input)

async def load_file(self, file_path: str, disable_cache: bool = False, sub_tool: str = '') -> Program:
out = await self._run_basic_command(
"load",
{"file": file_path, "disableCache": disable_cache, "subTool": sub_tool},
)
parsed_nodes = json.loads(out)
return Program(**parsed_nodes.get("program", {}))

async def load_content(self, content: str, disable_cache: bool = False, sub_tool: str = '') -> Program:
out = await self._run_basic_command(
"load",
{"content": content, "disableCache": disable_cache, "subTool": sub_tool},
)
parsed_nodes = json.loads(out)
return Program(**parsed_nodes.get("program", {}))

async def load_tools(self, tool_defs: list[ToolDef], disable_cache: bool = False, sub_tool: str = '') -> Program:
out = await self._run_basic_command(
"load",
{"toolDefs": [t.to_json() for t in tool_defs], "disableCache": disable_cache, "subTool": sub_tool},
)
parsed_nodes = json.loads(out)
return Program(**parsed_nodes.get("program", {}))

async def parse(self, file_path: str, disable_cache: bool = False) -> list[Text | Tool]:
out = await self._run_basic_command("parse", {"file": file_path, "disableCache": disable_cache})
Expand All @@ -114,8 +138,8 @@ async def parse(self, file_path: str, disable_cache: bool = False) -> list[Text
return [Text(**node["textNode"]) if "textNode" in node else Tool(**node.get("toolNode", {}).get("tool", {})) for
node in parsed_nodes.get("nodes", [])]

async def parse_tool(self, tool_def: str) -> list[Text | Tool]:
out = await self._run_basic_command("parse", {"content": tool_def})
async def parse_content(self, content: str) -> list[Text | Tool]:
out = await self._run_basic_command("parse", {"content": content})
parsed_nodes = json.loads(out)
if parsed_nodes is None or parsed_nodes.get("nodes", None) is None:
return []
Expand Down
45 changes: 38 additions & 7 deletions tests/test_gptscript.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,8 @@ def simple_tool():
@pytest.fixture
def complex_tool():
return ToolDef(
tools=["sys.write"],
jsonResponse=True,
instructions="""
Create three short graphic artist descriptions and their muses.
instructions="""Create three short graphic artist descriptions and their muses.
These should be descriptive and explain their point of view.
Also come up with a made up name, they each should be from different
backgrounds and approach art differently.
Expand Down Expand Up @@ -272,10 +270,43 @@ async def test_eval_with_context(gptscript):
)

run = gptscript.evaluate(tool)

assert "Acorn Labs" == await run.text(), "Unexpected output from eval using context"


@pytest.mark.asyncio
async def test_load_simple_file(gptscript):
wd = os.getcwd()
prg = await gptscript.load_file(wd + "/tests/fixtures/test.gpt")
assert prg.toolSet[prg.entryToolId].instructions == "Who was the president of the United States in 1986?", \
"Unexpected output from parsing simple file"


@pytest.mark.asyncio
async def test_load_remote_tool(gptscript):
prg = await gptscript.load_file("github.com/gptscript-ai/context/workspace")
assert prg.entryToolId != "", "Unexpected entry tool id from remote tool"
assert len(prg.toolSet) > 0, "Unexpected number of tools in remote tool"
assert prg.name != "", "Unexpected name from remote tool"


@pytest.mark.asyncio
async def test_load_simple_content(gptscript):
wd = os.getcwd()
with open(wd + "/tests/fixtures/test.gpt") as f:
prg = await gptscript.load_content(f.read())
assert prg.toolSet[prg.entryToolId].instructions == "Who was the president of the United States in 1986?", \
"Unexpected output from parsing simple file"


@pytest.mark.asyncio
async def test_load_tools(gptscript, tool_list):
prg = await gptscript.load_tools(tool_list)
assert prg.entryToolId != "", "Unexpected entry tool id from remote tool"
assert len(prg.toolSet) > 0, "Unexpected number of tools in remote tool"
# Name will be empty in this case.
assert prg.name == "", "Unexpected name from remote tool"


@pytest.mark.asyncio
async def test_parse_simple_file(gptscript):
wd = os.getcwd()
Expand All @@ -295,7 +326,7 @@ async def test_parse_empty_file(gptscript):

@pytest.mark.asyncio
async def test_parse_empty_str(gptscript):
tools = await gptscript.parse_tool("")
tools = await gptscript.parse_content("")
assert len(tools) == 0, "Unexpected number of tools for parsing empty string"


Expand All @@ -313,15 +344,15 @@ async def test_parse_tool_with_metadata(gptscript):

@pytest.mark.asyncio
async def test_parse_tool(gptscript):
tools = await gptscript.parse_tool("echo hello")
tools = await gptscript.parse_content("echo hello")
assert len(tools) == 1, "Unexpected number of tools for parsing tool"
assert isinstance(tools[0], Tool), "Unexpected node type from parsing tool"
assert tools[0].instructions == "echo hello", "Unexpected output from parsing tool"


@pytest.mark.asyncio
async def test_parse_tool_with_text_node(gptscript):
tools = await gptscript.parse_tool("echo hello\n---\n!markdown\nhello")
tools = await gptscript.parse_content("echo hello\n---\n!markdown\nhello")
assert len(tools) == 2, "Unexpected number of tools for parsing tool with text node"
assert isinstance(tools[0], Tool), "Unexpected node type for first tool from parsing tool with text node"
assert isinstance(tools[1], Text), "Unexpected node type for second tool from parsing tool with text node"
Expand Down