Documentation
¶
Overview ¶
Package agent provides the main Agent orchestrator, which uses LLM & Skills to process data.
Start of Selection ¶
Package memory provides an interface for storing and retrieving conversation data.
Package session provides the Session struct for per-conversation state, along with methods for handling user messages and producing agent outputs.
Package agent - tool.go Defines the Tool interface and basic stubs for tool usage.
Index ¶
- Constants
- Variables
- func AssistantMessage(content string) openai.ChatCompletionMessageParamUnion
- func DeveloperMessage(content string) openai.ChatCompletionMessageParamUnion
- func GenerateSchema[T any]() interface{}
- func GetMessageText(message openai.ChatCompletionMessageParamUnion) (string, error)
- func MessageWhenToolError(toolCallID string) openai.ChatCompletionMessageParamUnion
- func MessageWhenToolErrorWithRetry(errorString string, toolCallID string) openai.ChatCompletionMessageParamUnion
- func NewIgnorableError(format string, a ...interface{}) error
- func NewRetryableError(format string, a ...interface{}) error
- func UserMessage(content string) openai.ChatCompletionMessageParamUnion
- type Agent
- func (a *Agent) ConvertSkillsToTools() []openai.ChatCompletionToolParam
- func (a *Agent) GetLogger() *slog.Logger
- func (a *Agent) GetSkill(name string) (*Skill, error)
- func (a *Agent) Run(ctx context.Context, llm LLM, messageHistory *MessageList, ...)
- func (a *Agent) SetLogger(logger *slog.Logger)
- func (a *Agent) SkillContextRunner(ctx context.Context, messageHistory *MessageList, llm LLM, ...) (*openai.ChatCompletionToolMessageParam, error)
- func (a *Agent) StopTool() openai.ChatCompletionToolParam
- type ContextKey
- type CostDetails
- type IgnorableError
- type InMemoryStorage
- type KeywordsAIClient
- func (c *KeywordsAIClient) CheapModel() string
- func (c *KeywordsAIClient) New(ctx context.Context, params openai.ChatCompletionNewParams) (*openai.ChatCompletion, error)
- func (c *KeywordsAIClient) NewResponse(ctx context.Context, params responses.ResponseNewParams) (*responses.Response, error)
- func (c *KeywordsAIClient) NewStreaming(ctx context.Context, params openai.ChatCompletionNewParams) *ssestream.Stream[openai.ChatCompletionChunk]
- func (c *KeywordsAIClient) StrongModel() string
- type LLM
- type Memory
- type MemoryBlock
- type MemoryValue
- type MessageList
- func (ml *MessageList) Add(msgs ...openai.ChatCompletionMessageParamUnion)
- func (ml *MessageList) AddFirstDeveloperMessage(msg openai.ChatCompletionMessageParamUnion)
- func (ml *MessageList) All() []openai.ChatCompletionMessageParamUnion
- func (ml *MessageList) Clear()
- func (ml *MessageList) CloneWithoutDeveloperMessages() *MessageList
- func (ml *MessageList) Len() int
- func (ml *MessageList) PrintMessages()
- func (ml *MessageList) ReplaceAt(index int, newMsg openai.ChatCompletionMessageParamUnion) error
- type Response
- type ResponseType
- type RetryableError
- type Session
- type Skill
- type Storage
- type TokenRates
- type Tool
- type ValueType
Constants ¶
const ( GPT4oInputRate = 2.5 GPT4oOutputRate = 10.0 GPT4oMiniInputRate = 0.15 GPT4oMiniOutputRate = 0.60 O3MiniInputRate = 1.10 O3MiniOutputRate = 4.40 O1InputRate = 15.0 O1OutputRate = 60.0 O3InputRate = 10.0 O3OutputRate = 40.0 O4MiniInputRate = 1.10 O4MiniOutputRate = 4.40 GPT41InputRate = 2.0 GPT41OutputRate = 8.0 GPT41MiniInputRate = 0.40 GPT41MiniOutputRate = 1.60 GPT41NanoInputRate = 0.10 GPT41NanoOutputRate = 0.40 )
Pricing constants for GPT-4o and GPT-4o-mini and O3-mini(in dollars per million tokens)
Variables ¶
var ( ErrSessionClosed = errors.New("session has been closed") ErrNoMessage = errors.New("no message available") ErrNoSessionID = errors.New("session ID not found in context or is not a string") )
var ModelPricings = map[string]TokenRates{ "gpt-4o": { Input: GPT4oInputRate, Output: GPT4oOutputRate, }, "gpt-4o-mini": { Input: GPT4oMiniInputRate, Output: GPT4oMiniOutputRate, }, "o3-mini": { Input: O3MiniInputRate, Output: O3MiniOutputRate, }, "o1": { Input: O1InputRate, Output: O1OutputRate, }, "o3": { Input: O3InputRate, Output: O3OutputRate, }, "o4-mini": { Input: O4MiniInputRate, Output: O4MiniOutputRate, }, "gpt-4.1": { Input: GPT41InputRate, Output: GPT41OutputRate, }, "gpt-4.1-mini": { Input: GPT41MiniInputRate, Output: GPT41MiniOutputRate, }, "gpt-4.1-nano": { Input: GPT41NanoInputRate, Output: GPT41NanoOutputRate, }, "azure/gpt-4o": { Input: GPT4oInputRate, Output: GPT4oOutputRate, }, "azure/gpt-4o-mini": { Input: GPT4oMiniInputRate, Output: GPT4oMiniOutputRate, }, "azure/o3-mini": { Input: O3MiniInputRate, Output: O3MiniOutputRate, }, "azure/o1": { Input: O1InputRate, Output: O1OutputRate, }, "azure/o3": { Input: O3InputRate, Output: O3OutputRate, }, "azure/o4-mini": { Input: O4MiniInputRate, Output: O4MiniOutputRate, }, "azure/gpt-4.1": { Input: GPT41InputRate, Output: GPT41OutputRate, }, "azure/gpt-4.1-mini": { Input: GPT41MiniInputRate, Output: GPT41MiniOutputRate, }, "azure/gpt-4.1-nano": { Input: GPT41NanoInputRate, Output: GPT41NanoOutputRate, }, }
ModelPricings is a map of model names to their pricing information
Functions ¶
func AssistantMessage ¶
func AssistantMessage(content string) openai.ChatCompletionMessageParamUnion
func DeveloperMessage ¶
func DeveloperMessage(content string) openai.ChatCompletionMessageParamUnion
func GenerateSchema ¶
func GenerateSchema[T any]() interface{}
func GetMessageText ¶
func GetMessageText(message openai.ChatCompletionMessageParamUnion) (string, error)
GetMessageText extracts the plain text content from an OpenAI chat message of any type (user, assistant, or developer message)
func MessageWhenToolError ¶
func MessageWhenToolError(toolCallID string) openai.ChatCompletionMessageParamUnion
func MessageWhenToolErrorWithRetry ¶
func MessageWhenToolErrorWithRetry(errorString string, toolCallID string) openai.ChatCompletionMessageParamUnion
func NewIgnorableError ¶
NewIgnorableError creates a new instance of IgnorableError.
func NewRetryableError ¶
NewRetryableError creates a new instance of RetryableError.
func UserMessage ¶
func UserMessage(content string) openai.ChatCompletionMessageParamUnion
TODO Remove all three and use openai functions directly
Types ¶
type Agent ¶
type Agent struct {
// contains filtered or unexported fields
}
Agent orchestrates calls to the LLM, uses Skills/Tools, and determines how to respond.
func (*Agent) ConvertSkillsToTools ¶
func (a *Agent) ConvertSkillsToTools() []openai.ChatCompletionToolParam
TODO - we probably need to have a custom made description for the tool that uses skill.description
func (*Agent) Run ¶
func (a *Agent) Run(ctx context.Context, llm LLM, messageHistory *MessageList, memoryBlock *MemoryBlock, outUserChannel chan Response)
Run processes a user message through the LLM, executes any requested skills. It returns only after the agent is done. The intermediary messages are sent to the outUserChannel.
func (*Agent) SkillContextRunner ¶
func (a *Agent) SkillContextRunner(ctx context.Context, messageHistory *MessageList, llm LLM, memoryBlock *MemoryBlock, skill *Skill, skillToolCall openai.ChatCompletionMessageToolCall) (*openai.ChatCompletionToolMessageParam, error)
func (*Agent) StopTool ¶
func (a *Agent) StopTool() openai.ChatCompletionToolParam
type CostDetails ¶
CostDetails represents detailed cost information for a session
type IgnorableError ¶
type IgnorableError struct {
// contains filtered or unexported fields
}
IgnorableError is the custom type for errors that can be ignored.
func (*IgnorableError) Error ¶
func (e *IgnorableError) Error() string
Error returns the error message for IgnorableError.
type InMemoryStorage ¶
type InMemoryStorage struct {
// contains filtered or unexported fields
}
InMemoryStorage implements the Storage interface using in-memory data structures
func NewInMemoryStorage ¶
func NewInMemoryStorage() *InMemoryStorage
NewInMemoryStorage creates a new instance of InMemoryStorage
func (*InMemoryStorage) AddAssistantMessage ¶
func (s *InMemoryStorage) AddAssistantMessage(ctx context.Context, assistantMessage string) error
AddAssistantMessage adds the assistant message to the existing conversation
func (*InMemoryStorage) AddUserMessage ¶
func (s *InMemoryStorage) AddUserMessage(ctx context.Context, userMessage string) error
AddUserMessage creates a new conversation with the user message
func (*InMemoryStorage) GetConversations ¶
func (s *InMemoryStorage) GetConversations(ctx context.Context, limit int, offset int) (*MessageList, error)
GetConversations returns the conversations in the order they were created
type KeywordsAIClient ¶
type KeywordsAIClient struct {
APIKey string
BaseURL string
// contains filtered or unexported fields
}
func NewKeywordsAIClient ¶
func NewKeywordsAIClient(apiKey string, baseURL string, strongModel string, cheapModel string) *KeywordsAIClient
func (*KeywordsAIClient) CheapModel ¶
func (c *KeywordsAIClient) CheapModel() string
func (*KeywordsAIClient) New ¶
func (c *KeywordsAIClient) New(ctx context.Context, params openai.ChatCompletionNewParams) (*openai.ChatCompletion, error)
TODO failures like too long, non-processable etc from the LLM needs to be handled
func (*KeywordsAIClient) NewResponse ¶
func (c *KeywordsAIClient) NewResponse(ctx context.Context, params responses.ResponseNewParams) (*responses.Response, error)
NewResponse creates a new response using OpenAI's Response API
func (*KeywordsAIClient) NewStreaming ¶
func (c *KeywordsAIClient) NewStreaming(ctx context.Context, params openai.ChatCompletionNewParams) *ssestream.Stream[openai.ChatCompletionChunk]
func (*KeywordsAIClient) StrongModel ¶
func (c *KeywordsAIClient) StrongModel() string
type LLM ¶
type LLM interface {
// New issues a non-streaming chat completion request.
New(ctx context.Context, params openai.ChatCompletionNewParams) (*openai.ChatCompletion, error)
// NewStreaming issues a streaming chat completion request, returning
// an ssestream.Stream to consume the chunks.
NewStreaming(ctx context.Context, params openai.ChatCompletionNewParams) *ssestream.Stream[openai.ChatCompletionChunk]
StrongModel() string
CheapModel() string
}
LLM defines the minimal contract required by the agent runtime to interact with a language-model provider. Implementations may add additional helper methods but only the operations below are relied upon by the rest of the codebase.
type Memory ¶
type Memory interface {
Retrieve(ctx context.Context) (*MemoryBlock, error)
}
Memory is an interface for reading/writing conversation data or other context.
type MemoryBlock ¶
type MemoryBlock struct {
Items map[string]MemoryValue // For storing multiple key-value pairs
// contains filtered or unexported fields
}
MemoryBlock represents a key-value store where values can be strings or nested MemoryBlocks
func NewMemoryBlock ¶
func NewMemoryBlock() *MemoryBlock
NewMemoryBlock creates a new MemoryBlock with initialized map
func (*MemoryBlock) AddBlock ¶
func (mb *MemoryBlock) AddBlock(key string, value *MemoryBlock)
AddBlock adds a MemoryBlock value for the given key
func (*MemoryBlock) AddString ¶
func (mb *MemoryBlock) AddString(key string, value string)
AddString adds a string value for the given key
func (*MemoryBlock) Delete ¶
func (mb *MemoryBlock) Delete(key string) bool
Delete removes a key-value pair from the MemoryBlock Returns true if the key was found and deleted, false otherwise
func (*MemoryBlock) Exists ¶
func (mb *MemoryBlock) Exists(key string) bool
Exists checks if a key exists in the MemoryBlock
func (*MemoryBlock) Parse ¶
func (mb *MemoryBlock) Parse() string
Parse generates a string representation of the MemoryBlock recursively parsing any nested MemoryBlocks into XML-style format
type MemoryValue ¶
type MemoryValue struct {
// contains filtered or unexported fields
}
MemoryValue represents a value that can be either a string or a nested MemoryBlock
func NewBlockValue ¶
func NewBlockValue(block *MemoryBlock) MemoryValue
NewBlockValue creates a MemoryValue containing a MemoryBlock
func NewStringValue ¶
func NewStringValue(s string) MemoryValue
NewStringValue creates a MemoryValue containing a string
func (MemoryValue) AsBlock ¶
func (mv MemoryValue) AsBlock() *MemoryBlock
AsBlock returns the MemoryBlock value if type is BlockType, nil otherwise
func (MemoryValue) AsString ¶
func (mv MemoryValue) AsString() string
AsString returns the string value if type is StringType, empty string otherwise
func (MemoryValue) IsBlock ¶
func (mv MemoryValue) IsBlock() bool
IsBlock returns true if the value is a MemoryBlock
func (MemoryValue) IsString ¶
func (mv MemoryValue) IsString() bool
IsString returns true if the value is a string
type MessageList ¶
type MessageList struct {
Messages []openai.ChatCompletionMessageParamUnion
}
MessageList holds an ordered collection of LLMMessage to preserve the history.
func CompileConversationHistory ¶
func CompileConversationHistory(ctx context.Context, storage Storage) (*MessageList, error)
CompileConversationHistory builds the message history for the LLM request now it fetches the last 5 messages but in the future, we'lll do smart things here like old message summarization etc
func NewMessageList ¶
func NewMessageList() *MessageList
func (*MessageList) Add ¶
func (ml *MessageList) Add(msgs ...openai.ChatCompletionMessageParamUnion)
Add appends one or more new messages to the MessageList in a FIFO order.
func (*MessageList) AddFirstDeveloperMessage ¶
func (ml *MessageList) AddFirstDeveloperMessage(msg openai.ChatCompletionMessageParamUnion)
AddFirstDeveloperMessage prepends a developer message to the message list. It panics if the provided message is not a developer message.
func (*MessageList) All ¶
func (ml *MessageList) All() []openai.ChatCompletionMessageParamUnion
func (*MessageList) Clear ¶
func (ml *MessageList) Clear()
func (*MessageList) CloneWithoutDeveloperMessages ¶
func (ml *MessageList) CloneWithoutDeveloperMessages() *MessageList
CloneWithoutDeveloperMessages returns a copy of the MessageList that excludes any developer or system messages, preserving the original order of the remaining messages. This is useful when sending conversation history back to the LLM, where developer/system prompts should not be repeated.
func (*MessageList) Len ¶
func (ml *MessageList) Len() int
func (*MessageList) PrintMessages ¶
func (ml *MessageList) PrintMessages()
PrintMessages is for debugging purposes
func (*MessageList) ReplaceAt ¶
func (ml *MessageList) ReplaceAt(index int, newMsg openai.ChatCompletionMessageParamUnion) error
type Response ¶
type Response struct {
Content string
Type ResponseType
}
Response represents a communication unit from the Agent to the caller/UI.
type ResponseType ¶
type ResponseType string
const ( ResponseTypeEnd ResponseType = "end" ResponseTypeError ResponseType = "error" )
type RetryableError ¶
type RetryableError struct {
// contains filtered or unexported fields
}
RetryableError is the custom type for errors that can be retried.
func (*RetryableError) Error ¶
func (e *RetryableError) Error() string
Error returns the error message for RetryableError.
type Session ¶
type Session struct {
// contains filtered or unexported fields
}
Session holds ephemeral conversation data & references to global resources.
func NewSession ¶
NewSession constructs a session with references to shared LLM & memory, but isolated state.
func (*Session) Close ¶
func (s *Session) Close()
Close ends the session lifecycle and releases any resources if needed.
func (*Session) Cost ¶
func (s *Session) Cost() (*CostDetails, bool)
Cost returns the accumulated cost of the session. It calculates the cost based on the total input and output tokens and the pricing for the session's model.
type Skill ¶
type Skill struct {
Name string
ToolDescription string // used as the tool description when the skill is presented as a tool
SystemPrompt string // used as the system prompt when the skill is running as an Agent
Tools []Tool
}
Skill holds a set of tools and a domain-specific prompt/description.
func (*Skill) GetTools ¶
func (s *Skill) GetTools() []openai.ChatCompletionToolParam
type Storage ¶
type Storage interface {
// conversation related
// GetConversations should return the conversations in the order of creating them.
// The first message in the returned list must be older than the second message in the list.
// Be careful on applying limit and offset. If the limit is 10 and offset is 5, it means
// we'll do the offset from the end of the conversation (i.e., skip the last 5 conversations
// in the whole chat history) and then take the 10 messages from that point backwards and
// return a list of those 10 messages arranged in the described order.
GetConversations(ctx context.Context, limit int, offset int) (*MessageList, error)
AddUserMessage(ctx context.Context, userMessage string) error
AddAssistantMessage(ctx context.Context, assistantMessage string) error
}
Storage is an interface that abstracts the user storage layer. For agentpod, a conversation is a pair of user messages and assistant messages.