Skip to content

feat: PydanticAI support #133

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions typescript-sdk/apps/dojo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"@ag-ui/llamaindex": "workspace:*",
"@ag-ui/mastra": "workspace:*",
"@ag-ui/middleware-starter": "workspace:*",
"@ag-ui/pydantic-ai": "workspace:*",
"@ag-ui/server-starter": "workspace:*",
"@ag-ui/server-starter-all-features": "workspace:*",
"@ag-ui/vercel-ai-sdk": "workspace:*",
Expand Down
26 changes: 26 additions & 0 deletions typescript-sdk/apps/dojo/src/agents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { LangGraphAgent } from "@ag-ui/langgraph";
import { AgnoAgent } from "@ag-ui/agno";
import { LlamaIndexAgent } from "@ag-ui/llamaindex";
import { CrewAIAgent } from "@ag-ui/crewai";
import { PydanticAIAgent } from "@ag-ui/pydantic-ai";

export const agentsIntegrations: AgentIntegrationConfig[] = [
{
Expand All @@ -20,6 +21,31 @@ export const agentsIntegrations: AgentIntegrationConfig[] = [
};
},
},
{
id: "pydantic-ai",
agents: async () => {
return {
agentic_chat: new PydanticAIAgent({
url: "http://localhost:9000/agentic_chat",
}),
agentic_generative_ui: new PydanticAIAgent({
url: "http://localhost:9000/agentic_generative_ui",
}),
human_in_the_loop: new PydanticAIAgent({
url: "http://localhost:9000/human_in_the_loop",
}),
predictive_state_updates: new PydanticAIAgent({
url: "http://localhost:9000/predictive_state_updates",
}),
shared_state: new PydanticAIAgent({
url: "http://localhost:9000/shared_state",
}),
tool_based_generative_ui: new PydanticAIAgent({
url: "http://localhost:9000/tool_based_generative_ui",
}),
};
},
},
{
id: "server-starter",
agents: async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ const Chat = () => {
],
handler: ({ background }) => {
setBackground(background);
return {
status: "success",
message: `Background changed to ${background}`,
};
},
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const Chat = () => {

return (
<div className="flex">
<div className="bg-gray-100 rounded-lg w-[500px] p-4 text-black space-y-2">
<div className="bg-gray-100 rounded-lg w-[800px] p-4 text-black space-y-2">
{state.steps.map((step, index) => {
if (step.status === "completed") {
return (
Expand All @@ -55,7 +55,7 @@ const Chat = () => {
index === state.steps.findIndex((s) => s.status === "pending")
) {
return (
<div key={index} className="text-3xl font-bold text-slate-700">
<div key={index} className="text-2xl font-bold text-slate-700">
<Spinner />
{step.description}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ const Chat = () => {
});
useCopilotAction({
name: "generate_task_steps",
description: "Generates a list of steps for the user to perform",
parameters: [
{
name: "steps",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,23 +128,36 @@ const DocumentEditor = () => {
}, [text]);

useCopilotAction({
name: "confirm_changes",
renderAndWaitForResponse: ({ args, respond, status }) => (
<ConfirmChanges
args={args}
respond={respond}
status={status}
onReject={() => {
editor?.commands.setContent(fromMarkdown(currentDocument));
setAgentState({ document: currentDocument });
}}
onConfirm={() => {
editor?.commands.setContent(fromMarkdown(agentState?.document || ""));
setCurrentDocument(agentState?.document || "");
setAgentState({ document: agentState?.document || "" });
}}
/>
),
name: "write_document",
description: `Present the proposed changes to the user for review`,
parameters: [
{
name: "document",
type: "string",
description: "The full updated document in markdown format",
},
],
renderAndWaitForResponse({ args, status, respond }) {
if (status === "executing") {
return (
<ConfirmChanges
args={args}
respond={respond}
status={status}
onReject={() => {
editor?.commands.setContent(fromMarkdown(currentDocument));
setAgentState({ document: currentDocument });
}}
onConfirm={() => {
editor?.commands.setContent(fromMarkdown(agentState?.document || ""));
setCurrentDocument(agentState?.document || "");
setAgentState({ document: agentState?.document || "" });
}}
/>
);
}
return <></>;
},
});

return (
Expand Down
28 changes: 14 additions & 14 deletions typescript-sdk/apps/dojo/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,23 @@ export const featureConfig: FeatureConfig[] = [
description: "Chat with your Copilot and call frontend tools",
tags: ["Chat", "Tools", "Streaming"],
}),
createFeatureConfig({
id: "human_in_the_loop",
name: "Human in the loop",
description: "Plan a task together and direct the Copilot to take the right steps",
tags: ["HITL", "Interactivity"],
}),
createFeatureConfig({
id: "agentic_generative_ui",
name: "Agentic Generative UI",
description: "Assign a long running task to your Copilot and see how it performs!",
tags: ["Generative ui (agent)", "Long running task"],
}),
createFeatureConfig({
id: "tool_based_generative_ui",
name: "Tool Based Generative UI",
description: "Haiku generator that uses tool based generative UI.",
tags: ["Generative ui (action)", "Tools"],
id: "human_in_the_loop",
name: "Human in the loop",
description: "Plan a task together and direct the Copilot to take the right steps",
tags: ["HITL", "Interactivity"],
}),
createFeatureConfig({
id: "predictive_state_updates",
name: "Predictive State Updates",
description: "Use collaboration to edit a document in real time with your Copilot",
tags: ["State", "Streaming", "Tools"],
}),
createFeatureConfig({
id: "shared_state",
Expand All @@ -48,10 +48,10 @@ export const featureConfig: FeatureConfig[] = [
tags: ["Agent State", "Collaborating"],
}),
createFeatureConfig({
id: "predictive_state_updates",
name: "Predictive State Updates",
description: "Use collaboration to edit a document in real time with your Copilot",
tags: ["State", "Streaming", "Tools"],
id: "tool_based_generative_ui",
name: "Tool Based Generative UI",
description: "Haiku generator that uses tool based generative UI.",
tags: ["Generative ui (action)", "Tools"],
}),
];

Expand Down
12 changes: 12 additions & 0 deletions typescript-sdk/apps/dojo/src/menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@ export const menuIntegrations: MenuIntegrationConfig[] = [
name: "Middleware Starter",
features: ["agentic_chat"],
},
{
id: "pydantic-ai",
name: "Pydantic AI",
features: [
"agentic_chat",
"human_in_the_loop",
"agentic_generative_ui",
"tool_based_generative_ui",
"shared_state",
"predictive_state_updates",
],
},
{
id: "server-starter",
name: "Server Starter",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,22 +127,9 @@ async def chat_node(state: AgentState, config: RunnableConfig):
"content": "Document written.",
"tool_call_id": tool_call_id
}

# Add confirmation tool call
confirm_tool_call = {
"role": "assistant",
"content": "",
"tool_calls": [{
"id": str(uuid.uuid4()),
"function": {
"name": "confirm_changes",
"arguments": "{}"
}
}]
}

messages = messages + [tool_response, confirm_tool_call]


messages = messages + [tool_response]

# Return Command to route to end
return Command(
goto=END,
Expand Down
4 changes: 4 additions & 0 deletions typescript-sdk/integrations/pydantic-ai/.env-sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## OpenAI API Settings
# Get your Open AI API Key by following these instructions -
# https://help.openai.com/en/articles/4936850-where-do-i-find-my-openai-api-key
OPENAI_API_KEY="sk-proj-...."
12 changes: 12 additions & 0 deletions typescript-sdk/integrations/pydantic-ai/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.turbo
.DS_Store
.git
.gitignore
.idea
.vscode
.env
__tests__
src
tsup.config.ts
tsconfig.json
jest.config.js
Loading