Skip to content

Commit da89d65

Browse files
Merge branch 'ag-ui-protocol:main' into main
2 parents 428a604 + cfd4a5d commit da89d65

File tree

240 files changed

+13686
-3678
lines changed

Some content is hidden

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

240 files changed

+13686
-3678
lines changed

.github/CODEOWNERS

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
* @ag-ui-protocol/copilotkit
22

3-
sdks/community/java @ag-ui-protocol/copilotkit @pascalwilbrink
4-
docs/sdk/java @ag-ui-protocol/copilotkit @pascalwilbrink
3+
sdks/community/java @pascalwilbrink
4+
docs/sdk/java @pascalwilbrink
55

6-
sdks/community/kotlin @ag-ui-protocol/copilotkit @contextablemark
7-
docs/sdk/kotlin @ag-ui-protocol/copilotkit @contextablemark
6+
sdks/community/kotlin @contextablemark
7+
docs/sdk/kotlin @contextablemark
88

9-
sdks/community/go @ag-ui-protocol/copilotkit @mattsp1290
10-
docs/sdk/go @ag-ui-protocol/copilotkit @mattsp1290
9+
sdks/community/go @mattsp1290
10+
docs/sdk/go @mattsp1290
1111

12-
sdks/community/dart @ag-ui-protocol/copilotkit @mattsp1290
13-
docs/sdk/dart @ag-ui-protocol/copilotkit @mattsp1290
12+
sdks/community/dart @mattsp1290
13+
docs/sdk/dart @mattsp1290
1414

15-
integrations/adk-middleware @ag-ui-protocol/copilotkit @contextablemark
15+
integrations/adk-middleware @contextablemark
1616

17-
integrations/agent-spec @ag-ui-protocol/copilotkit @sonleoracle
17+
integrations/agent-spec @sonleoracle

.github/workflows/dojo-e2e.yml

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
name: e2e
22

33
on:
4+
workflow_dispatch:
45
push:
56
branches: [main]
67
paths:
@@ -165,34 +166,26 @@ jobs:
165166
restore-keys: |
166167
${{ runner.os }}-pnpm-store-
167168
168-
# Cache Python tool caches and virtualenvs; restore only to avoid long saves
169-
- name: Cache Python dependencies (restore-only)
170-
id: cache-python
171-
uses: actions/cache/restore@v4
169+
- name: Cache Python dependencies
170+
uses: actions/cache@v4
172171
with:
173172
path: |
174173
~/.cache/pip
175174
~/.cache/pypoetry
176175
~/.cache/uv
177176
**/.venv
178-
key: ${{ runner.os }}-pydeps-${{ hashFiles('**/poetry.lock', '**/pyproject.toml') }}
177+
key: ${{ runner.os }}-pydeps-${{ matrix.suite }}-${{ hashFiles('**/poetry.lock', '**/pyproject.toml') }}
179178
restore-keys: |
179+
${{ runner.os }}-pydeps-${{ matrix.suite }}-
180180
${{ runner.os }}-pydeps-
181181
182-
- name: Cache Nx build output
183-
uses: actions/cache@v4
184-
with:
185-
path: .nx/cache
186-
key: ${{ runner.os }}-nx-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }}
187-
restore-keys: |
188-
${{ runner.os }}-nx-${{ hashFiles('**/pnpm-lock.yaml') }}-
189-
${{ runner.os }}-nx-
182+
190183
191184
- name: Cache Next.js build
192185
uses: actions/cache@v4
193186
with:
194187
path: ${{ github.workspace }}/apps/dojo/.next/cache
195-
key: ${{ runner.os }}-nextjs-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }}
188+
key: ${{ runner.os }}-nextjs-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ hashFiles('apps/dojo/src/**/*.ts', 'apps/dojo/src/**/*.tsx', 'apps/dojo/src/**/*.js', 'apps/dojo/src/**/*.jsx') }}
196189
restore-keys: |
197190
${{ runner.os }}-nextjs-${{ hashFiles('**/pnpm-lock.yaml') }}-
198191
@@ -213,11 +206,28 @@ jobs:
213206
working-directory: apps/dojo
214207
if: ${{ join(matrix.services, ',') != '' }}
215208
run: node ./scripts/prep-dojo-everything.js --only ${{ join(matrix.services, ',') }}
209+
- name: Cache Playwright browsers
210+
id: cache-playwright
211+
uses: actions/cache@v4
212+
with:
213+
path: ~/.cache/ms-playwright
214+
key: ${{ runner.os }}-playwright-${{ hashFiles('apps/dojo/e2e/package.json') }}
215+
restore-keys: |
216+
${{ runner.os }}-playwright-
216217
217218
- name: Install e2e dependencies
218219
working-directory: apps/dojo/e2e
219-
run: |
220-
pnpm install
220+
run: pnpm install --ignore-scripts
221+
222+
- name: Install Playwright browsers
223+
working-directory: apps/dojo/e2e
224+
if: steps.cache-playwright.outputs.cache-hit != 'true'
225+
run: pnpm exec playwright install --with-deps chromium
226+
227+
- name: Install Playwright system dependencies
228+
working-directory: apps/dojo/e2e
229+
if: steps.cache-playwright.outputs.cache-hit == 'true'
230+
run: pnpm exec playwright install-deps chromium
221231

