Skip to content

Commit

Permalink
Merge pull request #4 from awslabs/definitions-cleaning
Browse files Browse the repository at this point in the history
seperated definitions into respective classes
  • Loading branch information
brnaba-aws authored Jul 25, 2024
2 parents 2e2d8b1 + 0ab7a52 commit 6a65c08
Show file tree
Hide file tree
Showing 7 changed files with 269 additions and 222 deletions.
42 changes: 42 additions & 0 deletions src/agents/agent.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,51 @@
import { ConversationMessage } from "../types";
import { AccumulatorTransform } from "../utils/helpers";

export interface AgentProcessingResult {
// The original input provided by the user
userInput: string;

// Unique identifier for the agent that processed the request
agentId: string;

// Human-readable name of the agent
agentName: string;

// Unique identifier for the user who initiated the request
userId: string;

// Unique identifier for the current session
sessionId: string;

// Additional parameters or metadata related to the processing result
// Can store any key-value pairs of varying types
additionalParams: Record<string, any>;
}

/**
* Represents the response from an agent, including metadata and output.
* @property metadata - Contains all properties of AgentProcessingResult except 'response'.
* @property output - The actual content of the agent's response, either as a transform or a string.
* @property streaming - Indicates whether the response is being streamed or not.
*/
export type AgentResponse = {
metadata: Omit<AgentProcessingResult, 'response'>;
output: AccumulatorTransform | string;
streaming: boolean;
};

export interface AgentOptions {
// The name of the agent
name: string;

// A description of the agent's purpose or capabilities
description: string;

// Optional: The ID of the model used by this agent
// If not provided, a default model may be used
modelId?: string;

// Optional: The geographic region where the agent should be deployed or run
region?: string;
}

Expand Down
20 changes: 17 additions & 3 deletions src/classifiers/anthropicClassifier.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,36 @@
import {
ANTHROPIC_MODEL_ID_CLAUDE_3_5_SONNET,
ClassifierResult,
ANTHROPIC_MODEL_ID_CLAUDE_3_5_SONNET,
ConversationMessage,
ParticipantRole,
} from "../types";
import { isToolInput } from "../utils/helpers";
import { Logger } from "../utils/logger";
import { Classifier } from "./classifier";
import { Classifier, ClassifierResult } from "./classifier";
import { Anthropic } from "@anthropic-ai/sdk";

export interface AnthropicClassifierOptions {
// Optional: The ID of the Anthropic model to use for classification
// If not provided, a default model may be used
modelId?: string;

// Optional: Configuration for the inference process
inferenceConfig?: {
// Maximum number of tokens to generate in the response
maxTokens?: number;

// Controls randomness in output generation
// Higher values (e.g., 0.8) make output more random, lower values (e.g., 0.2) make it more deterministic
temperature?: number;

// Controls diversity of output via nucleus sampling
// 1.0 considers all tokens, lower values (e.g., 0.9) consider only the most probable tokens
topP?: number;

// Array of sequences that will stop the model from generating further tokens when encountered
stopSequences?: string[];
};

// The API key for authenticating with Anthropic's services
apiKey: string;
}

Expand Down
18 changes: 16 additions & 2 deletions src/classifiers/bedrockClassifier.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {
BEDROCK_MODEL_ID_CLAUDE_3_5_SONNET,
ClassifierResult,
ConversationMessage,
ParticipantRole,
} from "../types";
Expand All @@ -10,18 +9,33 @@ import {
ConverseCommand,
} from "@aws-sdk/client-bedrock-runtime";

import { Classifier } from "./classifier";
import { Classifier, ClassifierResult } from "./classifier";
import { isToolInput } from "../utils/helpers";
import { Logger } from "../utils/logger";


