Skip to content

Commit

Permalink
Enable passing env variables such as APIKEYs trought the team configu…
Browse files Browse the repository at this point in the history
…ration.
  • Loading branch information
darielnoel committed Jul 24, 2024
1 parent 4c04586 commit a297980
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 30 deletions.
42 changes: 18 additions & 24 deletions src/agents.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,25 +35,17 @@ function interpolateDescription(description, inputs) {
return result;
}

function getApiKey(llmConfig, provider) {
function getApiKey(llmConfig, provider, env) {
if (llmConfig?.apiKey) return llmConfig.apiKey;

let env = {};

if (typeof process !== 'undefined' && process.env) {
env = process.env;
} else if (typeof window !== 'undefined') {
env = window?.process?.env || import.meta.env || {};
}

const apiKeys = {
anthropic: env.ANTHROPIC_API_KEY || env.NEXT_PUBLIC_ANTHROPIC_API_KEY || env.VITE_ANTHROPIC_API_KEY,
google: env.GOOGLE_API_KEY || env.NEXT_PUBLIC_GOOGLE_API_KEY || env.VITE_GOOGLE_API_KEY,
mistral: env.MISTRAL_API_KEY || env.NEXT_PUBLIC_MISTRAL_API_KEY || env.VITE_MISTRAL_API_KEY,
openai: env.OPENAI_API_KEY || env.NEXT_PUBLIC_OPENAI_API_KEY || env.VITE_OPENAI_API_KEY,
anthropic: env.ANTHROPIC_API_KEY,
google: env.GOOGLE_API_KEY,
mistral: env.MISTRAL_API_KEY,
openai: env.OPENAI_API_KEY
};

return apiKeys[provider] || apiKeys.openai || (() => { throw new Error('API key is missing. Please provide it through llmConfig or set the appropriate environment variables.'); })();
return apiKeys[provider] ||
(() => { throw new Error('API key is missing. Please provide it through the Agent llmConfig or throught the team env variable. E.g: new Team ({name: "My Team", env: {OPENAI_API_KEY: "your-api-key"}})') })();
}


Expand All @@ -65,22 +57,21 @@ class BaseAgent {
this.goal = goal;
this.background = background;
this.tools = tools;

const defaultConfig = {
model: "gpt-3.5-turbo-0125",
apiKey: getApiKey(llmConfig, llmConfig.provider || 'openai'),
apiKey: null,
};
this.llmConfig = { ...defaultConfig, ...llmConfig };

if (!this.llmConfig.apiKey) {
throw new Error('API key is missing. Please provide it through llmConfig or set the appropriate environment variables.');
}
}

async initAgent() {
throw new Error("initAgent must be implemented by subclasses.");
}

setEnv(env) {
this.env = env;
}

executeTask(task) {
throw new Error("executeTask must be implemented by subclasses.");
}
Expand All @@ -95,20 +86,20 @@ class BasicChatAgent extends BaseAgent {
this.llmConfig = { ...defaultConfig, ...config.llmConfig };
}

async initAgent() {
async initAgent() {
const providers = {
anthropic: ChatAnthropic,
google: ChatGoogleGenerativeAI,
mistral: ChatMistralAI,
openai: ChatOpenAI,
};

const provider = this.llmConfig.provider;
const provider = this.llmConfig.provider || 'openai';
const ChatClass = providers[provider] || providers.openai;

this.llmInstance = new ChatClass({
...this.llmConfig,
apiKey: getApiKey(this.llmConfig, provider),
apiKey: getApiKey(this.llmConfig, provider, this.env),
});
}

Expand Down Expand Up @@ -158,6 +149,9 @@ class ReActAgent extends BaseAgent {
}

async initAgent() {
if (!this.llmConfig.apiKey) {
throw new Error('API key is missing. Please provide it through the Agent llmConfig or throught the team env variable. E.g: new Team ({name: "My Team", env: {OPENAI_API_KEY: "your-api-key"}})');
}
this.llmInstance = new OpenAI({
...this.llmConfig,
apiKey: getApiKey(this.llmConfig, 'openai'),
Expand Down
7 changes: 6 additions & 1 deletion src/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ class Agent {
return this.agentInstance.executeTask(task, inputs, context);
}

setEnv(env){
this.agentInstance.setEnv(env);
}

// Proxy property access to the underlying agent instance
get id() {
return this.agentInstance.id;
Expand Down Expand Up @@ -81,7 +85,8 @@ class Task {

class Team {
constructor({ name, agents, tasks, verbose = 1, inputs = {}, env = null }) {
this.store = createTeamStore({ name, agents, tasks, inputs, env, verbose});
this.store = createTeamStore({ name, tasks, inputs, env, verbose});
this.store.getState().addAgents(agents);
}

async start(inputs = null) {
Expand Down
6 changes: 5 additions & 1 deletion src/stores.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ const createTeamStore = (initialState = {}) => {
setName: (name) => set({ name }), // Add a new action to update inputs
setEnv: (env) => set({ env }), // Add a new action to update inputs
addAgents: agents => {
const envVariables = get().env; // Accessing the env property using get().env
agents.forEach(agent => {
agent.setEnv(envVariables); // Setting the environment variables for each agent
});
set(state => ({ agents: [...state.agents, ...agents] }));
},
addTasks: (tasks) => {
Expand Down Expand Up @@ -140,7 +144,7 @@ const createTeamStore = (initialState = {}) => {
executeAgentTask: async (agent, task, inputs, context='') => {
// Assuming all agent classes extend BaseAgent and implement their own executeTask method
// TODO: Why inputs here?
return agent.executeTask(task, inputs, context);
return agent.executeTask(task, inputs, context, get().env);
}

}), "teamStore"))
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/examples/teams/anthropic/productSpecsTeam.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ const requirementsAnalyst = new Agent({
maxTokens: 1024,
anthropicApiUrl: "https://www.agenticjs.com/proxy/anthropic",
}

});

const technicalWriter = new Agent({
Expand Down Expand Up @@ -73,6 +72,7 @@ const team = new Team({
agents: [requirementsAnalyst, technicalWriter, validator],
tasks: [analysisTask, writingTask, validationTask],
inputs: { founderIdea: 'I want to add a Referral program to our SAAS platform.' }, // Initial input for the first task
env: {ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY} // Environment variables for the team
});

module.exports = team;
2 changes: 1 addition & 1 deletion tests/e2e/examples/teams/google/productSpecsTeam.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ const requirementsAnalyst = new Agent({
provider: "google",
model: "gemini-1.5-flash",
}

});

const technicalWriter = new Agent({
Expand Down Expand Up @@ -64,6 +63,7 @@ const team = new Team({
agents: [requirementsAnalyst, technicalWriter, validator],
tasks: [analysisTask, writingTask, validationTask],
inputs: { founderIdea: 'I want to add a Referral program to our SAAS platform.' }, // Initial input for the first task
env: {GOOGLE_API_KEY: process.env.GOOGLE_API_KEY} // Environment variables for the team
});

module.exports = team;
2 changes: 1 addition & 1 deletion tests/e2e/examples/teams/mistral/productSpecsTeam.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ const requirementsAnalyst = new Agent({
provider: "mistral",
model: "mistral-small",
}

});

const technicalWriter = new Agent({
Expand Down Expand Up @@ -64,6 +63,7 @@ const team = new Team({
agents: [requirementsAnalyst, technicalWriter, validator],
tasks: [analysisTask, writingTask, validationTask],
inputs: { founderIdea: 'I want to add a Referral program to our SAAS platform.' }, // Initial input for the first task
env: {MISTRAL_API_KEY: process.env.MISTRAL_API_KEY} // Environment variables for the team
});

module.exports = team;
3 changes: 2 additions & 1 deletion tests/e2e/examples/teams/openai/productSpecsTeam.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ const team = new Team({
name: 'Product Specs Team',
agents: [requirementsAnalyst, technicalWriter, validator],
tasks: [analysisTask, writingTask, validationTask],
inputs: { founderIdea: 'I want to add a Referral program to our SAAS platform.' }, // Initial input for the first task
inputs: { founderIdea: 'I want to add a Referral program to our SAAS platform.' }, // Initial input for the first task,
env: {OPENAI_API_KEY: process.env.OPENAI_API_KEY} // Environment variables for the team
});

module.exports = team;

0 comments on commit a297980

Please sign in to comment.