Skip to content

Commit

Permalink
add ai gateway
Browse files Browse the repository at this point in the history
  • Loading branch information
0xKoda committed Jan 18, 2025
1 parent 38d42fb commit 6bb1600
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 48 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ id = "" # Add your KV namespace ID here
preview_id = "" # Add your preview ID here
```

## AI Gateway
This is an optional feature that can be set inside your wrangler.toml with `USE_CF_GATEWAY = true # Toggle for Cloudflare AI Gateway`

Cloudflare AI Gateway provides centralized visibility and control for your AI applications. Enable AI gateway in your Cloudflare dashboard, create a gateway ID, and add the variables to the wrangler.toml. This will enable features like cost tracking across OpenRouter calls, observability, caching and evals.

## Features

- Multi-platform support (Twitter, Telegram, Farcaster)
Expand Down Expand Up @@ -129,6 +134,9 @@ Configure platform settings in `wrangler.toml`:
ENABLE_FARCASTER = true # Enable/disable Farcaster
ENABLE_TELEGRAM = true # Enable/disable Telegram
ENABLE_TWITTER = false # Enable Twitter API client
USE_CF_GATEWAY = true # Optional: Toggle for Cloudflare AI Gateway
CF_ACCOUNT_ID = "" # Optional: Cloudflare Account ID for AI gateway
CF_GATEWAY_ID = "" # Optional: Cloudflare Gateway ID
```

## Creating Scheduled Jobs
Expand Down
15 changes: 10 additions & 5 deletions src/actions/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import { Action } from './base';
import type { Env } from '../core/types';

// Register actions here from /actions
// import { FinancialAnalysisAction } from './financial';

// Register action
const actions: Record<string, Action> = {
// financial: new FinancialAnalysisAction()
};
let actions: Record<string, Action>;

export function loadActions(): Record<string, Action> {
export function loadActions(env: Env): Record<string, Action> {
if (!actions) {
actions = {
// add actions here
//financial: new FinancialAnalysisAction(),
};
}
return actions;
}
86 changes: 48 additions & 38 deletions src/core/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ export class Agent {

constructor(env: Env) {
this.env = env;
this.memory = new Memory({ agent_memory: env.agent_memory });
this.memory = new Memory(env);
this.character = character;
this.actions = loadActions();
this.actions = loadActions(env);

// Initialize actions with env
Object.values(this.actions).forEach(action => action.setEnv(env));
Expand Down Expand Up @@ -93,7 +93,7 @@ export class Agent {

updateEnv(env: Env) {
this.env = env;
this.memory = new Memory({ agent_memory: env.agent_memory });
this.memory = new Memory(env);

// Update actions with new env
Object.values(this.actions).forEach(action => action.setEnv(env));
Expand Down Expand Up @@ -278,11 +278,10 @@ export class Agent {
}

async publishFarcasterCast(text: string): Promise<void> {
if (this.farcaster) {
await this.farcaster.publishCast(text, null);
} else {
throw new Error('Farcaster client not initialized');
if (!this.farcaster) {
this.farcaster = await this.initializeFarcasterClient();
}
await this.farcaster.publishCast(text, null);
}

private getTwitterClient(): TwitterClient {
Expand Down Expand Up @@ -331,38 +330,61 @@ export class Agent {
return response;
}

// Make public for use by scheduled jobs
async generateLLMResponse(messages: any[], platform: string): Promise<string> {
Logger.debug('Generating LLM response:', { messages });

// Modify the last message (user prompt) to include character limit
if (messages.length > 0 && messages[messages.length - 1].role === 'user') {
const lastMessage = messages[messages.length - 1];
switch (platform) {
case 'twitter':
lastMessage.content += '\n\nIMPORTANT: Your response MUST be under 250 characters.';
break;
case 'farcaster':
lastMessage.content += '\n\nIMPORTANT: Your response MUST be under 500 characters.';
break;
}
// Configure response based on platform
let maxTokens = 800; // Default for standard responses
let characterLimit = 2000;

switch (platform) {
case 'twitter':
case 'farcaster':
case 'short':
maxTokens = 250;
characterLimit = 250;
// Add character limit reminder for social posts
if (messages.length > 0 && messages[messages.length - 1].role === 'user') {
messages[messages.length - 1].content += '\n\nIMPORTANT: Your response MUST be under 250 characters. No hashtags or emojis.';
}
break;
case 'telegram':
maxTokens = 300; // Short telegram updates
characterLimit = 300;
break;
case 'telegram-sara': // Special case for SARA's scheduled tweet
case 'long':
maxTokens = 1000;
characterLimit = 4096;
break;
case 'thesis':
maxTokens = 1000;
characterLimit = 4000;
break;
}

const apiKey = this.env.OPENROUTER_API_KEY;
if (!apiKey) {
throw new Error('Missing OpenRouter API key');
}

const response = await fetch('https://openrouter.ai/api/v1/chat/completions', {
const useCfGateway = this.env.USE_CF_GATEWAY === 'true';
const baseUrl = useCfGateway
? `https://gateway.ai.cloudflare.com/v1/${this.env.CF_ACCOUNT_ID}/${this.env.CF_GATEWAY_ID}/openrouter/v1/chat/completions`
: 'https://openrouter.ai/api/v1/chat/completions';