export interface BedrockClassifierOptions {
// Optional: The ID of the Bedrock model to use for classification
// If not provided, a default model may be used
modelId?: string;

// Optional: The AWS region where the Bedrock model is used
region?: string;

// Optional: Configuration for the inference process
inferenceConfig?: {
// Maximum number of tokens to generate in the response
maxTokens?: number;

// Controls randomness in output generation
// Higher values (e.g., 0.8) make output more random, lower values (e.g., 0.2) make it more deterministic
temperature?: number;

// Controls diversity of output via nucleus sampling
// 1.0 considers all tokens, lower values (e.g., 0.9) consider only the most probable tokens
topP?: number;

// Array of sequences that will stop the model from generating further tokens when encountered
stopSequences?: string[];
};
}
Expand Down
10 changes: 9 additions & 1 deletion src/classifiers/classifier.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {
AgentTypes,
ClassifierResult,
ConversationMessage,
TemplateVariables,
} from "../types";
Expand All @@ -10,6 +9,15 @@ import {

import { Agent } from "../agents/agent";

export interface ClassifierResult {
// The agent selected by the classifier to handle the user's request
selectedAgent: Agent | null;

// A numeric value representing the classifier's confidence in its selection
// Typically a value between 0 and 1, where 1 represents 100% confidence
confidence: number;
}

/**
* IntentClassifier class extends BedrockAgent to provide specialized functionality
* for classifying user intents, selecting appropriate agents, and generating
Expand Down
180 changes: 172 additions & 8 deletions src/orchestrator.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
import { AgentOverlapAnalyzer } from "./agentOverlapAnalyzer";
import {
OrchestratorConfig,
DEFAULT_CONFIG,
ClassifierResult,
DispatchToAgentsParams,
OrchestratorOptions,
AgentResponse,
AgentTypes,
RequestMetadata,
} from "./types/index";
import { Agent } from "./agents/agent";
import { Agent, AgentResponse } from "./agents/agent";
import { ClassifierResult } from './classifiers/classifier';
import { BedrockLLMAgent } from "./agents/bedrockLLMAgent";
import { ChatStorage } from "./storage/chatStorage";
import { InMemoryChatStorage } from "./storage/memoryChatStorage";
Expand All @@ -19,6 +13,176 @@ import { Logger } from "./utils/logger";
import { BedrockClassifier } from "./classifiers/bedrockClassifier";
import { Classifier } from "./classifiers/classifier";

export interface OrchestratorConfig {
/** If true, logs the chat interactions with the agent */
LOG_AGENT_CHAT?: boolean;

/** If true, logs the chat interactions with the classifier */
LOG_CLASSIFIER_CHAT?: boolean;

/** If true, logs the raw, unprocessed output from the classifier */
LOG_CLASSIFIER_RAW_OUTPUT?: boolean;

/** If true, logs the processed output from the classifier */
LOG_CLASSIFIER_OUTPUT?: boolean;

/** If true, logs the execution times of various operations */
LOG_EXECUTION_TIMES?: boolean;

/** The maximum number of retry attempts for the classifier if it receives a bad XML response */
MAX_RETRIES?: number;

/**
* If true, uses the default agent when no agent is identified during intent classification.
*
* When set to true:
* - If no agent is identified, the system will fall back to using a predefined default agent.
* - This ensures that user requests are still processed, even if a specific agent cannot be determined.
*
* When set to false:
* - If no agent is identified, the system will return an error message to the user.
* - This prompts the user to rephrase their request for better agent identification.
*
* Use this option to balance between always providing a response (potentially less accurate)
* and ensuring high confidence in agent selection before proceeding.
*/
USE_DEFAULT_AGENT_IF_NONE_IDENTIFIED?: boolean;

/**
* The error message to display when a classification error occurs.
*
* This message is shown to the user when there's an internal error during the intent classification process,
* separate from cases where no agent is identified.
*/
CLASSIFICATION_ERROR_MESSAGE?: string;

/**
* The message to display when no agent is selected to handle the user's request.
*
* This message is shown when the classifier couldn't determine an appropriate agent
* and USE_DEFAULT_AGENT_IF_NONE_IDENTIFIED is set to false.
*/
NO_SELECTED_AGENT_MESSAGE?: string;

/**
* The general error message to display when an error occurs during request routing.
*
* This message is shown when an unexpected error occurs during the processing of a user's request,
* such as errors in agent dispatch or processing.
*/
GENERAL_ROUTING_ERROR_MSG_MESSAGE?: string;

/**
* Maximum number of message pairs (user-assistant interactions) to retain per agent.
*
* This constant defines the upper limit for the conversation history stored for each agent.
* Each pair consists of a user message and its corresponding assistant response.
*
* Usage:
* - When saving messages: pass (MAX_MESSAGE_PAIRS_PER_AGENT * 2) as maxHistorySize
* - When fetching chats: pass (MAX_MESSAGE_PAIRS_PER_AGENT * 2) as maxHistorySize
*
* Note: The actual number of messages stored will be twice this value,
* as each pair consists of two messages (user and assistant).
*
* Example:
* If MAX_MESSAGE_PAIRS_PER_AGENT is 5, up to 10 messages (5 pairs) will be stored per agent.
*/
MAX_MESSAGE_PAIRS_PER_AGENT?: number;
}