222232
- name: write langgraph env files
223233
working-directory: integrations/langgraph
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: unit
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
- "integrations/community/genkit/go/**"
8+
- ".github/workflows/unit-genkit-go.yml"
9+
pull_request:
10+
branches: [main]
11+
paths:
12+
- "integrations/community/genkit/go/**"
13+
- ".github/workflows/unit-genkit-go.yml"
14+
15+
jobs:
16+
go-genkit:
17+
name: Go Genkit Integration Tests
18+
runs-on: ubuntu-latest
19+
20+
steps:
21+
- name: Checkout code
22+
uses: actions/checkout@v4
23+
24+
- name: Set up Go
25+
uses: actions/setup-go@v5
26+
with:
27+
go-version: "1.25.0"
28+
29+
- name: Setup Go module cache
30+
uses: actions/cache@v4
31+
with:
32+
path: |
33+
~/go/pkg/mod
34+
~/.cache/go-build
35+
key: ${{ runner.os }}-go-genkit-${{ hashFiles('integrations/community/genkit/go/genkit/go.sum') }}
36+
restore-keys: |
37+
${{ runner.os }}-go-genkit-
38+
39+
- name: Download dependencies
40+
working-directory: integrations/community/genkit/go/genkit
41+
run: go mod download
42+
43+
- name: Run tests
44+
working-directory: integrations/community/genkit/go/genkit
45+
run: go test ./... -v

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
**/.claude/settings.local.json
2+
.claude/worktrees
23

34
# Test coverage
45
coverage/
@@ -21,4 +22,6 @@ node_modules
2122
.pnpm-store
2223

