Skip to content
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

feat: Add Cloudflare AI Gateway support #821

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from

Conversation

w3-bounty
Copy link

Cloudflare AI Gateway Integration

Relates to

Enhances model provider integration by adding support for Cloudflare AI Gateway

image

Risks

Low - Changes are isolated to model provider routing and include fallback mechanisms:

  • If gateway configuration is incomplete/invalid, falls back to direct API calls
  • Comprehensive logging added for debugging
  • No changes to core model interaction logic

Background

What does this PR do?

Adds support for routing API calls through Cloudflare AI Gateway, providing:

  • Improved latency through Cloudflare's global network
  • Detailed analytics and monitoring
  • Cost optimization through request caching
  • Enhanced security and access control

Changes Made

  1. packages/core/src/generation.ts:

    • Added getCloudflareGatewayBaseURL utility function for consistent gateway URL construction
    • Implemented gateway support for OpenAI, Anthropic, and Groq providers
    • Added comprehensive logging for debugging
    • Implemented fallback logic when gateway is disabled/misconfigured
  2. docs/docs/guides/configuration.md:

    • Added new section documenting Cloudflare AI Gateway integration
    • Included configuration instructions and environment variables
    • Listed supported providers and benefits
    • Explained URL format and fallback behavior
  3. .env.example:

    • Added Cloudflare Gateway configuration variables:
      CLOUDFLARE_GW_ENABLED=true
      CLOUDFLARE_AI_ACCOUNT_ID=your-account-id
      CLOUDFLARE_AI_GATEWAY_ID=your-gateway-id

What kind of change is this?

Feature (non-breaking change which adds functionality)

Documentation changes

Documentation has been updated in configuration.md with:

  • Gateway setup instructions
  • Configuration options
  • Benefits and supported providers

Testing

Where should a reviewer start?

  1. Review the getCloudflareGatewayBaseURL function in generation.ts
  2. Check gateway integration in provider handlers
  3. Verify documentation clarity in configuration.md

Detailed testing steps

  1. Configure Cloudflare AI Gateway:

    CLOUDFLARE_GW_ENABLED=true
    CLOUDFLARE_AI_ACCOUNT_ID=your-account-id
    CLOUDFLARE_AI_GATEWAY_ID=your-gateway-id
  2. Test with different providers:

    • Verify OpenAI requests route through gateway
    • Verify Anthropic requests route through gateway
    • Verify Groq requests route through gateway
  3. Test fallback behavior:

    • Disable gateway and verify direct API calls
    • Use invalid configuration and verify fallback
    • Check logging messages for debugging info

Expected Results

  • When gateway is properly configured:

    • Requests route through Cloudflare
    • Logs show gateway URL being used
    • Response handling remains unchanged
  • When gateway is disabled/misconfigured:

    • Fallback to direct API calls
    • Warning logs indicate configuration issues
    • Service continues to function normally

Discord username

w3_bounty

- Add Cloudflare Gateway integration for OpenAI, Anthropic, and Groq
- Implement gateway URL construction and fallback logic
- Add comprehensive logging for debugging
- Update configuration documentation with gateway setup instructions
Copy link
Collaborator

@odilitime odilitime left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems to force all openai like apis to use CF, I think it needs to be more optional. I love the utility, desperately needed but we need fallback to the old URLs before we can merge thie

