Skip to content

Commit bd3183f

Browse files
Merge branch 'main' into issue-35-strands-integration
2 parents c9de5ad + 07a2ab5 commit bd3183f

File tree

158 files changed

+13442
-2512
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

158 files changed

+13442
-2512
lines changed
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
name: Auto-approve community PRs
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize, reopened]
6+
7+
permissions:
8+
pull-requests: write
9+
contents: read
10+
11+
jobs:
12+
auto-approve:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v4
17+
with:
18+
fetch-depth: 0
19+
20+
- name: Fetch PR branch
21+
run: |
22+
git fetch origin ${{ github.event.pull_request.head.ref }}:${{ github.event.pull_request.head.ref }}
23+
24+
- name: Set up Node.js
25+
uses: actions/setup-node@v4
26+
with:
27+
node-version: "22"
28+
29+
- name: Auto-approve based on CODEOWNERS
30+
env:
31+
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
32+
PR_NUMBER: ${{ github.event.pull_request.number }}
33+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
34+
BASE_REF: ${{ github.event.pull_request.base.ref }}
35+
HEAD_REF: ${{ github.event.pull_request.head.ref }}
36+
run: |
37+
node << 'EOF'
38+
const { execSync } = require('child_process');
39+
const fs = require('fs');
40+
const path = require('path');
41+
42+
const prAuthor = process.env.PR_AUTHOR;
43+
const prNumber = process.env.PR_NUMBER;
44+
45+
// Get changed files
46+
const changedFiles = execSync(
47+
`git diff --name-only origin/${process.env.BASE_REF}...origin/${process.env.HEAD_REF}`,
48+
{ encoding: 'utf-8' }
49+
)
50+
.trim()
51+
.split('\n')
52+
.filter(f => f.trim());
53+
54+
console.log(`Changed files (${changedFiles.length}):`);
55+
changedFiles.forEach(f => console.log(` - ${f}`));
56+
57+
// Parse CODEOWNERS file
58+
const codeownersPath = '.github/CODEOWNERS';
59+
const codeownersContent = fs.readFileSync(codeownersPath, 'utf-8');
60+
const lines = codeownersContent.split('\n');
61+
62+
// Map of path patterns to owners (excluding root * rule)
63+
const codeownersRules = [];
64+
65+
for (const line of lines) {
66+
const trimmed = line.trim();
67+
// Skip empty lines and comments
68+
if (!trimmed || trimmed.startsWith('#')) {
69+
continue;
70+
}
71+
72+
// Skip root * line
73+
if (trimmed.startsWith('* ')) {
74+
console.log('Skipping root * rule');
75+
continue;
76+
}
77+
78+
// Parse pattern and owners
79+
const parts = trimmed.split(/\s+/);
80+
if (parts.length < 2) {
81+
continue;
82+
}
83+
84+
const pattern = parts[0];
85+
const owners = parts.slice(1).map(o => o.replace('@', ''));
86+
87+
codeownersRules.push({ pattern, owners });
88+
}
89+
90+
console.log('\nCODEOWNERS rules (excluding root):');
91+
codeownersRules.forEach(rule => {
92+
console.log(` ${rule.pattern} -> ${rule.owners.join(', ')}`);
93+
});
94+
95+
// Function to check if a file matches a CODEOWNERS pattern
96+
// CODEOWNERS patterns match:
97+
// - Exact file/directory path
98+
// - pattern/ matches everything in that directory
99+
// - pattern/** matches everything recursively in that directory
100+
function matchesPattern(file, pattern) {
101+
// Normalize paths (handle both / and \ separators)
102+
const normalizePath = (p) => p.replace(/\\/g, '/');
103+
const normalizedFile = normalizePath(file);
104+
const normalizedPattern = normalizePath(pattern);
105+
106+
// Exact match
107+
if (normalizedFile === normalizedPattern) {
108+
return true;
109+
}
110+
111+
// Pattern ends with /**: matches recursively in directory
112+
if (normalizedPattern.endsWith('/**')) {
113+
const dirPrefix = normalizedPattern.slice(0, -3);
114+
return normalizedFile.startsWith(dirPrefix + '/');
115+
}
116+
117+
// Pattern ends with /: matches everything in directory
118+
if (normalizedPattern.endsWith('/')) {
119+
const dirPrefix = normalizedPattern.slice(0, -1);
120+
return normalizedFile.startsWith(dirPrefix + '/');
121+
}
122+
123+
// Pattern is a directory prefix (matches subdirectories)
124+
if (normalizedFile.startsWith(normalizedPattern + '/')) {
125+
return true;
126+
}
127+
128+
return false;
129+
}
130+
131+
// Check each changed file
132+
// CODEOWNERS rules are evaluated top-to-bottom, first match wins
133+
const unapprovedFiles = [];
134+
135+
for (const file of changedFiles) {
136+
let matched = false;
137+
let owned = false;
138+
139+
// Find the first matching rule (CODEOWNERS uses first match semantics)
140+
for (const rule of codeownersRules) {
141+
if (matchesPattern(file, rule.pattern)) {
142+
matched = true;
143+
// First match wins in CODEOWNERS, so check ownership here
144+
owned = rule.owners.includes(prAuthor);
145+
break; // Stop at first match
146+
}
147+
}
148+
149+
// File must be matched by a non-root CODEOWNERS rule AND author must own it
150+
if (!matched || !owned) {
151+
unapprovedFiles.push(file);
152+
}
153+
}
154+
155+
// Decision
156+
if (unapprovedFiles.length === 0) {
157+
console.log(`\n✅ All changed files are owned by ${prAuthor} according to CODEOWNERS`);
158+
159+
// Check if already approved by this workflow
160+
try {
161+
const reviews = JSON.parse(
162+
execSync(`gh pr view ${prNumber} --json reviews`, { encoding: 'utf-8' })
163+
);
164+
165+
// Check if there's already an approval from GitHub Actions bot
166+
// (look for approval with the auto-approve message)
167+
const hasAutoApproval = reviews.reviews.some(
168+
review => review.state === 'APPROVED' &&
169+
review.body &&
170+
review.body.includes('Auto-approved: PR author has CODEOWNERS access')
171+
);
172+
173+
if (hasAutoApproval) {
174+
console.log('PR already auto-approved by this workflow');
175+
} else {
176+
// Approve the PR using GitHub Actions bot account
177+
execSync(
178+
`gh pr review ${prNumber} --approve --body "Auto-approved: PR author ${prAuthor} has CODEOWNERS access to all changed files (excluding root rule)"`,
179+
{ stdio: 'inherit' }
180+
);
181+
console.log(`PR approved automatically for ${prAuthor}`);
182+
}
183+
} catch (error) {
184+
console.error('Error checking/approving PR:', error.message);
185+
// Don't fail the workflow if approval fails (might already be approved, etc.)
186+
console.log('Continuing despite approval error...');
187+
}
188+
} else {
189+
console.log(`\n❌ Not auto-approved: Some files are not owned by ${prAuthor}`);
190+
console.log('Unauthorized files:');
191+
unapprovedFiles.forEach(f => console.log(` - ${f}`));
192+
}
193+
EOF