export const DEFAULT_CONFIG: OrchestratorConfig = {
/** Default: Do not log agent chat interactions */
LOG_AGENT_CHAT: false,

/** Default: Do not log classifier chat interactions */
LOG_CLASSIFIER_CHAT: false,

/** Default: Do not log raw classifier output */
LOG_CLASSIFIER_RAW_OUTPUT: false,

/** Default: Do not log processed classifier output */
LOG_CLASSIFIER_OUTPUT: false,

/** Default: Do not log execution times */
LOG_EXECUTION_TIMES: false,

/** Default: Retry classifier up to 3 times on bad XML response */
MAX_RETRIES: 3,

/** Default: Use the default agent when no agent is identified during intent classification */
USE_DEFAULT_AGENT_IF_NONE_IDENTIFIED: true,

/** Default error message for classification errors */
CLASSIFICATION_ERROR_MESSAGE: "I'm sorry, an error occurred while processing your request. Please try again later.",

/** Default message when no agent is selected to handle the request */
NO_SELECTED_AGENT_MESSAGE: "I'm sorry, I couldn't determine how to handle your request. Could you please rephrase it?",

/** Default general error message for routing errors */
GENERAL_ROUTING_ERROR_MSG_MESSAGE: "An error occurred while processing your request. Please try again later.",

/** Default: Maximum of 100 message pairs (200 individual messages) to retain per agent */
MAX_MESSAGE_PAIRS_PER_AGENT: 100,
};

export interface DispatchToAgentsParams {
// The original input provided by the user
userInput: string;

// Unique identifier for the user who initiated the request
userId: string;

// Unique identifier for the current session
sessionId: string;

// The result from a classifier, determining which agent to use
classifierResult: ClassifierResult;

// Optional: Additional parameters or metadata to be passed to the agents
// Can store any key-value pairs of varying types
additionalParams?: Record<string, any>;
}

/**
* Configuration options for the Orchestrator.
* @property storage - Optional ChatStorage instance for persisting conversations.
* @property config - Optional partial configuration for the Orchestrator.
* @property logger - Optional logging mechanism.
*/
export interface OrchestratorOptions {
storage?: ChatStorage;
config?: Partial<OrchestratorConfig>;
logger?: any;
classifier?: Classifier;
}

export interface RequestMetadata {
// The original input provided by the user
userInput: string;

// Unique identifier for the agent that processed the request
agentId: string;

// Human-readable name of the agent
agentName: string;

// Unique identifier for the user who initiated the request
userId: string;

// Unique identifier for the current session
sessionId: string;

// Additional parameters or metadata related to the request
// Stores string key-value pairs
additionalParams: Record<string, string>;

// Optional: Indicates if classification failed during processing
// Only present if an error occurred during classification
errorType?: 'classification_failed';
}


export class MultiAgentOrchestrator {
private config: OrchestratorConfig;
private storage: ChatStorage;
Expand Down
Loading

0 comments on commit 6a65c08

Please sign in to comment.