console.log(`Using URL for LLM requests: ${baseUrl}`);

const response = await fetch(baseUrl, {
method: 'POST',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: this.env.LLM_MODEL || 'openai/gpt-3.5-turbo',
model: this.env.LLM_MODEL || 'openai/gpt-4o-mini',
messages,
max_tokens: 400,
max_tokens: maxTokens,
temperature: 0.7
})
});
Expand All @@ -372,23 +394,11 @@ export class Agent {
}

const data = await response.json();
const content = data.choices[0].message.content;
const content = data.choices[0].message.content.trim();
Logger.info(`Generated ${platform} response with ${maxTokens} max tokens, content length: ${content.length}`);

// Apply platform-specific character limits
switch (platform) {
case 'telegram':
// Telegram has a 4096 character limit
return content.length > 2000 ? content.slice(0, 1997) + '...' : content;
case 'twitter':
// Twitter has a 280 character limit
return content.length > 280 ? content.slice(0, 277) + '...' : content;
case 'farcaster':
// Farcaster has a 700 character limit
return content.length > 700 ? content.slice(0, 697) + '...' : content;
default:
Logger.warn('Unknown platform, no character limit applied:', platform);
return content;
}
// Apply character limits
return content.length > characterLimit ? content.slice(0, characterLimit - 3) + '...' : content;
}

private async getConversationId(message: Message): Promise<string> {
Expand Down
15 changes: 11 additions & 4 deletions src/core/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@

export interface Env {
// KV Namespace for agent memory
agent_memory?: KVNamespace;
KV: KVNamespace;
agent_memory: KVNamespace;

// Feature flags
ENABLE_TELEGRAM: string | boolean;
ENABLE_FARCASTER: string | boolean;
ENABLE_TWITTER: string | boolean;
ENABLE_TELEGRAM: boolean | string;
ENABLE_FARCASTER: boolean | string;
ENABLE_TWITTER: boolean | string;

LLM_MODEL: string;

// Telegram configuration
Expand All @@ -39,6 +41,11 @@ export interface Env {

// OpenRouter configuration
OPENROUTER_API_KEY: string;

// Cloudflare AI Gateway configuration
USE_CF_GATEWAY?: string;
CF_ACCOUNT_ID?: string;
CF_GATEWAY_ID?: string;
}

export interface Author {
Expand Down
5 changes: 4 additions & 1 deletion wrangler.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ rules = [
ENABLE_TELEGRAM = true
ENABLE_FARCASTER = true
ENABLE_TWITTER = false # Twitter API
LLM_MODEL = "openai/gpt-3.5-turbo" # Model to use for LLM responses
LLM_MODEL = "openai/gpt-4o-mini" # Model to use for LLM responses
USE_CF_GATEWAY = true # Optional: Toggle for Cloudflare AI Gateway
CF_ACCOUNT_ID = "" # Optional: Cloudflare Account ID for AI gateway
CF_GATEWAY_ID = "" # Optional: Cloudflare Gateway ID

# Cron Triggers
[triggers]
Expand Down

0 comments on commit 6bb1600

Please sign in to comment.