.github/workflows/dojo-e2e.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ jobs:
2828
dojo:
2929
name: dojo / ${{ matrix.suite }}
3030
runs-on: depot-ubuntu-24.04
31+
timeout-minutes: 20
3132
strategy:
3233
fail-fast: false
3334
matrix:

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,7 @@ node_modules
1313
.vscode
1414

1515
**/mastra.db*
16+
17+
.pnpm-store
18+
19+
**/.poetry-cache

CLAUDE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pnpm dev
1919
# Run linting
2020
pnpm lint
2121

22+
2223
# Run type checking
2324
pnpm check-types
2425

README.md

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ Built for simplicity and flexibility, it enables seamless integration between AI
1616

1717
<a href="https://discord.gg/Jd3FzfdJa8" target="_blank"> Join our Discord → </a> &nbsp;&nbsp;&nbsp; <a href="https://ag-ui.com/" target="_blank"> Read the Docs → </a> &nbsp;&nbsp;&nbsp; <a href="https://dojo.ag-ui.com/" target="_blank"> Go to the AG-UI Dojo → </a> &nbsp;&nbsp;&nbsp; <a href="https://x.com/CopilotKit" target="_blank"> Follow us → </a>
1818

19-
<img width="4096" height="1752" alt="Your application-AG-UI protocol" src="https://github.com/user-attachments/assets/dc58c64c-3257-490a-b827-e163475f4166" />
19+
<img width="4096" height="1752" alt="Your application-AG-UI protocol" src="https://github.com/user-attachments/assets/0ecc3a63-7947-442f-9a6e-be887d0bf245" />
20+
21+
2022

2123
## 🚀 Getting Started
2224
Create a new AG-UI application in seconds:
@@ -75,7 +77,7 @@ AG-UI is complementary to the other 2 top agentic protocols
7577
- 🧑‍💻 Human-in-the-loop collaboration
7678

7779

78-
## 🛠 Supported Frameworks
80+
## 🛠 Supported Integrations
7981

8082
AG-UI was born from CopilotKit's initial partnership with LangGraph and CrewAI - and brings the incredibly popular agent-user-interactivity infrastructure to the wider agentic ecosystem.
8183

