diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a4e534..9584c71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ The format is intentionally lightweight and human-readable. Group entries by rel ### Added - Added richer client usage reporting in `GET /api/stats` and the dashboard, including per-client tokens, failures, success rate, and aggregate client totals +- Added a second wave of AI-native starter templates for Agno, Semantic Kernel, Haystack, Mastra, and Google ADK ### Changed diff --git a/README.md b/README.md index c80ef09..f0d09d6 100644 --- a/README.md +++ b/README.md @@ -172,6 +172,7 @@ Start here for the deeper deployment details: - [Onboarding](./docs/ONBOARDING.md) - [Examples](./docs/examples) - [First-wave AI-native starters](./docs/AI-NATIVE-MATRIX.md#first-wave-template-set-for-v110) +- [Second-wave AI-native starters](./docs/AI-NATIVE-MATRIX.md#second-wave-template-set) - [Security review for `v1.0.0`](./docs/SECURITY-REVIEW-v1.0.0.md) - [Publishing](./docs/PUBLISHING.md) - [Troubleshooting](./docs/TROUBLESHOOTING.md) diff --git a/docs/INTEGRATIONS.md b/docs/INTEGRATIONS.md index a929358..b919796 100644 --- a/docs/INTEGRATIONS.md +++ b/docs/INTEGRATIONS.md @@ -154,6 +154,40 @@ These starters are intentionally small: - use client profiles only when the framework traffic really needs distinct routing behavior - validate with `POST /api/route` and `GET /api/traces` before adding policies or hooks +## Second-wave framework starters + +The second wave keeps the same integration discipline while extending FoundryGate coverage into more active agent ecosystems. + +### Agno + +- starter: [examples/agno-foundrygate.env.example](./examples/agno-foundrygate.env.example) +- recommended header: `X-FoundryGate-Client: agno` +- recommended profile name: `agno` + +### Semantic Kernel + +- starter: [examples/semantic-kernel-foundrygate.env.example](./examples/semantic-kernel-foundrygate.env.example) +- recommended header: `X-FoundryGate-Client: semantic-kernel` +- recommended profile name: `semantic-kernel` + +### Haystack + +- starter: [examples/haystack-foundrygate.env.example](./examples/haystack-foundrygate.env.example) +- recommended header: `X-FoundryGate-Client: haystack` +- recommended profile name: `haystack` + +### Mastra + +- starter: [examples/mastra-foundrygate.env.example](./examples/mastra-foundrygate.env.example) +- recommended header: `X-FoundryGate-Client: mastra` +- recommended profile name: `mastra` + +### Google ADK + +- starter: [examples/google-adk-foundrygate.env.example](./examples/google-adk-foundrygate.env.example) +- recommended header: `X-FoundryGate-Client: google-adk` +- recommended profile name: `google-adk` + ## Provider onboarding When onboarding a new provider: diff --git a/docs/ONBOARDING.md b/docs/ONBOARDING.md index 55440a0..7005ea9 100644 --- a/docs/ONBOARDING.md +++ b/docs/ONBOARDING.md @@ -155,6 +155,11 @@ Starter files: - [examples/ship-faster-foundrygate.env.example](./examples/ship-faster-foundrygate.env.example) - [examples/langchain-foundrygate.env.example](./examples/langchain-foundrygate.env.example) - [examples/langgraph-foundrygate.env.example](./examples/langgraph-foundrygate.env.example) +- [examples/agno-foundrygate.env.example](./examples/agno-foundrygate.env.example) +- [examples/semantic-kernel-foundrygate.env.example](./examples/semantic-kernel-foundrygate.env.example) +- [examples/haystack-foundrygate.env.example](./examples/haystack-foundrygate.env.example) +- [examples/mastra-foundrygate.env.example](./examples/mastra-foundrygate.env.example) +- [examples/google-adk-foundrygate.env.example](./examples/google-adk-foundrygate.env.example) ### 3b. First-wave framework starters @@ -168,6 +173,18 @@ The first post-`1.0` framework wave keeps every client on the same OpenAI-compat Use the starter env files above first, then add explicit profile rules only if one framework needs different locality, provider, or cost behavior. +### 3c. Second-wave framework starters + +The second post-`1.0` starter wave extends the same pattern to: + +- `Agno` -> `X-FoundryGate-Client: agno` +- `Semantic Kernel` -> `X-FoundryGate-Client: semantic-kernel` +- `Haystack` -> `X-FoundryGate-Client: haystack` +- `Mastra` -> `X-FoundryGate-Client: mastra` +- `Google ADK` -> `X-FoundryGate-Client: google-adk` + +Keep these on the shared OpenAI-compatible path first. The right time to split them into more specialized profiles is after traces and stats show a real difference in locality, fallback, or cost behavior. + ### 4. Add request hooks only if needed Keep hooks opt-in and narrow. Good uses are: diff --git a/docs/examples/agno-foundrygate.env.example b/docs/examples/agno-foundrygate.env.example new file mode 100644 index 0000000..d7dc448 --- /dev/null +++ b/docs/examples/agno-foundrygate.env.example @@ -0,0 +1,6 @@ +# Example FoundryGate environment for Agno. + +export OPENAI_BASE_URL="http://127.0.0.1:8090/v1" +export OPENAI_API_KEY="local" +export FOUNDRYGATE_CLIENT_HEADER="X-FoundryGate-Client: agno" + diff --git a/docs/examples/google-adk-foundrygate.env.example b/docs/examples/google-adk-foundrygate.env.example new file mode 100644 index 0000000..ca39b8f --- /dev/null +++ b/docs/examples/google-adk-foundrygate.env.example @@ -0,0 +1,6 @@ +# Example FoundryGate environment for Google ADK. + +export OPENAI_BASE_URL="http://127.0.0.1:8090/v1" +export OPENAI_API_KEY="local" +export FOUNDRYGATE_CLIENT_HEADER="X-FoundryGate-Client: google-adk" + diff --git a/docs/examples/haystack-foundrygate.env.example b/docs/examples/haystack-foundrygate.env.example new file mode 100644 index 0000000..f0b65c7 --- /dev/null +++ b/docs/examples/haystack-foundrygate.env.example @@ -0,0 +1,6 @@ +# Example FoundryGate environment for Haystack. + +export OPENAI_BASE_URL="http://127.0.0.1:8090/v1" +export OPENAI_API_KEY="local" +export FOUNDRYGATE_CLIENT_HEADER="X-FoundryGate-Client: haystack" + diff --git a/docs/examples/mastra-foundrygate.env.example b/docs/examples/mastra-foundrygate.env.example new file mode 100644 index 0000000..e61d499 --- /dev/null +++ b/docs/examples/mastra-foundrygate.env.example @@ -0,0 +1,6 @@ +# Example FoundryGate environment for Mastra. + +export OPENAI_BASE_URL="http://127.0.0.1:8090/v1" +export OPENAI_API_KEY="local" +export FOUNDRYGATE_CLIENT_HEADER="X-FoundryGate-Client: mastra" + diff --git a/docs/examples/semantic-kernel-foundrygate.env.example b/docs/examples/semantic-kernel-foundrygate.env.example new file mode 100644 index 0000000..79fde23 --- /dev/null +++ b/docs/examples/semantic-kernel-foundrygate.env.example @@ -0,0 +1,6 @@ +# Example FoundryGate environment for Semantic Kernel. + +export OPENAI_BASE_URL="http://127.0.0.1:8090/v1" +export OPENAI_API_KEY="local" +export FOUNDRYGATE_CLIENT_HEADER="X-FoundryGate-Client: semantic-kernel" + diff --git a/foundrygate/onboarding.py b/foundrygate/onboarding.py index 3e826cc..c2d37af 100644 --- a/foundrygate/onboarding.py +++ b/foundrygate/onboarding.py @@ -420,6 +420,89 @@ def build_onboarding_report( " locality or cost boundaries.", ], }, + "agno": { + "recommended": "agno" in profile_names, + "header": "X-FoundryGate-Client: agno", + "profile": "agno", + "snippet": [ + "export OPENAI_BASE_URL=http://127.0.0.1:8090/v1", + "export OPENAI_API_KEY=local", + ], + "notes": [ + "Keep Agno on the shared OpenAI-compatible path first.", + ( + "Split profiles only when one agent family needs different cost " + "or locality defaults." + ), + ], + }, + "semantic-kernel": { + "recommended": "semantic-kernel" in profile_names, + "header": "X-FoundryGate-Client: semantic-kernel", + "profile": "semantic-kernel", + "snippet": [ + "export OPENAI_BASE_URL=http://127.0.0.1:8090/v1", + "export OPENAI_API_KEY=local", + ], + "notes": [ + ( + "Use one stable client tag for kernel traffic before adding " + "skill-specific routing." + ), + "Validate tool-heavy paths with route previews before adding custom hook hints.", + ], + }, + "haystack": { + "recommended": "haystack" in profile_names, + "header": "X-FoundryGate-Client: haystack", + "profile": "haystack", + "snippet": [ + "export OPENAI_BASE_URL=http://127.0.0.1:8090/v1", + "export OPENAI_API_KEY=local", + ], + "notes": [ + ( + "Treat Haystack as another OpenAI-compatible client unless a " + "pipeline-specific gap appears." + ), + ( + "Keep retrieval and generation traffic together until a real " + "routing split is needed." + ), + ], + }, + "mastra": { + "recommended": "mastra" in profile_names, + "header": "X-FoundryGate-Client: mastra", + "profile": "mastra", + "snippet": [ + "export OPENAI_BASE_URL=http://127.0.0.1:8090/v1", + "export OPENAI_API_KEY=local", + ], + "notes": [ + "Keep Mastra on one shared gateway path first.", + ( + "Only add dedicated policies when workflow classes need stronger " + "provider separation." + ), + ], + }, + "google-adk": { + "recommended": "google-adk" in profile_names, + "header": "X-FoundryGate-Client: google-adk", + "profile": "google-adk", + "snippet": [ + "export OPENAI_BASE_URL=http://127.0.0.1:8090/v1", + "export OPENAI_API_KEY=local", + ], + "notes": [ + "Keep Google ADK traffic on the common gateway path for provider consistency.", + ( + "Use a dedicated profile only when ADK workloads need different " + "fallback or locality rules." + ), + ], + }, } return {