@lalalune lalalune changed the base branch from main to develop December 14, 2024 09:36
@odilitime odilitime deleted the branch elizaOS:develop December 17, 2024 02:33
@odilitime odilitime closed this Dec 17, 2024
@odilitime odilitime reopened this Dec 17, 2024
@shakkernerd shakkernerd deleted the branch elizaOS:develop December 17, 2024 03:45
@odilitime odilitime reopened this Dec 17, 2024
@shakkernerd shakkernerd deleted the branch elizaOS:develop December 22, 2024 07:01
@odilitime odilitime reopened this Dec 22, 2024
Comment on lines +190 to +192
CLOUDFLARE_GW_ENABLED= # Set to true to enable Cloudflare AI Gateway
CLOUDFLARE_AI_ACCOUNT_ID= # Cloudflare AI Account ID - found in the Cloudflare Dashboard under AI Gateway
CLOUDFLARE_AI_GATEWAY_ID= # Cloudflare AI Gateway ID - found in the Cloudflare Dashboard under AI Gateway

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@w3-bounty The addition of sensitive configuration variables such as CLOUDFLARE_AI_ACCOUNT_ID and CLOUDFLARE_AI_GATEWAY_ID in the example environment file could lead to security vulnerabilities if this file is exposed. Consider using placeholders or ensuring that sensitive information is not included in example files. For instance, use CLOUDFLARE_AI_ACCOUNT_ID=YOUR_ACCOUNT_ID instead.

Comment on lines +44 to +80
function getCloudflareGatewayBaseURL(runtime: IAgentRuntime, provider: string): string | undefined {
const isCloudflareEnabled = runtime.getSetting("CLOUDFLARE_GW_ENABLED") === "true";
const cloudflareAccountId = runtime.getSetting("CLOUDFLARE_AI_ACCOUNT_ID");
const cloudflareGatewayId = runtime.getSetting("CLOUDFLARE_AI_GATEWAY_ID");

elizaLogger.debug("Cloudflare Gateway Configuration:", {
isEnabled: isCloudflareEnabled,
hasAccountId: !!cloudflareAccountId,
hasGatewayId: !!cloudflareGatewayId,
provider: provider
});

if (!isCloudflareEnabled) {
elizaLogger.debug("Cloudflare Gateway is not enabled");
return undefined;
}

if (!cloudflareAccountId) {
elizaLogger.warn("Cloudflare Gateway is enabled but CLOUDFLARE_AI_ACCOUNT_ID is not set");
return undefined;
}

if (!cloudflareGatewayId) {
elizaLogger.warn("Cloudflare Gateway is enabled but CLOUDFLARE_AI_GATEWAY_ID is not set");
return undefined;
}

const baseURL = `https://gateway.ai.cloudflare.com/v1/${cloudflareAccountId}/${cloudflareGatewayId}/${provider.toLowerCase()}`;
elizaLogger.info("Using Cloudflare Gateway:", {
provider,
baseURL,
accountId: cloudflareAccountId,
gatewayId: cloudflareGatewayId
});

return baseURL;
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@w3-bounty The function getCloudflareGatewayBaseURL does not handle potential errors when retrieving settings from runtime. If the runtime is not properly configured or if there are issues accessing the settings, it could lead to unexpected behavior. Consider adding error handling to manage these scenarios gracefully.

Comment on lines +188 to +191
const baseURL = getCloudflareGatewayBaseURL(runtime, 'openai') || endpoint;
elizaLogger.debug("OpenAI baseURL result:", { baseURL });

const openai = createOpenAI({ apiKey, baseURL });

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@w3-bounty The baseURL is derived from getCloudflareGatewayBaseURL, which can return undefined. If this happens, the createOpenAI function will be called with an undefined baseURL, potentially leading to runtime errors. Ensure that a valid baseURL is always provided or handle the case where it is undefined.

Comment on lines +231 to +234
const baseURL = getCloudflareGatewayBaseURL(runtime, 'anthropic');
elizaLogger.debug("Anthropic baseURL result:", { baseURL });

const anthropic = createAnthropic({ apiKey, baseURL });

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@w3-bounty Similar to the previous comment, the baseURL for the createAnthropic function can also be undefined. This could lead to issues when the function is called. Implement a check to ensure that baseURL is valid before proceeding.

Comment on lines +301 to +304
const baseURL = getCloudflareGatewayBaseURL(runtime, 'groq');
elizaLogger.debug("Groq baseURL result:", { baseURL });

const groq = createGroq({ apiKey, baseURL });

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@w3-bounty Again, the baseURL for the createGroq function can be undefined. This inconsistency in handling undefined values across different model initializations can lead to bugs. Ensure that a valid baseURL is always passed to the create functions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants