Skip to content

Commit ba81e14

Browse files
committed
Update to latest agent framework
1 parent 6026961 commit ba81e14

29 files changed

Lines changed: 433 additions & 373 deletions
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
---
2+
name: pdf-to-markdown
3+
description: Converts PDF files to Markdown using Microsoft's markitdown package. Use this skill when the user asks to convert a PDF to Markdown, extract text from a PDF, or read/parse PDF content.
4+
argument-hint: "[path to file]"
5+
---
6+
7+
# PDF to Markdown Conversion
8+
9+
This skill converts PDF files to Markdown format using [Microsoft's markitdown](https://github.com/microsoft/markitdown) package.
10+
11+
## When to use
12+
13+
- User asks to convert a PDF to Markdown
14+
- User wants to extract text content from a PDF
15+
- User needs to read or parse a PDF document
16+
- User asks to summarize or analyze a PDF file
17+
18+
## How to use
19+
20+
Use `uvx` to run markitdown directly. Pick the dependency group matching the file type:
21+
22+
| File type | Dependency group |
23+
|-----------|-----------------|
24+
| PDF | `pdf` |
25+
| PowerPoint | `pptx` |
26+
| Word | `docx` |
27+
| Excel (.xlsx) | `xlsx` |
28+
| Excel (.xls) | `xls` |
29+
30+
```bash
31+
uvx 'markitdown[pdf]' <path-to-file> -o output.md
32+
```
33+
34+
Or install all optional dependencies at once:
35+
36+
```bash
37+
uvx 'markitdown[all]' <path-to-file> -o output.md
38+
```
39+
40+
## Examples
41+
42+
```bash
43+
uvx 'markitdown[pdf]' report.pdf -o report.md
44+
uvx 'markitdown[pptx]' slides.pptx -o slides.md
45+
uvx 'markitdown[docx]' document.docx -o document.md
46+
```
47+
48+
## Output
49+
50+
- If you were asked to save the output to a specific file, save it to the requested file using `-o`.
51+
- If no output file was specified, use the source filename with a `.md` suffix.

examples/agent_basic.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import asyncio
22
import os
33

4-
from agent_framework import ChatAgent
4+
from agent_framework import Agent
55
from agent_framework.openai import OpenAIChatClient
66
from azure.identity.aio import DefaultAzureCredential, get_bearer_token_provider
77
from dotenv import load_dotenv
@@ -31,7 +31,7 @@
3131
api_key=os.environ["OPENAI_API_KEY"], model_id=os.environ.get("OPENAI_MODEL", "gpt-5-mini")
3232
)
3333

34-
agent = ChatAgent(chat_client=client, instructions="You're an informational agent. Answer questions cheerfully.")
34+
agent = Agent(client=client, instructions="You're an informational agent. Answer questions cheerfully.")
3535

3636

3737
async def main():

examples/agent_mcp_local.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import os
44
from datetime import datetime
55

6-
from agent_framework import ChatAgent, MCPStreamableHTTPTool
6+
from agent_framework import Agent, MCPStreamableHTTPTool
77
from agent_framework.openai import OpenAIChatClient
88
from azure.identity.aio import DefaultAzureCredential, get_bearer_token_provider
99
from dotenv import load_dotenv
@@ -47,8 +47,8 @@ async def main() -> None:
4747
"""Run an agent connected to a local MCP server for expense logging."""
4848
async with (
4949
MCPStreamableHTTPTool(name="Expenses MCP Server", url=MCP_SERVER_URL) as mcp_server,
50-
ChatAgent(
51-
chat_client=client,
50+
Agent(
51+
client=client,
5252
instructions=(
5353
"You help users with tasks using the available tools. "
5454
f"Today's date is {datetime.now().strftime('%Y-%m-%d')}."

examples/agent_mcp_remote.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import logging
33
import os
44

5-
from agent_framework import ChatAgent, MCPStreamableHTTPTool
5+
from agent_framework import Agent, MCPStreamableHTTPTool
66
from agent_framework.openai import OpenAIChatClient
77
from azure.identity.aio import DefaultAzureCredential, get_bearer_token_provider
88
from dotenv import load_dotenv
@@ -48,8 +48,8 @@ async def main() -> None:
4848
name="Microsoft Learn MCP",
4949
url="https://learn.microsoft.com/api/mcp",
5050
) as mcp_server,
51-
ChatAgent(
52-
chat_client=client,
51+
Agent(
52+
client=client,
5353
instructions=(
5454
"You help with Microsoft documentation questions. "
5555
"Use the available tools to search for relevant docs."

examples/agent_memory_mem0.py

Lines changed: 13 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@
33
import os
44
import random
55
import uuid
6-
from collections.abc import MutableSequence
7-
from typing import Annotated, Any
6+
from typing import Annotated
87

9-
from agent_framework import ChatAgent, ChatMessage, Context, tool
10-
from agent_framework.mem0 import Mem0Provider
8+
from agent_framework import Agent, tool
9+
from agent_framework.mem0 import Mem0ContextProvider
1110
from agent_framework.openai import OpenAIChatClient
1211
from azure.identity.aio import DefaultAzureCredential, get_bearer_token_provider
1312
from dotenv import load_dotenv
@@ -49,7 +48,7 @@
4948

5049
# NOTE: approval_mode="never_require" is for sample brevity.
5150
# Use "always_require" in production.
52-
@tool(approval_mode="never_require")
51+
@tool
5352
def get_weather(
5453
city: Annotated[str, Field(description="The city to get the weather for.")],
5554
) -> str:
@@ -59,53 +58,12 @@ def get_weather(
5958
return f"The weather in {city} is {conditions[random.randint(0, 3)]} with a high of {random.randint(10, 30)}°C."
6059

6160

62-
class Mem0OSSProvider(Mem0Provider):
63-
"""Mem0Provider subclass that fixes search for Mem0 OSS (AsyncMemory).
64-
65-
The base Mem0Provider passes user_id/agent_id inside a 'filters' dict,
66-
which works for the Mem0 Platform client but not for AsyncMemory (OSS),
67-
which expects them as direct keyword arguments.
68-
"""
69-
70-
async def invoking(self, messages: ChatMessage | MutableSequence[ChatMessage], **kwargs: Any) -> Context:
71-
self._validate_filters()
72-
messages_list = [messages] if isinstance(messages, ChatMessage) else list(messages)
73-
input_text = "\n".join(msg.text for msg in messages_list if msg and msg.text and msg.text.strip())
74-
75-
if not input_text.strip():
76-
return Context(messages=None)
77-
78-
# Pass user_id/agent_id as keyword args (Mem0 OSS API)
79-
search_kwargs: dict[str, Any] = {"query": input_text}
80-
if self.user_id:
81-
search_kwargs["user_id"] = self.user_id
82-
if self.agent_id:
83-
search_kwargs["agent_id"] = self.agent_id
84-
85-
search_response = await self.mem0_client.search(**search_kwargs)
86-
87-
if isinstance(search_response, list):
88-
memories = search_response
89-
elif isinstance(search_response, dict) and "results" in search_response:
90-
memories = search_response["results"]
91-
else:
92-
memories = [search_response]
93-
94-
line_separated_memories = "\n".join(memory.get("memory", "") for memory in memories)
95-
96-
return Context(
97-
messages=[ChatMessage(role="user", text=f"{self.context_prompt}\n{line_separated_memories}")]
98-
if line_separated_memories
99-
else None
100-
)
101-
102-
10361
async def main() -> None:
10462
"""Demonstrate an agent with Mem0 OSS for long-term memory.
10563
106-
Unlike RedisProvider (which stores raw messages), Mem0 uses an LLM to
64+
Unlike RedisContextProvider (which stores raw messages), Mem0 uses an LLM to
10765
extract and store distilled facts from conversations. When the agent
108-
starts a new thread, Mem0 injects relevant memories as context.
66+
starts a new session, Mem0 injects relevant memories as context.
10967
11068
Mem0 OSS needs an LLM and embedder for memory extraction. This example
11169
uses Azure OpenAI when API_HOST=azure, otherwise falls back to OPENAI_API_KEY.
@@ -161,16 +119,16 @@ async def main() -> None:
161119

162120
mem0_client = await AsyncMemory.from_config(mem0_config)
163121

164-
provider = Mem0OSSProvider(user_id=user_id, mem0_client=mem0_client)
122+
provider = Mem0ContextProvider(source_id="mem0_memory", user_id=user_id, mem0_client=mem0_client)
165123

166-
agent = ChatAgent(
167-
chat_client=client,
124+
agent = Agent(
125+
client=client,
168126
instructions=(
169127
"You are a helpful weather assistant. Personalize replies using provided context. "
170128
"Before answering, always check for stored context."
171129
),
172130
tools=[get_weather],
173-
context_provider=provider,
131+
context_providers=[provider],
174132
)
175133

176134
# Step 1: Teach the agent user preferences
@@ -179,12 +137,12 @@ async def main() -> None:
179137
response = await agent.run("Remember that my favorite city is Tokyo and I prefer Celsius.")
180138
print(f"[green]Agent:[/green] {response.text}")
181139

182-
# Step 2: Start a new thread — Mem0 should inject remembered facts
183-
print("\n[dim]--- Step 2: New thread — recalling preferences ---[/dim]")
140+
# Step 2: Start a new session — Mem0 should inject remembered facts
141+
print("\n[dim]--- Step 2: New session — recalling preferences ---[/dim]")
184142
print("[blue]User:[/blue] What's my favorite city?")
185143
response = await agent.run("What's my favorite city?")
186144
print(f"[green]Agent:[/green] {response.text}")
187-
print("[dim]Note: Mem0 extracted and stored facts, then injected them into the new thread.[/dim]")
145+
print("[dim]Note: Mem0 extracted and stored facts, then injected them into the new session.[/dim]")
188146

189147
# Step 3: Use a tool, demonstrating memory with tool outputs
190148
print("\n[dim]--- Step 3: Tool use with memory ---[/dim]")

examples/agent_memory_redis.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
import uuid
66
from typing import Annotated
77

8-
from agent_framework import ChatAgent, tool
8+
from agent_framework import Agent, tool
99
from agent_framework.openai import OpenAIChatClient
10-
from agent_framework.redis import RedisProvider
10+
from agent_framework.redis import RedisContextProvider
1111
from azure.identity.aio import DefaultAzureCredential, get_bearer_token_provider
1212
from dotenv import load_dotenv
1313
from pydantic import Field
@@ -48,7 +48,7 @@
4848

4949
# NOTE: approval_mode="never_require" is for sample brevity.
5050
# Use "always_require" in production.
51-
@tool(approval_mode="never_require")
51+
@tool
5252
def get_weather(
5353
city: Annotated[str, Field(description="The city to get the weather for.")],
5454
) -> str:
@@ -59,9 +59,9 @@ def get_weather(
5959

6060

6161
async def example_agent_with_memory() -> None:
62-
"""Demonstrate an agent with Redis-backed long-term memory via RedisProvider.
62+
"""Demonstrate an agent with Redis-backed long-term memory via RedisContextProvider.
6363
64-
The RedisProvider stores conversational context in Redis and retrieves it
64+
The RedisContextProvider stores conversational context in Redis and retrieves it
6565
using full-text search (BM25), or hybrid search (BM25 + vector similarity)
6666
when an embedding model is configured.
6767
@@ -71,10 +71,11 @@ async def example_agent_with_memory() -> None:
7171

7272
user_id = str(uuid.uuid4())
7373

74-
# RedisProvider supports hybrid search (full-text + vector) when a vectorizer is configured.
74+
# RedisContextProvider supports hybrid search (full-text + vector) when a vectorizer is configured.
7575
# However, there is currently a version mismatch between agent-framework-redis and redisvl
7676
# (the HybridQuery API changed), so this example uses text-only search for now.
77-
memory_provider = RedisProvider(
77+
memory_provider = RedisContextProvider(
78+
source_id="redis_memory",
7879
redis_url=REDIS_URL,
7980
index_name="agent_memory_demo",
8081
prefix="memory_demo",
@@ -84,14 +85,14 @@ async def example_agent_with_memory() -> None:
8485
overwrite_index=True,
8586
)
8687

87-
agent = ChatAgent(
88-
chat_client=client,
88+
agent = Agent(
89+
client=client,
8990
instructions=(
9091
"You are a helpful weather assistant. Personalize replies using provided context. "
9192
"Before answering, always check for stored context."
9293
),
9394
tools=[get_weather],
94-
context_provider=memory_provider,
95+
context_providers=[memory_provider],
9596
)
9697

9798
# Step 1: Teach the agent a user preference

0 commit comments

Comments
 (0)