@@ -89,20 +91,21 @@ AG-UI was born from CopilotKit's initial partnership with LangGraph and CrewAI -
8991
| Framework | Status | AG-UI Resources |
9092
| ---------- | ------- | ---------------- |
9193
| [LangGraph](https://www.langchain.com/langgraph) | ✅ Supported | ➡️ [Docs](https://docs.copilotkit.ai/langgraph/) 🎮 [Demos](https://dojo.ag-ui.com/langgraph-fastapi/feature/shared_state) |
92-
| [Google ADK](https://google.github.io/adk-docs/get-started/) | ✅ Supported | ➡️ [Docs](https://docs.copilotkit.ai/adk) 🎮 [Demos](https://dojo.ag-ui.com/adk-middleware) |
94+
| [Google ADK](https://google.github.io/adk-docs/get-started/) | ✅ Supported | ➡️ [Docs](https://docs.copilotkit.ai/adk) 🎮 [Demos](https://dojo.ag-ui.com/adk-middleware/feature/shared_state?openCopilot=true) |
9395
| [CrewAI](https://crewai.com/) | ✅ Supported | ➡️ [Docs](https://docs.copilotkit.ai/crewai-flows) 🎮 [Demos](https://dojo.ag-ui.com/crewai/feature/shared_state) |
9496

9597
#### 🧩 1st Party
9698
| Framework | Status | AG-UI Resources |
9799
| ---------- | ------- | ---------------- |
98-
| [Mastra](https://mastra.ai/) | ✅ Supported | ➡️ [Docs](https://docs.copilotkit.ai/mastra/) 🎮 [Demos](https://dojo.ag-ui.com/mastra) |
100+
| [Microsoft Agent Framework](https://azure.microsoft.com/en-us/blog/introducing-microsoft-agent-framework/) | ✅ Supported | ➡️ [Docs](https://docs.copilotkit.ai/microsoft-agent-framework) 🎮 [Demos](https://dojo.ag-ui.com/microsoft-agent-framework-dotnet/feature/shared_state) |
101+
| [Mastra](https://mastra.ai/) | ✅ Supported | ➡️ [Docs](https://docs.copilotkit.ai/mastra/) 🎮 [Demos](https://dojo.ag-ui.com/mastra/feature/tool_based_generative_ui) |
99102
| [Pydantic AI](https://github.com/pydantic/pydantic-ai) | ✅ Supported | ➡️ [Docs](https://docs.copilotkit.ai/pydantic-ai/) 🎮 [Demos](https://dojo.ag-ui.com/pydantic-ai/feature/shared_state) |
100-
| [Agno](https://github.com/agno-agi/agno) | ✅ Supported | ➡️ [Docs](https://docs.copilotkit.ai/agno/) 🎮 [Demos](https://dojo.ag-ui.com/agno) |
103+
| [Agno](https://github.com/agno-agi/agno) | ✅ Supported | ➡️ [Docs](https://docs.copilotkit.ai/agno/) 🎮 [Demos](https://dojo.ag-ui.com/agno/feature/tool_based_generative_ui) |
101104
| [LlamaIndex](https://github.com/run-llama/llama_index) | ✅ Supported | ➡️ [Docs](https://docs.copilotkit.ai/llamaindex/) 🎮 [Demos](https://dojo.ag-ui.com/llamaindex/feature/shared_state) |
102105
| [AG2](https://ag2.ai/) | ✅ Supported | ➡️ [Docs](https://docs.copilotkit.ai/ag2/) |
103106
| [AWS Bedrock Agents](https://aws.amazon.com/bedrock/agents/) | 🛠️ In Progress ||
104107
| [AWS Strands Agents](https://github.com/strands-agents/sdk-python) | 🛠️ In Progress ||
105-
| [Microsoft Agent Framework](https://azure.microsoft.com/en-us/blog/introducing-microsoft-agent-framework/) | 🛠️ In Progress ||
108+
106109

107110
#### 🌐 Community
108111
| Framework | Status | AG-UI Resources |
@@ -112,7 +115,7 @@ AG-UI was born from CopilotKit's initial partnership with LangGraph and CrewAI -
112115
| [Cloudflare Agents](https://developers.cloudflare.com/agents/) | 🛠️ In Progress ||
113116

114117

115-
## Protocols
118+
## Agent Interaction Protocols
116119

117120
| Protocols | Status | AG-UI Resources | Integrations |
118121
| ---------- | ------- | ---------------- | ------------- |
@@ -126,11 +129,11 @@ AG-UI was born from CopilotKit's initial partnership with LangGraph and CrewAI -
126129
| --- | ------- | ---------------- | ------------- |
127130
| [Kotlin]() | ✅ Supported | ➡️ [Getting Started](https://github.com/ag-ui-protocol/ag-ui/blob/main/docs/sdk/kotlin/overview.mdx) | Community |
128131
| [Golang]() | ✅ Supported | ➡️ [Getting Started](https://github.com/ag-ui-protocol/ag-ui/blob/main/docs/sdk/go/overview.mdx) | Community |
132+
| [Dart]() | ✅ Supported | ➡️ [Getting Started](https://github.com/ag-ui-protocol/ag-ui/tree/main/sdks/community/dart) | Community |
129133
| [Java]() | ✅ Supported | ➡️ [Getting Started](https://github.com/ag-ui-protocol/ag-ui/blob/main/docs/sdk/java/overview.mdx) | Community |
130134
| [Rust]() | ✅ Supported | ➡️ [Getting Started](https://github.com/ag-ui-protocol/ag-ui/tree/main/sdks/community/rust/crates/ag-ui-client) | Community |
131135
| [.NET]() | 🛠️ In Progress | ➡️ [PR](https://github.com/ag-ui-protocol/ag-ui/pull/38) | Community |
132136
| [Nim]() | 🛠️ In Progress | ➡️ [PR](https://github.com/ag-ui-protocol/ag-ui/pull/29) | Community |
133-
| [Dart]() | 🛠️ In Progress | ➡️ [PR](https://github.com/ag-ui-protocol/ag-ui/pull/432) | Community |
134137
| [Flowise]() | 🛠️ In Progress | ➡️ [GitHub Source](https://github.com/ag-ui-protocol/ag-ui/issues/367) | Community |
135138
| [Langflow]() | 🛠️ In Progress | ➡️ [GitHub Source](https://github.com/ag-ui-protocol/ag-ui/issues/366) | Community |
136139

@@ -142,7 +145,7 @@ AG-UI was born from CopilotKit's initial partnership with LangGraph and CrewAI -
142145
| [Terminal + Agent]() | ✅ Supported | ➡️ [Getting Started](https://docs.ag-ui.com/quickstart/clients) | Community |
143146
| [React Native]() | 🛠️ Help Wanted | ➡️ [GitHub Source](https://github.com/ag-ui-protocol/ag-ui/issues/510) | Community |
144147

145-
[View all supported frameworks](https://docs.ag-ui.com/introduction#supported-frameworks)
148+
[View all supported integrations](https://docs.ag-ui.com/introduction#supported-integrations)
146149

147150
## Examples
148151
### Hello World App

apps/dojo/package.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
"run-everything": "./scripts/prep-dojo-everything.js && ./scripts/run-dojo-everything.js"
1313
},
1414
"dependencies": {
15+
"@a2a-js/sdk": "0.2.5",
16+
"@ag-ui/a2a": "workspace:*",
1517
"@ag-ui/a2a-middleware": "workspace:*",
1618
"@ag-ui/adk": "workspace:*",
1719
"@ag-ui/agno": "workspace:*",
@@ -20,10 +22,10 @@
2022
"@ag-ui/llamaindex": "workspace:*",
2123
"@ag-ui/mastra": "workspace:*",
2224
"@ag-ui/middleware-starter": "workspace:*",
23-
"@ag-ui/spring-ai": "workspace:*",
2425
"@ag-ui/pydantic-ai": "workspace:*",
2526
"@ag-ui/server-starter": "workspace:*",
2627
"@ag-ui/server-starter-all-features": "workspace:*",
28+
"@ag-ui/spring-ai": "workspace:*",
2729
"@ag-ui/vercel-ai-sdk": "workspace:*",
2830
"@ag-ui/aws-strands-integration": "workspace:*",
2931
"@ai-sdk/openai": "^2.0.42",
@@ -32,6 +34,9 @@
3234
"@copilotkit/runtime": "1.10.6",
3335
"@copilotkit/runtime-client-gql": "1.10.6",
3436
"@copilotkit/shared": "1.10.6",
37+
"@copilotkitnext/react": "0.0.19-alpha.0",
38+
"@copilotkitnext/runtime": "0.0.19-alpha.0",
39+
"@copilotkitnext/agent": "0.0.19-alpha.0",
3540
"@mastra/client-js": "^0.15.2",
3641
"@mastra/core": "^0.20.2",
3742
"@mastra/dynamodb": "^0.15.6",
@@ -59,6 +64,7 @@
5964
"diff": "^7.0.0",
6065
"embla-carousel-react": "^8.6.0",
6166
"fast-json-patch": "^3.1.1",
67+
"hono": "^4.10.3",
6268
"lucide-react": "^0.477.0",
6369
"markdown-it": "^14.1.0",
6470
"markdown-it-ins": "^4.0.0",

0 commit comments

Comments
 (0)