Skip to content

Commit

Permalink
Merge branch 'dev' into f/tasks-error-handling
Browse files Browse the repository at this point in the history
  • Loading branch information
HamadaSalhab committed Oct 8, 2024
2 parents 95f52ab + 966f7d8 commit 0e89dc9
Show file tree
Hide file tree
Showing 50 changed files with 1,106 additions and 296 deletions.
337 changes: 247 additions & 90 deletions README.md

Large diffs are not rendered by default.

137 changes: 137 additions & 0 deletions SCRATCHPAD.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
Sure! So imagine you want to build an AI agent that can do more than just answer simple queries—it needs to handle complex tasks, remember past interactions, and maybe even integrate with other tools or APIs. That's where Julep comes in. It's an open-source platform that lets you create persistent AI agents with customizable workflows, making it super easy to develop and deploy advanced AI applications without reinventing the wheel.



Julep is really useful when you want to build AI agents that can maintain context and state over long-term interactions. It's great for designing complex, multi-step workflows and integrating various tools and APIs directly into your agent's processes.

Compared to LangChain, which is excellent for chaining together prompts and managing LLM interactions, Julep focuses more on creating persistent agents with customizable workflows. While LangChain provides a robust framework for building applications with language models, it doesn't inherently offer the same level of session management or state persistence that Julep does.





