feat(developer): add hybrid iframe integration for developer tools

Replace placeholder pages with ToolEmbed component that embeds
LangGraph, LangFlow, and Langfuse in iframes when configured, or
shows "Not Configured" placeholders when URLs are empty. Add
ServiceUrlsContext for passing service URLs through Dioxus context.

Add docker-compose services for local development: LangFlow,
LangGraph (trial), Langfuse with full dependency stack (Postgres,
ClickHouse, Redis, MinIO).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Sharang Parnerkar
2026-02-25 17:49:56 +01:00
parent d9401d4be5
commit a24ea984b1
21 changed files with 467 additions and 52 deletions

View File

@@ -11,23 +11,50 @@ test.describe("Developer section", () => {
await expect(nav.locator("a", { hasText: "Analytics" })).toBeVisible();
});
test("agents page shows Coming Soon badge", async ({ page }) => {
test("agents page shows Not Configured when URL is empty", async ({
page,
}) => {
await page.goto("/developer/agents");
await page.waitForSelector(".placeholder-page", { timeout: 15_000 });
await expect(page.locator(".placeholder-badge")).toContainText(
"Coming Soon"
"Not Configured"
);
await expect(page.locator("h2")).toContainText("Agent Builder");
});
test("analytics page loads via sub-nav", async ({ page }) => {
test("analytics page shows Not Configured when URL is empty", async ({
page,
}) => {
await page.goto("/developer/analytics");
await page.waitForSelector(".placeholder-page", { timeout: 15_000 });
await expect(page.locator("h2")).toContainText("Analytics");
await expect(
page.locator("h2", { hasText: "Analytics" })
).toBeVisible();
await expect(page.locator(".placeholder-badge")).toContainText(
"Coming Soon"
"Not Configured"
);
});
test("agents page shows iframe when URL is configured", async ({
page,
}) => {
// This test only runs meaningfully when LANGGRAPH_URL is set in the
// environment. When empty, the placeholder is shown instead.
await page.goto("/developer/agents");
await page.waitForTimeout(2000);
const iframe = page.locator(".tool-embed-iframe");
const placeholder = page.locator(".placeholder-badge");
if (await placeholder.isVisible()) {
await expect(placeholder).toContainText("Not Configured");
} else {
await expect(iframe).toBeVisible();
await expect(
page.locator(".tool-embed-popout-btn")
).toBeVisible();
}
});
});