-
Notifications
You must be signed in to change notification settings - Fork 6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
23 changed files
with
1,216 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import { AgentMessage, ChatMessage } from '../messages/Messages'; | ||
|
||
/** | ||
* A valid name for an agent. | ||
* To ensure parity with Python, we require agent names to be Python identifiers. | ||
*/ | ||
export class AgentName { | ||
private static readonly ID_START_CLASS = /[\p{Lu}\p{Ll}\p{Lt}\p{Lm}\p{Lo}\p{Nl}_\u1185-\u1186\u2118\u212E\u309B-\u309C]/u; | ||
private static readonly ID_CONTINUE_CLASS = /[\w\p{Nl}\p{Mc}_\u1185-\u1186\u2118\u212E\u309B-\u309C\u00B7\u0387\u1369-\u1371\u19DA\u200C\u200D\u30FB\uFF65]/u; | ||
private static readonly AGENT_NAME_REGEX = new RegExp(`^${AgentName.ID_START_CLASS.source}${AgentName.ID_CONTINUE_CLASS.source}*$`); | ||
|
||
constructor(private readonly value: string) { | ||
AgentName.checkValid(value); | ||
} | ||
|
||
public static isValid(name: string): boolean { | ||
return AgentName.AGENT_NAME_REGEX.test(name); | ||
} | ||
|
||
public static checkValid(name: string): void { | ||
if (!AgentName.isValid(name)) { | ||
throw new Error(`Agent name '${name}' is not a valid identifier.`); | ||
} | ||
} | ||
|
||
toString(): string { | ||
return this.value; | ||
} | ||
} | ||
|
||
/** | ||
* A response from calling IChatAgent's handleAsync. | ||
*/ | ||
export interface Response { | ||
/** | ||
* A chat message produced by the agent as a response. | ||
*/ | ||
message: ChatMessage; | ||
|
||
/** | ||
* Inner messages produced by the agent. | ||
*/ | ||
innerMessages?: AgentMessage[]; | ||
} | ||
|
||
/** | ||
* Base class for representing a stream of messages interspacing responses and internal processing messages. | ||
* This functions as a discriminated union. | ||
*/ | ||
export class StreamingFrame<TResponse, TInternalMessage extends AgentMessage> { | ||
public type: 'InternalMessage' | 'Response' = 'Response'; // Set default value | ||
public internalMessage?: TInternalMessage; | ||
public response?: TResponse; | ||
} | ||
|
||
/** | ||
* Base class for representing a stream of messages with internal messages of any AgentMessage subtype. | ||
*/ | ||
export class BaseStreamingFrame<TResponse> extends StreamingFrame<TResponse, AgentMessage> {} | ||
|
||
/** | ||
* The stream frame for IChatAgent's streamAsync | ||
*/ | ||
export class ChatStreamFrame extends BaseStreamingFrame<Response> {} | ||
|
||
/** | ||
* An agent that can participate in a chat. | ||
*/ | ||
export interface IChatAgent { | ||
/** | ||
* The name of the agent. This is used by team to uniquely identify the agent. | ||
* It should be unique within the team. | ||
*/ | ||
readonly name: AgentName; | ||
|
||
/** | ||
* The description of the agent. This is used by team to make decisions about which agents to use. | ||
* The description should describe the agent's capabilities and how to interact with it. | ||
*/ | ||
readonly description: string; | ||
|
||
/** | ||
* The types of messages that the agent produces. | ||
*/ | ||
readonly producedMessageTypes: Array<Function>; | ||
|
||
/** | ||
* Handles chat messages asynchronously and produces a response. | ||
* @param messages The messages to handle | ||
* @returns A promise resolving to the response | ||
*/ | ||
handleAsync(messages: ChatMessage[]): Promise<Response>; | ||
|
||
/** | ||
* Handles chat messages asynchronously and produces a stream of frames. | ||
* @param messages The messages to handle | ||
* @returns An async iterable of chat stream frames | ||
*/ | ||
streamAsync(messages: ChatMessage[]): AsyncIterable<ChatStreamFrame>; | ||
|
||
/** | ||
* Reset the agent to its initialization state. | ||
*/ | ||
resetAsync(): Promise<void>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { AgentMessage, ChatMessage, StopMessage } from "../messages/Messages"; | ||
import { Response } from "./ChatAgent"; | ||
|
||
/** | ||
* Base class for all group chat events. | ||
*/ | ||
export abstract class GroupChatEventBase {} | ||
|
||
/** | ||
* A request to start a group chat. | ||
*/ | ||
export class GroupChatStart extends GroupChatEventBase { | ||
/** | ||
* An optional list of messages to start the group chat. | ||
*/ | ||
messages?: ChatMessage[]; | ||
} | ||
|
||
/** | ||
* A response published to a group chat. | ||
*/ | ||
export class GroupChatAgentResponse extends GroupChatEventBase { | ||
/** | ||
* The response from an agent. | ||
*/ | ||
agentResponse!: Response; | ||
} | ||
|
||
/** | ||
* A request to publish a message to a group chat. | ||
*/ | ||
export class GroupChatRequestPublish extends GroupChatEventBase {} | ||
|
||
/** | ||
* A message from a group chat. | ||
*/ | ||
export class GroupChatMessage extends GroupChatEventBase { | ||
/** | ||
* The message that was published. | ||
*/ | ||
message!: AgentMessage; | ||
} | ||
|
||
/** | ||
* A message indicating that group chat was terminated. | ||
*/ | ||
export class GroupChatTermination extends GroupChatEventBase { | ||
/** | ||
* The stop message that indicates the reason of termination. | ||
*/ | ||
message!: StopMessage; | ||
} | ||
|
||
/** | ||
* A request to reset the agents in the group chat. | ||
*/ | ||
export class GroupChatReset extends GroupChatEventBase {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
/** | ||
* Interface for streaming handlers that can process an input type and produce an output type. | ||
*/ | ||
export interface IHandleStream<TIn, TOut> { | ||
/** | ||
* Processes the input and produces a stream of output. | ||
* @param input The input to process | ||
* @param cancellation Optional token to cancel the operation | ||
* @returns An async iterable of output items | ||
*/ | ||
streamAsync(input: TIn, cancellation?: AbortSignal): AsyncIterable<TOut>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { AgentMessage } from "./Messages"; | ||
|
||
/** | ||
* Message indicating that control should be handed off to another agent. | ||
*/ | ||
export class HandoffMessage extends AgentMessage { | ||
/** | ||
* Gets or sets the target agent to hand off control to. | ||
*/ | ||
targetAgent: string; | ||
|
||
/** | ||
* Gets or sets an optional message to send to the target agent. | ||
*/ | ||
message?: string; | ||
|
||
constructor(targetAgent: string, message?: string, source?: string) { | ||
super(); | ||
this.targetAgent = targetAgent; | ||
this.message = message; | ||
this.source = source; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { TaskFrame } from "./Tasks"; | ||
|
||
/** | ||
* Defines a team of agents that can work together to accomplish tasks. | ||
*/ | ||
export interface ITeam { | ||
/** | ||
* Gets a unique identifier for this team. | ||
*/ | ||
readonly teamId: string; | ||
|
||
/** | ||
* Executes a task and returns a stream of frames containing intermediate messages and final results. | ||
* @param task The task to execute, typically a string or message | ||
* @param cancellation Optional cancellation token | ||
* @returns An async iterable of task frames containing messages or results | ||
*/ | ||
streamAsync(task: string | unknown, cancellation?: AbortSignal): AsyncIterable<TaskFrame>; | ||
|
||
/** | ||
* Resets the team to its initial state. | ||
* @param cancellation Optional cancellation token | ||
*/ | ||
resetAsync(cancellation?: AbortSignal): Promise<void>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/** | ||
* Base class for all messages in the agent chat system. | ||
*/ | ||
export abstract class AgentMessage { | ||
/** | ||
* Gets or sets the source of the message (e.g., agent name, system, user). | ||
*/ | ||
source?: string; | ||
} | ||
|
||
/** | ||
* Represents a basic chat message with text content. | ||
*/ | ||
export class ChatMessage extends AgentMessage { | ||
/** | ||
* Gets or sets the text content of the message. | ||
*/ | ||
content: string; | ||
|
||
constructor(content: string, source?: string) { | ||
super(); | ||
this.content = content; | ||
this.source = source; | ||
} | ||
} | ||
|
||
/** | ||
* Message indicating that the chat should stop. | ||
*/ | ||
export class StopMessage extends AgentMessage { | ||
/** | ||
* Gets or sets the reason for stopping. | ||
*/ | ||
content: string; | ||
|
||
constructor(content: string, source?: string) { | ||
super(); | ||
this.content = content; | ||
this.source = source; | ||
} | ||
} | ||
|
||
/** | ||
* Represents metadata about a message exchange. | ||
*/ | ||
export class MessageMetadata { | ||
/** | ||
* Gets or sets any model parameters used to generate the message. | ||
*/ | ||
modelParameters?: Record<string, unknown>; | ||
} | ||
|
||
/** | ||
* Interface for handlers that need to store message metadata. | ||
*/ | ||
export interface IStoreMessageMetadata { | ||
/** | ||
* Gets the metadata associated with a message. | ||
* @param messageId The unique identifier of the message. | ||
* @returns The metadata associated with the message. | ||
*/ | ||
getMetadata(messageId: string): MessageMetadata | undefined; | ||
|
||
/** | ||
* Associates metadata with a message. | ||
* @param messageId The unique identifier of the message. | ||
* @param metadata The metadata to store. | ||
*/ | ||
setMetadata(messageId: string, metadata: MessageMetadata): void; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { AgentMessage } from "./Messages"; | ||
|
||
/** | ||
* Represents a frame of task execution, containing either a message or result. | ||
*/ | ||
export class TaskFrame { | ||
public readonly isResult: boolean; | ||
public readonly message?: AgentMessage; | ||
public readonly result?: TaskResult; | ||
|
||
/** | ||
* Creates a new task frame. | ||
* @param messageOrResult Either an AgentMessage or TaskResult | ||
*/ | ||
constructor(messageOrResult: AgentMessage | TaskResult) { | ||
if (messageOrResult instanceof TaskResult) { | ||
this.isResult = true; | ||
this.result = messageOrResult; | ||
} else { | ||
this.isResult = false; | ||
this.message = messageOrResult; | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Represents the result of a task execution, including all messages generated. | ||
*/ | ||
export class TaskResult { | ||
/** | ||
* Gets the messages generated during task execution. | ||
*/ | ||
public readonly messages: AgentMessage[]; | ||
|
||
/** | ||
* Creates a new task result. | ||
* @param messages The messages generated during task execution | ||
*/ | ||
constructor(messages: AgentMessage[]) { | ||
this.messages = messages; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { AgentMessage, StopMessage } from "./Messages"; | ||
|
||
/** | ||
* Exception thrown when a chat has already terminated. | ||
*/ | ||
export class TerminatedException extends Error { | ||
constructor() { | ||
super("The chat has already terminated."); | ||
this.name = "TerminatedException"; | ||
} | ||
} | ||
|
||
/** | ||
* Defines a condition that determines when a chat should terminate. | ||
*/ | ||
export interface ITerminationCondition { | ||
/** | ||
* Gets whether the chat has already terminated. | ||
*/ | ||
readonly isTerminated: boolean; | ||
|
||
/** | ||
* Checks if new messages should cause termination of the chat. | ||
* @param messages The messages to check | ||
* @returns A StopMessage if the chat should terminate, null otherwise | ||
*/ | ||
checkAndUpdateAsync(messages: AgentMessage[]): Promise<StopMessage | null>; | ||
|
||
/** | ||
* Resets the termination condition to its initial state. | ||
*/ | ||
reset(): void; | ||
} |
Oops, something went wrong.