Releases: AgentEra/Agently
v4.0.6
Features
ChromaDB Integrations
You can use Agently ChromaDB Integrations to simplify the use case of ChromaDB
from agently import Agently
from agently.integrations.chromadb import ChromaData, ChromaEmbeddingFunction
from chromadb import Client as ChromaDBClient
embedding = Agently.create_agent()
embedding.set_settings(
"OpenAICompatible",
{
"model": "qwen3-embedding:0.6b",
"base_url": "http://127.0.0.1:11434/v1/",
"auth": "nothing",
"model_type": "embeddings",
},
).set_settings("debug", False)
embedding_function = ChromaEmbeddingFunction(agent=embedding)
chroma_data = ChromaData(
[
{
"document": "Book about Dogs",
"metadata": {"book_name": "🐶"},
},
{
"document": "Book about cars",
"metadata": {"book_name": "🚗"},
},
{
"document": "Book about vehicles",
"metadata": {"book_name": "🚘"},
},
{
"document": "Book about birds",
"metadata": {"book_name": "🐦⬛"},
},
],
)
chromadb = ChromaDBClient()
collection = chromadb.create_collection(
name="test",
get_or_create=True,
metadata={
"hnsw:space": "cosine",
},
configuration={
"embedding_function": embedding_function,
},
)
collection.add(**chroma_data.get_kwargs())
print("[ADD]:\n", chroma_data.get_original_data())
result = collection.query(query_texts=["Book about traffic"])
print(result)Updates
TriggerFlow
.when()support 'and', 'or' and 'simple_or' mode. [Example Code]- Developers can use
.save_blue_print()to export blue print data from trigger flow instance or from blue print instance and use.load_blue_print()to import blue print data into other trigger flow instance or blue print instance. [Example Code]
Agent Request
Better Prompt DX
- [Prompt]: New prompt slots
optionsto allow developers to customize single request / agent request options. - [Prompt]: New prompt slots
examplesto help developers provide one-shot / few-shots examples. - [Prompt]: Update
agent.promptto allow developers export prompt text or messages only. [Example Code] - [Prompt]: New settings
prompt.prompt_title_mappingto help developers to customize title of different prompt slots. [Example Code]
Configure Prompt Update
- [Configure Prompt]: Support the expression of Agently output format. [Example Code]
Request Settings Updates to Support Local Deployed Model Service
- [Request Settings]: Support customized authorization headers [Example Code]
- [Request Settings]: Developers can use
full_urlto provide full model request URL in case that sometimes the model URL does not follow the rule of OpenAI base URL. - [Request Settings]: Developers can use
api_keyin request settings now, it works all the same asauth.
Agent Response
- [Instant Mode]: StreamingData add attribute
full_datawhich contains current completed streaming data. - [Result]: Former
.get_result()method is renamed as.get_data()which will return parsed data. New.get_result()method will returnAgentlyResponseResultinstance which contains more attributes to help developers to collect information of result. - [Response Generator Type]: New response generator type
typed_delta(and now.get_generator()and.get_async_generator()will use argumenttypeinstead of argumentcontent). - [Response Event]: Add new response event
tool_callswhich can be consumed in generator typetyped_deltaandinstant/streaming_parse. [Example Code]
Plugins
- [Agent Extension Core]: Update extension handler slots to
request_prefixes,broadcast_prefixes,broadcast_suffixesandfinally - [Tools]: Built-in tool Search new support argument
optionsto customize more options configures. [Example Code]
Utils
- [FunctionShifter]: New decorator
@auto_options_functo help developers to create a function that will ignore undefined key arguments that passed by caller (useful when model try to pass undefined arguments to a tool function).
v4.0.5
Key Feature Updates
TriggerFlow
- Rewrite for each process (
.for_each()) to support nested for each loops perfectly. [Example Code] - Add
.____(<comments>, log_info=<True | False>, print_info=<True | False>, show_value=<True | False>)to help developers to write flow chain beautifully. - Add
.when()to support developers to wait chunk done event, runtime data change event, flow data change event or customize event and trigger the next actions. [Example Code] - Add
.collect()to support developers to wait and collect parallel branches. [Example Code] - Rewrite and update match case process, now developers can use
.match(mode=<"hit_all" | "hit_first">)to set different judgement hit strategy. [Example Code]
You can also explore more example codes in TriggerFlow examples dir.
Prompt Configures
In Agently v3, developers loved YAML-Prompt very much. Now we update this feature to Prompt Configures!
Mappings replacing in any prompt settings
Now developers can use mappings parameter in any prompt setting methods. Use case examples: agent.input("${user_input}", mappings={ "user_input": beautify(user_input) }) or agent.set_agent_prompt("instruct", "You're a ${ role }", mappings={ "role": roles[current_role] }).
Developers can use mapping replacing feature to replace placeholder ${ <variable name> } in string content. Dvelopers can also use it to replace key name or value in dictionary like { "${ key_to_be_replaced }": "${ value_to_be_replaced_directly }" }.
Check here to see Example Code
YAML and JSON format supported!
Now developers can use both YAML and JSON format data to configure agent behaviors!
-
YAML-Prompt Example Code:
-
JSON-Prompt Example Code:
Built-In Tools
We added two built-in tools Search and Browse which can be registered to agent or be used independently. You can use from agently.builtins.tools import Search, Browse to import and use them.
Search tool can search information from DuckDuckGo, Bing, Google, Yahoo, Wikipedia via package ddgs and search document from arXiv.
Browse tool use BeautifulSoup4 to fetch most common website page content for agent.
Check here to see Example Code
Instant Mode
We add a new attribute .wildcard_path to instant mode event data for developers to watch items in list easier. Now developers can use code like if data.wildcard_path == "root_key.list[*]:" to watch and handle every item in root_key.list from Agently agent response in instant mode.
Check here to see Example Code
Other Updates
- Optimized
LazyImportto support the situation when the package's import name is different from the install name. - Optimized tool using logic to catch exceptions when calling the tools instead of preventing the agent request process.
- Many other updates and bug fixes...
=========
We'll keep updating and welcome all users to express your ideas or discuss with us in https://github.com/AgentEra/Agently/discussions
Have fun and happy coding!
v4.0.3
Some major bugs fixed and add more examples:
Trigger Flow Feature Examples: https://github.com/AgentEra/Agently/tree/main/examples/trigger_flow
Trigger Flow WebSocket Server Example: https://github.com/AgentEra/Agently/tree/main/examples/trigger_flow/ws_server
v4.0.1
New Features:
[Trigger Flow]:
- if condition chain expression;
- flow.when(), flow.when_event(), flow.when_runtime_data(), flow.when_flow_data();
- quick start from flow instance(create a temp execution);
- separator method .____();
- support specific event type when create new process;
v4.0.0 Official
New Feature:
TriggerFlow(Examples)
v4.0.0-beta-3
v4.0.0b3 (#232)
New Features:
- Support MCP as Tools: https://github.com/AgentEra/Agently/blob/main/examples/mcp_agent.py
- Key Waiter Extension: https://github.com/AgentEra/Agently/blob/main/examples/key_waiter_agent.py
- Auto Func Decorator: https://github.com/AgentEra/Agently/blob/main/examples/auto_func_decorator.py
- Use system message to manage in-frame events
- Streaming debug logs (new Debug Console CUI still need to be optimized)
Bug fix:
- Bugs of Tool Extension in v4.0.0v2
- Httpx connection close too soon when request need a long time
Full Changelog: v4.0.0-beta-2...v4.0.0-beta-3
v4.0.0-beta-2
Key feature: Agent Extension Tool
import asyncio
from agently import Agently
Agently.set_settings(
"OpenAICompatible",
{
"base_url": "http://localhost:11434/v1",
"model": "qwen2.5:7b",
"model_type": "chat",
},
)
agent = Agently.create_agent()
@agent.tool_func
async def add(a: int, b: int) -> int:
"""
Get result of `a(int)` add `b(int)`
"""
await asyncio.sleep(1)
print(a, b, a + b)
return a + b
result = agent.input("34643523+52131231=? Use tool to calculate!").use_tool(add).start()
print(result)v4.0.0-beta-1
Agently 4 (v4.0.0.Beta1)
Speed Up Your GenAI Application Development
Getting Started
Agently is a Python-based framework for building GenAI applications. You can install it via pip and import features using from agently import Agently.
Install via pip:
pip install agently==4.0.0b1Clone the repository and install locally:
git clone [email protected]:AgentEra/Agently.git
cd Agently
pip install -e .What is Agently?
Agently aims to provide an intuitive, efficient, and developer-friendly framework for GenAI application development. By deeply understanding the runtime control needs of model outputs, Agently bridges the gap between large language models and real-world applications.
Agently abstracts away the complexities of:
- Varying model parameters
- Output formatting
- Communication between engineering modules and GenAI logic
...while giving developers full control over business logic and integration with existing systems.
We believe GenAI is not a generational replacement for current systems but a powerful extension. Engineers and tools are key to turning GenAI's possibilities into reality.
Our mission is to build the best developer experience (DX) for GenAI application engineers.
Core Features Overview
Structured and Streamed Output Control for LLMs
Agently allows you to control and consume model outputs using a developer-centric pattern:
from agently import Agently
agent = Agently.create_agent()
(
agent
.input("What time is it now?", always=True)
.info({
"default_timezone": "",
"tool_list": [{
"name": "get_current_time",
"desc": "Get current time by time zone provided",
"kwargs": {
"timezone_str": (str, "time zone string in ZoneInfo()"),
},
}]
})
.output({
"first_time_response": (str, ),
"tool_using_judgement": (bool, ),
"tool_using_command": (
{
"name": (str, "Decide which tool to use by tool name:{tool_list.[].name}"),
"kwargs": (dict, "According {tool_list.[].args} to output kwargs dictionary"),
},
"If {tool_using_judgement}==False, just output {}",
),
})
)Then, consume the model response:
response = agent.get_response()
# Get raw output
response_text = response.get_text()
# Get parsed structured result
response_dict = response.get_result()
# Streamed output
for delta in response.get_generator(content="delta"):
print(delta, end="", flush=True)Or use the instant parsing mode:
instant_response_generator = response.get_generator(content="instant")
use_tool = False
for instant_message in instant_response_generator:
if instant_message.path == "first_time_response":
if instant_message.delta is not None:
print(instant_message.delta, end="", flush=True)
elif instant_message.path == "tool_using_judgement":
use_tool = instant_message.value
print()
if use_tool:
print("[USE TOOL!]")
else:
print("[NO NEED TO USE TOOL!]")
if use_tool:
if instant_message.path == "tool_using_command.name" and instant_message.is_complete:
print(f"I want to use: '{ instant_message.value }'")
elif instant_message.path == "tool_using_command":
print(f"call: { instant_message.value }")
print(f"kwargs: { instant_message.value }")I can check the current time for you. Please specify a timezone (e.g., 'America/New_York') so I can provide the accurate time.
[NO NEED TO USE TOOL!][More documentation coming soon...]
💬 WeChat Group (Join Us)
Click Here to Apply
or Scan the QR Code Below:
