Migrating to Kern v2.0
Guide to migrate your Kern applications from v1 to v2.
If you have questions during your migration, we can help! See Get Help for more information.
Reference the v2.0 Changelog for the full list of changes.
Installing Kern v2
If you are already using Kern, you can upgrade to v2 by running:
1pip install -U kern-aiOtherwise, you can install the latest version of Kern v2 by running:
1pip install kern-aiMigrating your Kern DB
If you used our Storage or Memory functionalities to store Agent sessions and memories in your database, you can start by migrating your tables.
Use our migration script: libs/kern/migrations/v1_to_v2/migrate_to_v2.py
The script supports PostgreSQL, MySQL, SQLite, and MongoDB. Update the database connection settings, the batch size (useful if you are migrating large tables) in the script and run it.
Notice:
- The script won't cleanup the old tables, in case you still need them.
- The script is idempotent. If something goes wrong or if you stop it mid-run, you can run it again.
- Metrics are automatically converted from v1 to v2 format.
Migrating your Kern code
Each section here covers a specific framework domain, with before and after examples and detailed explanations where needed.
1. Agents and Teams
Agents and Teams are the main building blocks in the Kern framework.
Below are some of the v2 updates we have made to the Agent and Team classes:
1.1. Streaming responses with arun now returns an AsyncIterator, not a coroutine. This is how you consume the resulting events now, when streaming a run:
1async for event in agent.arun(...):2 ...1.2. The RunResponse class is now RunOutput. This is the type of the results you get when running an Agent:
1from kern.run.agent import RunOutput23run_output: RunOutput = agent.run(...)1.3. The events you get when streaming an Agent result have been renamed:
RunOutputStartedEvent→RunStartedEventRunOutputCompletedEvent→RunCompletedEventRunOutputErrorEvent→RunErrorEventRunOutputCancelledEvent→RunCancelledEventRunOutputContinuedEvent→RunContinuedEventRunOutputPausedEvent→RunPausedEventRunOutputContentEvent→RunContentEvent
1.4. Similarly, for Team output events:
TeamRunOutputStartedEvent→TeamRunStartedEventTeamRunOutputCompletedEvent→TeamRunCompletedEventTeamRunOutputErrorEvent→TeamRunErrorEventTeamRunOutputCancelledEvent→TeamRunCancelledEventTeamRunOutputContentEvent→TeamRunContentEvent
1.5. The add_state_in_messages parameter has been deprecated. Variables in instructions are now resolved automatically by default.
1.6. The context parameter has been renamed to dependencies.
This is how it looked like on v1:
1from kern.agent import Agent23agent = Agent(4 context={"top_stories": get_top_hackernews_stories},5 instructions="Here are the top stories: {top_stories}",6 add_state_in_messages=True,7)This is how it looks like now, on v2:
1from kern.agent import Agent23agent = Agent(4 dependencies={"top_stories": get_top_hackernews_stories},5 instructions="Here are the top stories: {top_stories}",6 # resolve_in_context=True by default - no need to set add_state_in_messages7)See the full list of changes in the Agent Updates section of the changelog.
2. Storage
Storage is used to persist Agent sessions, state and memories in a database.
This is how Storage looks like on v1:
1from kern.agent import Agent2from kern.storage.sqlite import SqliteStorage34storage = SqliteStorage(table_name="agent_sessions", db_file="kern.db", mode="agent")56agent = Agent(storage=storage)These are the changes we have made for v2:
2.1. The Storage classes have moved from kern/storage to kern/db. We will now refer to them as our Db classes.
2.2. The mode parameter has been deprecated. The same instance can now be used by Agents, Teams and Workflows.
1from kern.agent import Agent2from kern.db.sqlite import SqliteDb34db = SqliteDb(db_file="kern.db")56agent = Agent(db=db)2.3. The table_name parameter has been deprecated. One instance now handles multiple tables, you can define their names individually.
1db = SqliteDb(db_file="kern.db", sessions_table="your_sessions_table_name", ...)These are all the supported tables, each used to persist data related to a specific domain:
1db = SqliteDb(2 db_file="kern.db",3 # Table to store your Agent, Team and Workflow sessions and runs4 session_table="your_session_table_name",5 # Table to store all user memories6 memory_table="your_memory_table_name",7 # Table to store all metrics aggregations8 metrics_table="your_metrics_table_name",9 # Table to store all your evaluation data10 eval_table="your_evals_table_name",11 # Table to store all your knowledge content12 knowledge_table="your_knowledge_table_name",13)2.4. Previously running a Team would create a team session and sessions for every team member participating in the run. Now, only the Team session is created. The runs for the team leader and all members can be found in the Team session.
1team.run(...)23team_session = team.get_latest_session()45# The runs for the team leader and all team members are here6team_session.runsSee more changes in the Storage Updates section of the changelog.
3. Memory
Memory gives an Agent the ability to recall relevant information.
This is how Memory looks like on V1:
1from kern.agent import Agent2from kern.memory.v2.db.sqlite import SqliteMemoryDb3from kern.memory.v2.memory import Memory45memory_db = SqliteMemoryDb(table_name="memory", db_file="kern.db")6memory = Memory(db=memory_db)78agent = Agent(memory=memory)These are the changes we have made for v2:
3.1. The MemoryDb classes have been deprecated. The main Db classes are to be used.
3.2. The Memory class has been deprecated. You now just need to set enable_user_memories=True on an Agent with a db for Memory to work.
1from kern.agent import Agent2from kern.db.sqlite import SqliteDb34db = SqliteDb(db_file="kern.db")56agent = Agent(db=db, enable_user_memories=True)3.3. The generated memories will be stored in the memories_table. By default, the agno_memories will be used. It will be created if needed. You can also set the memory table like this:
1db = SqliteDb(db_file="kern.db", memory_table="your_memory_table_name")3.4. The methods you previously had access to through the Memory class, are now direclty available on the relevant db object. For example:
1agent.get_user_memories(user_id="123")You can find examples for other databases and advanced scenarios in the Memory documentation.
See more changes in the Memory Updates section of the changelog.
4. Knowledge
Knowledge gives an Agent the ability to search and retrieve relevant, domain-specific information from a knowledge base.
These are the changes we have made for v2:
4.1. AgentKnowledge has been deprecated in favor of the new Knowledge class.
Along with this, all of the child classes that used AgentKnowledge as a base have been removed. Their capabilities are now supported
by default in Knowledge. This also means that the correct reader for the content that you are adding is now selected automatically, with
the option to override it at any time.
4.2. The load() method and its variations have been replaced by insert(). Content is the building block of any piece of knowledge originating
from any sources. For a full example of the usage, see the Content Types page.
4.3. Knowledge now supports a contents_db. This allows the storage and management of every piece of content that is added to your knowledge.
Furthermore, we now support deletion of individual vectors using the remove_vectors_by_id(), remove_vectors_by_name() and remove_vectors by metadata()methods. You can also delete all vectors created by a specific piece of content usingremove_content_by_id()`.
4.4 In order to support the deletion mentioned above, VectorDB tables have been updated. Two new columns, content_hash and content_id have been added.
4.5. The retriever field has been renamed to knowledge_retriever.
4.6. The add_references method has been renamed to add_knowledge_to_context.
Renamed
retriever->knowledge_retrieveradd_references->add_knowledge_to_context
See more changes in the Knowledge Updates section of the changelog.
5. Metrics
Metrics are used to understand the usage and consumption related to a Session, a Run or a Message.
These are the changes we have made for v2:
5.1. Field name changes:
time→durationaudio_tokens→audio_total_tokensinput_audio_tokens→audio_input_tokensoutput_audio_tokens→audio_output_tokenscached_tokens→cache_read_tokens
5.2. Deprecated fields (removed in v2):
prompt_tokensandcompletion_tokens- replaced byinput_tokensandoutput_tokensprompt_tokens_detailsandcompletion_tokens_details- detailed info moved toprovider_metrics
5.3. New structure:
- Provider-specific metrics fields are now inside the
provider_metricsfield - A new
additional_metricsfield has been added for custom metrics
The migration script automatically converts all metrics from v1 to v2 format, including nested metrics in session data.
6. Teams
We have refactored the Team class to be more flexible and powerful.
The biggest changes is that the mode parameter has been deprecated. Instead there are attributes that can be used to control the behavior of the team:
respond_directly-> If True, the team leader won't process responses from the members and instead will return them directlydelegate_to_all_members-> If True, the team leader will delegate tasks to all members simultaneously, instead of one by one. When running async (usingarun) members will run concurrently.determine_input_for_members->Trueby default. Set to False if you want to send the run input directly to the member agents without the team leader synthesizing its own input. This is useful if you want to send pydantic model input directly to the member agents.
Here is a quick migration guide:
- If you previously used
mode=coordinate, this is now the default behaviour and you can use theTeamwithout any modifications. - If you previously used
mode=route, you can now userespond_directly=Trueanddetermine_input_for_members=Falseto achieve the same behaviour. - If you previously used
mode=collaborate, you can setdelegate_to_all_members=Trueto achieve the same behaviour.
See the Team updates section of the changelog for more details.
7. Workflows
We have heavily updated our Workflows, aiming to provide top-of-the-line tooling to build agentic systems.
Make sure to check our comprehensive migration guide for Workflows.
7. Apps -> Interfaces
The old "apps" system (AGUIApp, SlackApi, WhatsappApi) has been replaced with a unified interfaces system within AgentOS.
Before - Standalone Apps
1from kern.app.agui.app import AGUIApp23agui_app = AGUIApp(agent=agent)4app = agui_app.get_app()5agui_app.serve(port=8000)After - Unified Interfaces
1from kern.os import AgentOS2from kern.os.interfaces.agui import AGUI34agent_os = AgentOS(agents=[agent], interfaces=[AGUI(agent=agent)])5app = agent_os.get_app()6agent_os.serve(port=8000)Migration Steps
- Update imports: Replace app imports with interface imports
- Use AgentOS: Wrap agents with
AgentOSand specify interfaces - Update serving: Use
agent_os.serve()instead ofapp.serve()
8. Playground -> AgentOS
Our Playground has been deprecated. Our new AgentOS offering will substitute all usecases.
See AgentOS for more details!