Persistent sessions in Julep mean that the AI agents can maintain context and state over long periods and multiple interactions. So instead of just handling a single query and forgetting everything afterward (which is what you'd get with regular sessions), the agent can remember past conversations, user preferences, and any relevant data from previous interactions. This is super handy when you want your agent to provide a more personalized experience or when the tasks require building upon previous steps.

For example, if you're building a customer support agent, it can recall a user's issue from earlier chats without them having to repeat themselves. Regular sessions typically don't offer this level of continuity.

As for complex workflows, Julep lets you define multi-step tasks that can include conditional logic, loops, parallel processing, and integration with external tools or APIs. Regular workflows might be more linear and straightforward—think a simple sequence of prompts or API calls without much branching or decision-making capability.

In Julep, you can create tasks where the agent might, say, take user input, perform a web search, process the results, maybe even interact with other services like sending an email or updating a database—all within a single workflow. This level of complexity allows you to build more sophisticated applications without having to manage the orchestration logic yourself.

That said, one thing to keep in mind is that while Julep offers these advanced features, it's still relatively new compared to something like LangChain. So you might find that the community support and pre-built integrations aren't as extensive yet. If you need something up and running quickly with lots of existing modules, LangChain might be more convenient. But if you want more control over persistent state and complex task execution, Julep provides a solid framework for that.






LangChain is great for creating sequences of prompts and managing interactions with LLMs. It has a large ecosystem with lots of pre-built integrations, which makes it convenient if you want to get something up and running quickly.

Julep, on the other hand, is more about building persistent AI agents that can maintain context over long-term interactions. It shines when you need complex workflows that involve multi-step tasks, conditional logic, and integration with various tools or APIs directly within the agent's process.

So, you shouldn't think of Julep as a direct replacement for LangChain. Instead, consider it as an alternative that's better suited for projects where maintaining state over time and handling complex task executions are important. If your application requires agents that can remember past interactions, personalize responses, and perform intricate operations, Julep might be the way to go.




Think of LangChain and Julep as tools with different focuses within the AI development stack.

LangChain is like a powerful library that helps you chain together prompts and manage interactions with language models. It's excellent for building applications where the primary interaction is between the user and the LLM in a sequential manner. You get utilities for prompt management, memory, and even some basic tools integration. But when it comes to handling more complex state management or long-term sessions, you might find yourself writing a lot of custom code.

Julep, on the other hand, is more of an orchestration platform for AI agents. It's designed from the ground up to manage persistent sessions and complex workflows. Here's how you might think about it:

Persistent State and Sessions: Julep allows your AI agents to maintain state over time without you having to implement the storage and retrieval mechanisms yourself. So if your application requires the agent to remember previous interactions, user preferences, or intermediate data across sessions, Julep handles that natively.

Complex Workflow Management: With Julep, you can define multi-step tasks that include conditional logic, loops, parallel processing, and more. It's like having a built-in workflow engine tailored for AI agents. This is particularly useful when your agent needs to perform a series of actions that depend on each other or on external inputs.

Tool and API Integration: While LangChain allows for some tools integration, Julep provides a more seamless way to incorporate external tools and APIs directly into your agent's workflows. You can define tools once and reuse them across different tasks and agents.

Agent-Centric Design: Julep is centered around the concept of agents that have their own identities, abilities, and long-term goals. This abstraction is helpful when you're building applications where the agent needs to interact with users or systems in a more autonomous or stateful way.

So, rather than a drop-in replacement, Julep can be thought of as a higher-level framework that sits on top of or alongside tools like LangChain. If you imagine building a complex AI assistant that needs to:

Keep track of user interactions over days or weeks.
Perform scheduled tasks, like sending daily summaries or monitoring data sources.
Make decisions based on prior interactions or stored data.
Interact with multiple external services as part of its workflow.
Then Julep provides the infrastructure to support all that without you having to build it from scratch.

In contrast, if you're building a simpler application where you just need to chain a few prompts together and don't require persistent state or complex task management, LangChain might be sufficient and quicker to implement.

In summary:

Use LangChain when you need to manage LLM interactions and prompt sequences in a stateless or short-term context.
Choose Julep when you need a robust framework for stateful agents with advanced workflow capabilities, persistent sessions, and complex task orchestration.




Sure! To help you "bookmark" Julep in your mind, here are some key phrases and keywords that set it apart and highlight where it uniquely shines:

Persistent AI Agents: Julep specializes in creating AI agents that maintain context and state over long-term interactions.

Stateful Sessions: Think of Julep when you need sessions that remember past interactions, enabling personalized and context-aware responses.

Customizable Workflows: It's ideal for building complex, multi-step workflows with features like conditional logic, loops, and parallel processing.

Advanced Task Orchestration: Julep excels at orchestrating intricate tasks without requiring you to build the orchestration logic from scratch.

Seamless Tool and API Integration: Use Julep when you want to integrate external tools and APIs directly into your agent's workflows.

Agent-Centric Design: It's designed around autonomous agents with their own identities and long-term goals, perfect for applications needing more than simple prompt-response interactions.

Reason to Recall Julep:

When you're working on a project that requires an AI agent to:

Maintain Long-Term Context: Remember user preferences or past interactions over extended periods.

Handle Complex Operations: Perform multi-step tasks that involve decision-making, branching logic, or interacting with multiple services.

Integrate with External Systems: Seamlessly connect with APIs, databases, or other tools as part of the agent's workflow.

Provide Personalized Experiences: Offer responses or actions tailored to individual users based on accumulated context.

In these scenarios, Julep uniquely shines by providing the infrastructure and tools needed to build such sophisticated, stateful AI applications without having to build the underlying systems yourself.






Possible Descriptions:

"Julep is an open-source platform for building persistent AI agents that maintain long-term context and execute complex, customizable workflows."

"Create AI agents that remember past interactions and handle intricate tasks with Julep's customizable workflows and seamless tool integration."

"Julep enables developers to build stateful AI agents with advanced task orchestration, maintaining context over time and integrating external tools directly into workflows."

"With Julep, develop AI agents that persist over sessions, perform multi-step tasks, and integrate various tools and APIs effortlessly."

"Julep is a platform for creating AI agents that maintain state and execute complex workflows, offering long-term context and advanced orchestration capabilities."




Key Concepts to Include:

Persistent AI Agents: Agents that maintain context and state over long-term interactions.
Customizable Workflows: Ability to define complex, multi-step tasks with conditional logic, loops, and more.
Seamless Tool and API Integration: Direct integration of external tools and APIs into agents' workflows.
Stateful Sessions: Sessions that remember past interactions for personalized and context-aware responses.
Advanced Task Orchestration: Orchestrate intricate tasks without building the underlying logic from scratch.



Top 5 Winners
1.5 "Julep: Open-source platform for AI agents with long-term memory and complex workflows."

2.5 "Julep: Create AI agents that remember and handle intricate tasks effortlessly."

3.5 "Julep: Create AI agents with persistent context and advanced orchestration."

4.5 "Julep: Craft AI agents that persist and perform complex tasks seamlessly."

5.5 "Julep: Build AI agents with persistent state and powerful task execution."

18 changes: 15 additions & 3 deletions agents-api/agents_api/models/user/create_or_update_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,21 @@

@rewrap_exceptions(
{
QueryException: partialclass(HTTPException, status_code=400),
ValidationError: partialclass(HTTPException, status_code=400),
TypeError: partialclass(HTTPException, status_code=400),
QueryException: partialclass(
HTTPException,
status_code=400,
detail="A database query failed to return the expected results. This might occur if the requested resource doesn't exist or your query parameters are incorrect.",
),
ValidationError: partialclass(
HTTPException,
status_code=400,
detail="Input validation failed. Please check the provided data for missing or incorrect fields, and ensure it matches the required format.",
),
TypeError: partialclass(
HTTPException,
status_code=400,
detail="A type mismatch occurred. This likely means the data provided is of an incorrect type (e.g., string instead of integer). Please review the input and try again.",
),
}
)
@wrap_in_class(User, one=True, transform=lambda d: {"id": UUID(d.pop("user_id")), **d})
Expand Down
21 changes: 17 additions & 4 deletions agents-api/agents_api/models/user/create_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,24 @@
lambda e: isinstance(e, QueryException)
and "asserted to return some results, but returned none"
in str(e): lambda *_: HTTPException(
detail="developer not found", status_code=403
detail="Developer not found. Please ensure the provided auth token (which refers to your developer_id) is valid and the developer has the necessary permissions to create an agent.",
status_code=403,
),
QueryException: partialclass(
HTTPException,
status_code=400,
detail="A database query failed to return the expected results. This might occur if the requested resource doesn't exist or your query parameters are incorrect.",
),
ValidationError: partialclass(
HTTPException,
status_code=400,
detail="Input validation failed. Please check the provided data for missing or incorrect fields, and ensure it matches the required format.",
),
TypeError: partialclass(
HTTPException,
status_code=400,
detail="A type mismatch occurred. This likely means the data provided is of an incorrect type (e.g., string instead of integer). Please review the input and try again.",
),
QueryException: partialclass(HTTPException, status_code=400),
ValidationError: partialclass(HTTPException, status_code=400),
TypeError: partialclass(HTTPException, status_code=400),
}
)
@wrap_in_class(
Expand Down
29 changes: 26 additions & 3 deletions agents-api/agents_api/models/user/delete_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,32 @@

@rewrap_exceptions(
{
QueryException: partialclass(HTTPException, status_code=400),
ValidationError: partialclass(HTTPException, status_code=400),
TypeError: partialclass(HTTPException, status_code=400),
lambda e: isinstance(e, QueryException)
and "Developer does not exist" in str(e): lambda *_: HTTPException(
detail="The specified developer does not exist.",
status_code=403,
),
lambda e: isinstance(e, QueryException)
and "Developer does not own resource"
in e.resp["display"]: lambda *_: HTTPException(
detail="The specified developer does not own the requested resource. Please verify the ownership or check if the developer ID is correct.",
status_code=404,
),
QueryException: partialclass(
HTTPException,
status_code=400,
detail="A database query failed to return the expected results. This might occur if the requested resource doesn't exist or your query parameters are incorrect.",
),
ValidationError: partialclass(
HTTPException,
status_code=400,
detail="Input validation failed. Please check the provided data for missing or incorrect fields, and ensure it matches the required format.",
),
TypeError: partialclass(
HTTPException,
status_code=400,
detail="A type mismatch occurred. This likely means the data provided is of an incorrect type (e.g., string instead of integer). Please review the input and try again.",
),
}
)
@wrap_in_class(
Expand Down
26 changes: 20 additions & 6 deletions agents-api/agents_api/models/user/get_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,31 @@
@rewrap_exceptions(
{
lambda e: isinstance(e, QueryException)
and "Developer not found" in str(e): lambda *_: HTTPException(
detail="developer does not exist", status_code=403
and "Developer does not exist" in str(e): lambda *_: HTTPException(
detail="The specified developer does not exist.",
status_code=403,
),
lambda e: isinstance(e, QueryException)
and "Developer does not own resource"
in e.resp["display"]: lambda *_: HTTPException(
detail="developer doesnt own resource", status_code=404
detail="The specified developer does not own the requested resource. Please verify the ownership or check if the developer ID is correct.",
status_code=404,
),
QueryException: partialclass(
HTTPException,
status_code=400,
detail="A database query failed to return the expected results. This might occur if the requested resource doesn't exist or your query parameters are incorrect.",
),
ValidationError: partialclass(
HTTPException,
status_code=400,
detail="Input validation failed. Please check the provided data for missing or incorrect fields, and ensure it matches the required format.",
),
TypeError: partialclass(
HTTPException,
status_code=400,
detail="A type mismatch occurred. This likely means the data provided is of an incorrect type (e.g., string instead of integer). Please review the input and try again.",
),
QueryException: partialclass(HTTPException, status_code=400),
ValidationError: partialclass(HTTPException, status_code=400),
TypeError: partialclass(HTTPException, status_code=400),
}
)
@wrap_in_class(User, one=True)
Expand Down
18 changes: 15 additions & 3 deletions agents-api/agents_api/models/user/list_users.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,21 @@

@rewrap_exceptions(
{
QueryException: partialclass(HTTPException, status_code=400),
ValidationError: partialclass(HTTPException, status_code=400),
TypeError: partialclass(HTTPException, status_code=400),
QueryException: partialclass(
HTTPException,
status_code=400,
detail="A database query failed to return the expected results. This might occur if the requested resource doesn't exist or your query parameters are incorrect.",
),
ValidationError: partialclass(
HTTPException,
status_code=400,
detail="Input validation failed. Please check the provided data for missing or incorrect fields, and ensure it matches the required format.",
),
TypeError: partialclass(
HTTPException,
status_code=400,
detail="A type mismatch occurred. This likely means the data provided is of an incorrect type (e.g., string instead of integer). Please review the input and try again.",
),
}
)
@wrap_in_class(User)
Expand Down
18 changes: 15 additions & 3 deletions agents-api/agents_api/models/user/patch_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,21 @@

@rewrap_exceptions(
{
QueryException: partialclass(HTTPException, status_code=400),
ValidationError: partialclass(HTTPException, status_code=400),
TypeError: partialclass(HTTPException, status_code=400),
QueryException: partialclass(
HTTPException,
status_code=400,
detail="A database query failed to return the expected results. This might occur if the requested resource doesn't exist or your query parameters are incorrect.",
),
ValidationError: partialclass(
HTTPException,
status_code=400,
detail="Input validation failed. Please check the provided data for missing or incorrect fields, and ensure it matches the required format.",
),
TypeError: partialclass(
HTTPException,
status_code=400,
detail="A type mismatch occurred. This likely means the data provided is of an incorrect type (e.g., string instead of integer). Please review the input and try again.",
),
}
)
@wrap_in_class(
Expand Down
Loading

0 comments on commit 0e89dc9

Please sign in to comment.