2324
**/.poetry-cache
24-
*.egg-info
25+
*.egg-info
26+
27+
**/python/**/__pycache__/

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ AG-UI was born from CopilotKit's initial **partnership** with LangGraph and Crew
106106
| [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) |
107107
| [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) |
108108
| [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) |
109-
| [AG2](https://ag2.ai/) | ✅ Supported | ➡️ [Docs](https://docs.copilotkit.ai/ag2/) |
109+
| [AG2](https://ag2.ai/) | ✅ Supported | ➡️ [Docs](https://docs.copilotkit.ai/ag2/) 🎮 [Demos](https://dojo.ag-ui.com/ag2/feature/shared_state) |
110110
| [AWS Bedrock Agents](https://aws.amazon.com/bedrock/agents/) | 🛠️ In Progress ||
111111

112112

apps/client-cli-example/src/agent.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,21 @@ export const agent = new MastraAgent({
1212
name: "AG-UI Agent",
1313
instructions: `
1414
You are a helpful assistant that runs a CLI application.
15-
15+
1616
When helping users get weather details for specific locations, respond:
1717
- Always ask for a location if none is provided.
1818
- If the location name isn’t in English, please translate it
1919
- If giving a location with multiple parts (e.g. "New York, NY"), use the most relevant part (e.g. "New York")
2020
- Include relevant details like humidity, wind conditions, and precipitation
2121
- Keep responses concise but informative
22-
22+
2323
Use the weatherTool to fetch current weather data.
2424
2525
When helping users browse the web, always use a full URL, for example: "https://www.google.com"
2626
Use the browserTool to browse the web.
2727
2828
`,
29-
model: "openai/gpt-4o-mini",
29+
model: "openai/gpt-4.1-mini",
3030
tools: { weatherTool, browserTool },
3131
memory: new Memory({
3232
storage: new LibSQLStore({

apps/dojo/e2e/clean-reporter.js

Lines changed: 74 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -25,47 +25,81 @@ class CleanReporter {
2525
.trim();
2626

2727
if (result.status === "passed") {
28-
logStamp(`✅ ${cleanSuite}: ${testName}`);
29-
} else if (result.status === "failed") {
30-
logStamp(`❌ ${cleanSuite}: ${testName}`);
31-
32-
// Extract the most relevant error info
33-
const error = result.error || result.errors?.[0];
34-
if (error) {
35-
let errorMsg = error.message || "Unknown error";
36-
37-
// Clean up common error patterns to make them more readable
38-
if (errorMsg.includes("None of the expected patterns matched")) {
39-
const patterns = errorMsg.match(/patterns matched[^:]*: ([^`]+)/);
40-
errorMsg = `AI response timeout - Expected: ${
41-
patterns?.[1] || "AI response"
42-
}`;
43-
} else if (
44-
errorMsg.includes("Timed out") &&
45-
errorMsg.includes("toBeVisible")
46-
) {
47-
const element = errorMsg.match(/locator\('([^']+)'\)/);
48-
errorMsg = `Element not found: ${element?.[1] || "UI element"}`;
49-
} else if (errorMsg.includes("toBeGreaterThan")) {
50-
errorMsg = "Expected content not generated (count was 0)";
51-
}
52-
53-
// Show just the key error info
54-
console.log(` 💥 ${errorMsg.split("\n")[0]}`);
55-
56-
// If it's an AI/API issue, make it clear
57-
if (
58-
errorMsg.includes("AI") ||
59-
errorMsg.includes("patterns") ||
60-
errorMsg.includes("timeout")
61-
) {
62-
console.log(` 🔑 Likely cause: AI service down or API key issue`);
63-
}
28+
logStamp(`✅ PASS ${cleanSuite}: ${testName}`);
29+
return;
30+
}
31+
32+
if (result.status === "skipped") {
33+
console.log(`⚠️ SKIP ${cleanSuite}: ${testName} (skipped)`);
34+
return;
35+
}
36+
37+
// Handle all failure modes: "failed", "timedOut", "interrupted"
38+
const icon = result.status === "timedOut" ? "⏰ TIMEOUT" : "❌ FAIL";
39+
logStamp(`${icon} ${cleanSuite}: ${testName}`);
40+
41+
// Extract the most relevant error info
42+
const error = result.error || result.errors?.[0];
43+
if (error) {
44+
let errorMsg = error.message || "Unknown error";
45+
46+
// Clean up common error patterns to make them more readable
47+
if (errorMsg.includes("None of the expected patterns matched")) {
48+
const patterns = errorMsg.match(/patterns matched[^:]*: ([^`]+)/);
49+
errorMsg = `AI response timeout - Expected: ${
50+
patterns?.[1] || "AI response"
51+
}`;
52+
} else if (
53+
errorMsg.includes("Timed out") &&
54+
errorMsg.includes("toBeVisible")
55+
) {
56+
const element = errorMsg.match(/locator\('([^']+)'\)/);
57+
errorMsg = `Element not found: ${element?.[1] || "UI element"}`;
58+
} else if (errorMsg.includes("Test timeout of")) {
59+
errorMsg = errorMsg.split("\n")[0];
60+
} else if (errorMsg.includes("toBeGreaterThan")) {
61+
errorMsg = "Expected content not generated (count was 0)";
62+
}
63+
64+
// Show just the key error info
65+
console.log(`💥 ERROR: ${errorMsg.split("\n")[0]}`);
66+
67+
// If it's an AI/API issue, make it clear
68+
if (
69+
errorMsg.includes("AI") ||
70+
errorMsg.includes("patterns") ||
71+
errorMsg.includes("timeout")
72+
) {
73+
console.log(` HINT: Likely cause: AI service down or API key issue`);
74+
}
75+
}
76+
77+
// Surface diagnostic output from test-isolation-helper on failure.
78+
// This includes AI State Dump, NetworkError, PageError, and
79+
// BrowserConsole lines that would otherwise be hidden by this reporter.
80+
const diagnosticPrefixes = [
81+
"[AI State Dump]",
82+
"[NetworkError]",
83+
"[PageError]",
84+
"[BrowserConsole]",
85+
"[Test Cleanup]",
86+
"[User]",
87+
"[Assistant]",
88+
];
89+
const stdout = (result.stdout || [])
90+
.map((chunk) => (typeof chunk === "string" ? chunk : chunk.toString("utf-8")))
91+
.join("");
92+
const diagnosticLines = stdout
93+
.split("\n")
94+
.filter((line) => diagnosticPrefixes.some((p) => line.includes(p)));
95+
if (diagnosticLines.length > 0) {
96+
console.log(" --- Diagnostics ---");
97+
for (const line of diagnosticLines) {
98+
console.log(` ${line.trim()}`);
6499
}
65-
console.log(""); // Extra spacing after failures
66-
} else if (result.status === "skipped") {
67-
console.log(`⏭ ${cleanSuite}: ${testName} (skipped)`);
68100
}
101+
102+
console.log(""); // Extra spacing after failures
69103
}
70104

71105
onEnd(result) {
@@ -75,7 +109,7 @@ class CleanReporter {
75109

76110
if (!process.env.CI) {
77111
console.log(
78-
`Run 'pnpm exec playwright show-report' for detailed HTML report`
112+
`Run 'pnpm exec playwright show-report' for detailed HTML report`
79113
);
80114
}
81115

0 commit comments

Comments
 (0)