From 3f60ba540bc5e4384b899ae6e072ed8ea3b67730 Mon Sep 17 00:00:00 2001 From: Cyber MacGeddon Date: Sun, 10 Nov 2024 10:26:34 +0000 Subject: [PATCH] Parsing and implementation complete, not tested or working --- .../trustgraph/agent/react/README.md | 4 +- .../trustgraph/agent/react/service.py | 64 +++++++----- .../trustgraph/agent/react/tools.py | 99 +++++++++++-------- .../trustgraph/agent/react/types.py | 3 + 4 files changed, 103 insertions(+), 67 deletions(-) diff --git a/trustgraph-flow/trustgraph/agent/react/README.md b/trustgraph-flow/trustgraph/agent/react/README.md index b60851d4..9965194a 100644 --- a/trustgraph-flow/trustgraph/agent/react/README.md +++ b/trustgraph-flow/trustgraph/agent/react/README.md @@ -2,8 +2,8 @@ agent-manager-react \ -p pulsar://localhost:6650 \ --tool-type \ - shuttle=knowledge-base:query \ - cats=knowledge-base:query \ + shuttle=knowledge-query:query \ + cats=knowledge-query:query \ compute=text-completion:computation \ --tool-description \ shuttle="Query a knowledge base with information about the space shuttle. The query should be a simple natural language question" \ diff --git a/trustgraph-flow/trustgraph/agent/react/service.py b/trustgraph-flow/trustgraph/agent/react/service.py index c8880571..e1bd75c6 100755 --- a/trustgraph-flow/trustgraph/agent/react/service.py +++ b/trustgraph-flow/trustgraph/agent/react/service.py @@ -22,9 +22,9 @@ from ... clients.prompt_client import PromptClient from ... clients.llm_client import LlmClient from ... clients.graph_rag_client import GraphRagClient -from . tools import CatsKb, ShuttleKb, Compute +from . tools import KnowledgeQueryImpl, TextCompletionImpl from . agent_manager import AgentManager -from . types import Final, Action +from . types import Final, Action, Tool module = ".".join(__name__.split(".")[1:-1]) @@ -49,32 +49,50 @@ class Processor(ConsumerProducer): f"Tool-type string not well-formed: {t}" ) ttoks = toks[1].split(":", 1) - if len(ttoks) == 1: - tool_base[toks[0]] = { - "type": ttoks[0], - "input-arg": "query", - "arguments": {}, - } - else: - tool_base[toks[0]] = { - "type": ttoks[0], - "input-arg": ttoks[1], - "arguments": {}, - } + if len(ttoks) < 1: + raise RuntimeError( + f"Tool-type string not well-formed: {t}" + ) - # Parsing the prompt information to the prompt configuration + if ttoks[0] == "knowledge-query": + impl = KnowledgeQueryImpl + elif ttoks[0] == "text-completion": + impl = TextCompletionImpl + else: + raise RuntimeError( + f"Tool-kind {ttoks[0]} not known" + ) + + if len(ttoks) == 1: + tool_base[toks[0]] = Tool( + name = ttoks[0], + description = "", + implementation = impl, + config = { "input": "query" }, + arguments = {}, + ) + else: + tool_base[toks[0]] = Tool( + name = ttoks[0], + description = "", + implementation = impl, + config = { "input": ttoks[1] }, + arguments = {}, + ) + + # parsing the prompt information to the prompt configuration # structure tool_desc_arg = params.get("tool_description", []) if tool_desc_arg: for t in tool_desc_arg: toks = t.split("=", 1) if len(toks) < 2: - raise RuntimeError( - f"Tool-type string not well-formed: {t}" + raise runtimeerror( + f"tool-type string not well-formed: {t}" ) if toks[0] not in tool_base: - raise RuntimeError(f"Description, tool {toks[0]} not known") - tool_base[toks[0]]["description"] = toks[1] + raise runtimeerror(f"description, tool {toks[0]} not known") + tool_base[toks[0]].description = toks[1] # Parsing the prompt information to the prompt configuration # structure @@ -93,13 +111,13 @@ class Processor(ConsumerProducer): ) if toks[0] not in tool_base: raise RuntimeError(f"Description, tool {toks[0]} not known") - tool_base[toks[0]]["arguments"][ttoks[0]] = { + tool_base[toks[0]].arguments[ttoks[0]] = { "name": ttoks[0], "type": ttoks[1], "description": ttoks[2], } - print(json.dumps(tool_base, indent=4)) + print(json.dumps({k: str(v) for k, v in tool_base.items()}, indent=4)) sys.exit(0) @@ -169,7 +187,7 @@ class Processor(ConsumerProducer): ) tools = [ - CatsKb(self), ShuttleKb(self), Compute(self), +# CatsKb(self), ShuttleKb(self), Compute(self), ] self.agent = AgentManager(self, tools) @@ -347,7 +365,7 @@ class Processor(ConsumerProducer): '--tool-type', nargs='*', help=f'''Specifies the type of an agent tool. Takes the form =. is the name of the tool. is one of -knowledge-base, text-completion. Additional parameters are specified +knowledge-query, text-completion. Additional parameters are specified for different tools which are tool-specific. e.g. knowledge-query: which specifies the name of the arg whose content is fed into the knowledge query as a question. text-completion: specifies the name of the arg diff --git a/trustgraph-flow/trustgraph/agent/react/tools.py b/trustgraph-flow/trustgraph/agent/react/tools.py index 918279db..7154fa79 100644 --- a/trustgraph-flow/trustgraph/agent/react/tools.py +++ b/trustgraph-flow/trustgraph/agent/react/tools.py @@ -1,52 +1,67 @@ -from . types import Tool, Argument +# from . types import Tool -class CatsKb: - tool = Tool( - name = "cats-kb", - description = "Query a knowledge base with information about Mark's cats. The query should be a simple natural language question", - arguments = [ - Argument( - name = "query", - type = "string", - description = "The search query string" - ) - ] - ) +# class CatsKb: +# tool = Tool( +# name = "cats-kb", +# description = "Query a knowledge base with information about Mark's cats. The query should be a simple natural language question", +# arguments = [ +# Argument( +# name = "query", +# type = "string", +# description = "The search query string" +# ) +# ] +# ) +# def __init__(self, context): +# self.context = context +# def invoke(self, **arguments): +# return self.context.graph_rag.request(arguments.get("query")) + +# class ShuttleKb: +# tool = Tool( +# name = "shuttle-kb", +# description = "Query a knowledge base with information about the space shuttle. The query should be a simple natural language question", +# arguments = [ +# Argument( +# name = "query", +# type = "string", +# description = "The search query string" +# ) +# ] +# ) +# def __init__(self, context): +# self.context = context +# def invoke(self, **arguments): +# return self.context.graph_rag.request(arguments.get("query")) + +# class Compute: +# tool = Tool( +# name = "compute", +# description = "A computation engine which can answer questions about maths and computation", +# arguments = [ +# Argument( +# name = "computation", +# type = "string", +# description = "The computation to solve" +# ) +# ] +# ) +# def __init__(self, context): +# self.context = context +# def invoke(self, **arguments): +# return self.context.prompt.request( +# "question", { "question": arguments.get("computation") } +# ) + + +class KnowledgeQueryImpl: def __init__(self, context): self.context = context def invoke(self, **arguments): return self.context.graph_rag.request(arguments.get("query")) -class ShuttleKb: - tool = Tool( - name = "shuttle-kb", - description = "Query a knowledge base with information about the space shuttle. The query should be a simple natural language question", - arguments = [ - Argument( - name = "query", - type = "string", - description = "The search query string" - ) - ] - ) - def __init__(self, context): - self.context = context - def invoke(self, **arguments): - return self.context.graph_rag.request(arguments.get("query")) - -class Compute: - tool = Tool( - name = "compute", - description = "A computation engine which can answer questions about maths and computation", - arguments = [ - Argument( - name = "computation", - type = "string", - description = "The computation to solve" - ) - ] - ) +class TextCompletionImpl: def __init__(self, context): self.context = context def invoke(self, **arguments): diff --git a/trustgraph-flow/trustgraph/agent/react/types.py b/trustgraph-flow/trustgraph/agent/react/types.py index efc2ef6c..7180db3e 100644 --- a/trustgraph-flow/trustgraph/agent/react/types.py +++ b/trustgraph-flow/trustgraph/agent/react/types.py @@ -1,5 +1,6 @@ import dataclasses +from typing import Any, Dict @dataclasses.dataclass class Argument: @@ -12,6 +13,8 @@ class Tool: name : str description : str arguments : list[Argument] + implementation : Any + config : Dict[str, str] @dataclasses.dataclass class Action: