griptape-ai / griptape Goto Github PK
View Code? Open in Web Editor NEWModular Python framework for AI agents and workflows with chain-of-thought reasoning, tools, and memory.
Home Page: https://www.griptape.ai
License: Apache License 2.0
Modular Python framework for AI agents and workflows with chain-of-thought reasoning, tools, and memory.
Home Page: https://www.griptape.ai
License: Apache License 2.0
Tool activities that have pass_artifact
set to True should be validated during instantiation with an attrs validator and throw a ValueError
if the tool doesn't have any ramps.
attempt to use [insert]
from griptape.memory import Memory
from griptape.structures import Agent
from griptape.drivers import OpenAiPromptDriver
agent = Agent(
memory=Memory(),
prompt_driver=OpenAiPromptDriver(
model="text-davinci-003"
)
)
agent.run("hello friend, today we are going to do the following: [insert]")
returns a 'NoneType' object has no attribute 'to_text'
Describe the solution you'd like
tokenizer for https://github.com/google/sentencepiece/blob/master/python/README.md
This would be used for Google Vertex AI Prompt driver
Is your feature request related to a problem? Please describe.
I was wondering what the plans are for supporting OpenAI function calling since that might help with LLM reliability and tool development.
Describe the solution you'd like
I would like to have griptape
support OpenAI function calling internally and maintain the same semantics.
Describe alternatives you've considered
N/A
Additional context
I am evaluating griptape
for my projects and have found that the function calling functionality makes for more reliable interactions with the 0613 series of models.
Prompt drivers currently miss unit tests. We need to use Python mocks to mock out the underlying driver API libraries and write unit tests for all prompt drivers.
Customers need a way to allow LLMs to access their Snowflake tables.
I propose building the SnowflakeSqlDriver
based on Snowflake Connector.
We're standing up a local hf text gen service ( it's pretty good )
https://github.com/huggingface/text-generation-inference
Griptape already has HuggingFaceHubPromptDriver, HuggingFacePipelinePromptDriver, could you add one that can interface with locally hosted huggingface text-generation-inference?
Here's the alternative
https://python.langchain.com/docs/modules/model_io/models/llms/integrations/huggingface_textgen_inference
Thank you for developing griptape! It looks like it's gonna be awesome!
Describe the bug
Custom rules don't appear to have an impact on Agents or Pipeline tasks.
To Reproduce
from griptape.structures import Agent
from griptape.rules import Rule
agent = Agent(
rulesets = [
Rule("Always reply backwards")
]
)
agent.run("Say hello")
Expected behavior
Output: ayot uoy tsissa I nac woH !olleH
Actual behavior
Output: Hello! How can I assist you today?
Additional context
I may be using rules incorrectly - is this the expected way to use them?
Is your feature request related to a problem? Please describe.
I see a lot of back and forth when I run some of the examples, like where we're saving texts and blobs to, etc.
So I wanted to compare token usage for similar tasks from Langchain and Griptape.
Describe the solution you'd like
A way to count the number of tokens spent to fulfill a request.
For example, let's say you have an agent that is doing multiple things, similar to the RestApiClient Example. I'd like to know how many tokens we use to fulfill this request to compare to other frameworks.
Describe alternatives you've considered
I tried using Langchain's counter but it only works with Langchain LLMs. I also searched to see if the OpenAI package has this functionality already but it doesn't seem so.
Additional context
N/A
Executors, such as LocalExecutor
and DockerExecutor
, always install tool dependencies on every run. It's wasteful and is often undesirable in production environments.
I propose adding an install_dependencies_on_execute
flag to the BaseExecutor
set to True
by default that controls whether dependencies are installed on every run.
Separately, I propose adding an abstract method install_dependencies()
to the BaseExecutor
and consolidating LocalExecutor().install_dependencies()
and DockerExecutor().build_image()
.
Describe the bug
I've created a custom tool for LLM to call, and when it comes to a calling a method, it doesn't execute the actual subtask (and just exits).
It looks like the returned Action param has the json md template mark and fails to create the sub-task. See below
Raw output
Task 29114d55776f4aa4891eaf08c32dd63f
Input: For the calendar <gcal>@group.calendar.google.com and
event
NjUyMGx0NzA0bDgwNDg3aWJscjkxdjFzcHQgZTNkZjI1Y2RkNmI1YmVjNGYxMzc3NmYzNzE2ODk1Nzg4ZmFhNTk1Mzg4NThlZDA3Nzk3YmFiN2M1MjY1OT
RjNkBn, how many guests have we sent invitations out to?
[07/05/23 13:54:05] INFO Task 29114d55776f4aa4891eaf08c32dd63f
Output: Thought: To find out how many guests we have sent invitations out to for a specific event, I can use the
"get_event_details" activity of the GoogleCalendarManager tool.
Action:
```json
{"type": "tool", "name": "GoogleCalendarManager", "activity": "get_event_details", "input": {"values": {"calendar_id":
"e3df25cdd6b5bec4f13776f3716895788faa59538858ed07797bab7c526594c6@group.calendar.google.com", "event_id":
"NjUyMGx0NzA0bDgwNDg3aWJscjkxdjFzcHQgZTNkZjI1Y2RkNmI1YmVjNGYxMzc3NmYzNzE2ODk1Nzg4ZmFhNTk1Mzg4NThlZDA3Nzk3YmFiN2M1MjY1O
TRjNkBn"}}}
```
It would be useful not to have to load memory by hand after object initialization. I propose adding memory auto-loading logic in BaseMemoryDriver().__attrs_post_init__()
.
Activity decorators don't need to have an explicit name property.
When a decorator is applied to a method, we can dynamically generate a name and set it as name
similar to how we set config
. This way, the method name itself can be used as an activity name:
wrapper.name = func.__name__
Hey again,
thanx for fixing the docs. It works very well. I stumbled into another issue when running the code for Agent:
(base) ➜ griptape: python agent.py
[05/09/23 19:37:28] INFO Task 763acc754437403f9e17b36dc73e17f2
Input: Give me a summary of https://en.wikipedia.org/wiki/Large_language_model
ERROR:root:PromptDriver.run attempt 0 failed: The model: `gpt-4` does not exist
Retrying in 1 seconds
[...]
File "/Users/++++/miniconda/lib/python3.10/site-packages/openai/api_requestor.py", line 687, in _interpret_response_line
raise self.handle_error_response(
openai.error.InvalidRequestError: The model: `gpt-4` does not exist
I would love to check this out by myself and find the error but unfortunately, I am new to this kinda stuff ;-)
Thanks for any hint.
Best
Andy
It looks to be creating a default prompt driver that doesn't allow for configuration:
As structures execute tasks, users want to see task outputs as stream events.
I propose adding Python iterator support to structures and implementing __iter__
and __next__
methods. This way users can execute structures like this:
for event in Agent().run():
print(event.value)
BasePromptDriver
should use the same retry logic used in BaseEmbeddingDriver
.
We want to enable developers who want to deploy tools in the cloud serverlessly by introducing AwsLambdaExecutor
—one of the first serverless platform integrations.
BaseVectorStorageDriver
should support regular inserts in addition to upserts for TextArtifact
s
from griptape.memory import Memory
from griptape.structures import Agent
agent = Agent(
memory=Memory()
)
agent.run("my name is kyle")
agent.run("write a haiku about me in new york city")
using 3.5 it'll imagine a generate_haiku ramp. 4 does fine and keeps memory context and generates the haiku.
[05/13/23 11:19:13] INFO Task 2217534452044c48ab2bd42e275611d7
Input: my name is kyle
[05/13/23 11:19:14] INFO Task 2217534452044c48ab2bd42e275611d7
Output: Hello Kyle. How can I assist you today?
INFO Task 2217534452044c48ab2bd42e275611d7
Input: write a haiku about me in new york city
[05/13/23 11:19:19] INFO Task 2217534452044c48ab2bd42e275611d7
Output: Thought: I can generate a haiku about New
York City and mention Kyle in it.
Action: {"type": "ramp", "name": "generate_haiku",
"activity": "mention_Kyle_in_NYC_haiku"}
This works as expected w/ GPT-4. With 3.5 you get the following (no action + hallucination of a tool)
from griptape.memory import Memory
from griptape.rules import Rule
from griptape.rules.ruleset import Ruleset
from griptape.structures import Agent
ruleset = Ruleset(
name="pirate",
rules=[
Rule("act like a pirate")
]
)
agent = Agent(
# prompt_driver=OpenAiPromptDriver(
# model="gpt-4"
# ),
rulesets=[ruleset],
memory=Memory()
)
agent.run("my name is kyle")
agent.run("what's my name?")
Returns the following output:
[05/13/23 11:30:39] INFO Task a6705ea538e240648e69a084493b45d3
Input: my name is kyle
[05/13/23 11:30:41] INFO Task a6705ea538e240648e69a084493b45d3
Output: Thought: I don't need to perform any
actions for this request.
Output: Nice to meet you, Kyle.
INFO Task a6705ea538e240648e69a084493b45d3
Input: what's my name?
[05/13/23 11:30:44] INFO Task a6705ea538e240648e69a084493b45d3
Output: Thought: I can retrieve the user's name
from previous input.
Action: {"type": "tool", "name": "retrieveName",
"activity": "get"}
I am using a MacOS M1 (12.6.6).
I have installed these modules with pip:
griptape 0.12.0
griptape-tools 0.14.0
I am trying to run the AWSCli example at this page reported below for convenience and history:
from griptape.tools import AwsCli
from griptape.memory.structure import ConversationMemory
from griptape.tasks import ToolkitTask
from griptape.structures import Pipeline
aws_cli = AwsCli(
aws_access_key_id=os.environ.get("AWS_ACCESS_KEY_ID"),
aws_secret_access_key=os.environ.get("AWS_SECRET_ACCESS_KEY"),
aws_cli_policy="""{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"*","Resource":"*"}]}"""
)
pipeline = Pipeline(
memory=ConversationMemory()
)
pipeline.add_tasks(
ToolkitTask(
tools=[aws_cli]
)
)
result = pipeline.run("what S3 buckets do I have?")
print(result.output.value)
I found a couple of problems (one blocking, one not).
The program appears to be missing the import os
statement. Easy fix.
However, it still spits the following error message:
$ python app.py
[06/30/23 09:52:56] INFO Task 04d58708c0a5418b80b8f9231fbf004a
Input: what S3 buckets do I have?
[06/30/23 09:53:00] INFO Subtask fc7a518b91fb4f2d9aa82b80111b94df
Thought: To find out what S3 buckets the user has, I can use the AwsCli tool and execute the "aws s3 ls" command.
Action:
{"type": "tool", "name": "AwsCli", "activity": "execute", "input": {"values": {"command": "aws s3 ls"}}}
ERROR Subtask fc7a518b91fb4f2d9aa82b80111b94df
execute() takes 2 positional arguments but 3 were given
Traceback (most recent call last):
File "/home/ec2-user/.local/lib/python3.9/site-packages/griptape/tasks/action_subtask.py", line 91, in run
observation = self._tool.execute(getattr(self._tool, self.action_activity), self)
File "/home/ec2-user/.local/lib/python3.9/site-packages/griptape/core/decorators.py", line 25, in wrapper
return func(self, *args, **kwargs)
TypeError: execute() takes 2 positional arguments but 3 were given
INFO Subtask fc7a518b91fb4f2d9aa82b80111b94df
Observation: execute() takes 2 positional arguments but 3 were given
[06/30/23 09:53:06] INFO Subtask 06772aec86074a029d34ea6ccbcbe6b6
Thought: It seems that there is an error in the input schema for the execute activity of the AwsCli tool. I will need to fix this error before proceeding.
.....
.....
.....
.....
Observation: execute() takes 2 positional arguments but 3 were given
[06/30/23 09:54:13] INFO Subtask 7c7b53ad8cb2450c82e417cb97a144b3
Thought: The error message suggests that the execute() function of the AwsCli tool is expecting 2 positional arguments instead of 3. I will need to modify the input to fix this error.
Action: {"type": "tool", "name": "AwsCli", "activity": "execute", "input": {"values": {"command": "aws s3 ls"}}}
ERROR Subtask 7c7b53ad8cb2450c82e417cb97a144b3
execute() takes 2 positional arguments but 3 were given
Traceback (most recent call last):
File "/home/ec2-user/.local/lib/python3.9/site-packages/griptape/tasks/action_subtask.py", line 91, in run
observation = self._tool.execute(getattr(self._tool, self.action_activity), self)
File "/home/ec2-user/.local/lib/python3.9/site-packages/griptape/core/decorators.py", line 25, in wrapper
return func(self, *args, **kwargs)
TypeError: execute() takes 2 positional arguments but 3 were given
INFO Subtask 7c7b53ad8cb2450c82e417cb97a144b3
Observation: execute() takes 2 positional arguments but 3 were given
[06/30/23 09:54:15] INFO Task 04d58708c0a5418b80b8f9231fbf004a
Output: I apologize, but I am unable to execute the "aws s3 ls" command using the AwsCli tool at the moment. Please try again later.
I apologize, but I am unable to execute the "aws s3 ls" command using the AwsCli tool at the moment. Please try again later.
$
I haven't modified anything in the script (beyond adding the import os
statement).
We need a Griptape-native way to work with text embeddings and vector databases in order to support the following requested functionality:
Here is a general outline of proposed embeddings components and improvements
BaseEmbeddingDriver
and OpenAiEmbeddingDriver
.TextDocument
to store and lazily generate embeddings.BaseVectorStorageDriver
abstraction to provide a generic way to load and store embeddings.PineconeVectorStorageDriver
to be the first vector driver in order to support the most popular vector DB.There are some scenarios where it's useful to capture not just structure run inputs and outputs but also intermediate task and substask run inputs and outputs.
To store tasks and subtasks in memory, we'll need to add Marshmallow models for serialization and deserialization and integrate them with memory.
using default example prompt from cohere generate api docs, getting empty output
agent = Agent(
prompt_driver=CoherePromptDriver(
api_key="key here"
),
#rulesets=[ruleset],
memory=Memory()
)
result = agent.run("one upon a time in a land called")
print(result.output.to_text())
In order to start experimenting with PaLM models, we need to implement a new driver for Google Cloud GooglePromptDriver
that can execute models on Google AI platform. We should be able to use their official Python SDK to accomplish this goal.
Griptape needs a generic way to run queries against large bodies of text in TextArtifact
s (e.g., for search). We currently rely on LlamaIndex for that functionality in tools but there is a number of downsides when it comes to using it.
I propose building a standalone component that uses PromptDriver
s to load text of arbitrary length and run queries against it. After completing this feature, we can modify TextProcessor
to support it.
Workflows should support memory after #40 is complete. We can then merge Structure
and StructureWithMemory
into one class.
Core Actions
Developers want to define task-specific RuleSet
s that are injected into the base prompt in addition to structure-level RuleSet
s.
Is your feature request related to a problem? Please describe.
I'm really enjoying the Chat utility and was wondering if it would be possible to add a flag to control the input and exit text to make it more personable?
Describe the solution you'd like
Possibly define it as part of the ruleset?
pirate_agent = Agent(
rulesets = [
Ruleset(
name = "Pirate",
rules = [
Rule('You are a pirate'),
Rule('You are worried about people stealing your gold)
],
chat_prompt = "Arr?",
chat_exit = "Arr!"
)
]
)
You might want to define other things about the chat utility as well.. things like:
Introduction Text: "Arr - I be a pirate. Please chat with me!"
or ways to exit:
"bye", "see ya", "I'm walking the plank now!"
Before adding memory to workflows, we should add support for multiple memory run inputs and outputs, since DAGs can have multiple initial tasks and multiple finish tasks.
Griptape should be able to support custom prompt template that the user can define. Additionally, we should provide a way for prompt drivers to provide their own default base templates.
Activities schemas have to always be JSON. Validation should happen in the activity decorator.
BaseTool
should have a dependencies
property that can be used to add custom dependencies to tools. This is useful for tools like SqlClient
.
Sometimes it makes sense to only add a small set of rules to a structure instead of multiple rulesets.
For that purpose we propose adding an optional rules: list[Rule]
field to Structure
s. It should only be possible to use one or the other.
We need a streamlined way to load data from different sources.
I propose a new abstraction called Loaders. Initially, we should support the following two loaders:
TextLoader
to load text and optionally chunk it and generate embeddings.PdfLoader
to load PDF files.WebLoader
to load web pages.Describe the bug
If you create two Agent objects in the same script and add different rulesets the first agent doesn't seem to work
To Reproduce
from griptape.structures import Agent
from griptape.rules import Rule
from griptape.rules.ruleset import Ruleset
pirate_ruleset = Ruleset(
name='pirate',
rules = [Rule('act like a pirate')]
)
teacher_ruleset = Ruleset(
name='teacher',
rules = [Rule('you are a teacher')]
)
agent1 = Agent(
rulesets=[pirate_ruleset]
)
agent2 = Agent(
rulesets=[teacher_ruleset]
)
agent1.run("Say hello")
agent2.run("Say hello")
You can comment out the 2nd run and the first agent still has an empty prompt.
You can comment out the 2nd instantiation and run and it works fine.
Tests in TestOpenAiEmbeddingDriver
run correctly locally but hang on GitHub.
Current hypothesis is that pinecone.Index
in PineconeVectorStorageDriver
either makes requests that hang forever or mismanages thread pools.
Our current fix is to move those tests outside of unit
into integration
, which don't yet run on GitHub.
Customers need a way to allow LLMs to access their Redshift tables with IAM credentials.
I propose building the AwsRedshiftSqlDriver
based on RedshiftDataAPIService.
WebScraper
should use WebLoader
To support users that want to use embeddings and vector DBs, we need to add classes for splitting text into chunks.
BaseChunker
should have the following configuration options:
Initial implementation should have the following chunkers:
Hi there,
thanks for creating this. I played around with the examples from https://griptape.readthedocs.io/en/latest/griptape-framework and stumbled over this error in all examples, where OpenAiPromptDriver
is used
TypeError: WebScraper.__init__() got an unexpected keyword argument 'openai_api_key'
I tried also api_key
because it is mentioned here https://griptape.readthedocs.io/en/latest/griptape-framework/prompt-drivers/openai/
but had no luck.
OPENAI_API_KEY
is set.
Thanks for your help.
Best
Andy
Tool converters were removed from Griptape in 4f86608 since they are an experimental feature.
We need to move converters to griptape-labs under labs.converters
.
Developers want to generate embeddings locally, so we need to build a driver for that.
Before starting on the issue, let's figure out what approach we should use (e.g., gensim).
Describe the bug
I'm trying to follow the example here: https://docs.griptape.ai/en/latest/griptape-framework/#build-a-simple-pipeline and the example fails when trying to run it. It's throwing a value error ValueError: activity query doesn't exist
. This is on windows 10, using python 3.10.8 and I also tried with python 3.11.3
To Reproduce
Steps to reproduce the behavior:
Expected behavior
I expected the program to run without errors.
Screenshots
If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
Some LLMs require a specific structure or "anchors" when it comes to processing input. The best way to customize it in Griptape is in PromptDriver
s.
Any time Griptape is run, the following warning from the transformers library is displayed:
None of PyTorch, TensorFlow >= 2.0, or Flax have been found. Models won't be available and only tokenizers, configuration and file/data utilities can be used.
We need to get rid of it either by disabling it at the library level of importing transformers lazily in tokenizers and prompt drivers.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.