Agent class
The Agent
class is the core class in Agenite that orchestrates interactions between LLMs and tools.
Constructor
new Agent<
Reducer extends AnyStateReducer = typeof defaultStateReducer,
Steps extends BaseSteps = typeof defaultStepConfig,
Middlewares extends BaseMiddlewares = [],
Extensions extends Record<string, unknown> | undefined = undefined
>({
name: string;
provider: LLMProvider;
tools?: Tool[];
instructions?: string;
description?: string;
agents?: Agent[];
stateReducer?: Reducer;
initialState?: Partial<StateFromReducer<Reducer>>;
steps?: Steps;
startStep?: string;
middlewares?: Middlewares;
extensions?: Extensions;
})
Parameters
name
(required): Unique identifier for the agent
provider
(required): LLM provider instance
tools
: Array of tools available to the agent
instructions
: System instructions for the agent (default: “You are a helpful assistant.”)
description
: Description of the agent’s purpose
agents
: Sub-agents that can be called by this agent
stateReducer
: Custom state management functions
initialState
: Initial agent state
steps
: Custom execution steps
startStep
: First step to execute (default: “agenite.llm-call”)
middlewares
: Array of middleware functions to modify agent behavior
extensions
: Additional custom functionality
Methods
execute
Execute the agent with a set of inputs.
execute(
input: Partial<StateFromReducer<Reducer>>,
options?: ExecutionOptions
): Promise<{
messages: BaseMessage[];
tokenUsage: TokenUsage;
[key: string]: unknown;
}>
Parameters
input
(required): Input state, typically containing messages
options
: Additional execution options
stream
: Enable streaming responses
context
: Additional execution context
parentExecution
: Context from a parent execution (for nested agents)
Returns
Returns the final state object containing:
messages
: Array of messages from the conversation
tokenUsage
: Token usage statistics
- Additional properties from the state
iterate
Get an iterator for streaming responses.
iterate(
input: Partial<StateFromReducer<Reducer>>,
options?: ExecutionOptions
): AsyncGenerator<YieldValue, ReturnValue, NextValue>
Parameters
Same as execute
Returns
An AsyncGenerator that yields various events during execution:
// Example yield types
{ type: 'agenite.start', executionContext: StepContext }
{ type: 'agenite.llm-call.input', content: { messages, instructions, tools } }
{ type: 'agenite.llm-call.streaming', content: PartialReturn }
{ type: 'agenite.tool-call.params', toolUseBlocks: ToolUseBlock[], hasAgentCall: boolean }
{ type: 'agenite.end', executionContext: StepContext }
State and Messages
State Structure
The agent maintains state which typically includes at minimum:
interface DefaultState {
messages: BaseMessage[];
[key: string]: unknown;
}
Message Structure
Messages follow the structure defined in the LLM package:
interface BaseMessage {
role: 'user' | 'assistant' | 'system';
content: ContentBlock[];
}
type ContentBlock =
| TextBlock // { type: 'text', text: string }
| ImageBlock // { type: 'image', source: { type: 'url', url: string } | { type: 'base64', ... } }
| ToolUseBlock // { type: 'toolUse', id: string, name: string, input: unknown }
| ToolResultBlock // { type: 'toolResult', toolUseId: string, toolName: string, content?: string | Array<...> }
| DocumentBlock // { type: 'document', source: { ... } }
| ThinkingBlock // { type: 'thinking', thinking: string }
| RedactedThinkingBlock; // { type: 'redactedThinking', redactedThinking: string }
Step Interface
Custom steps implement the Step interface:
interface Step<
ReturnValue,
YieldValue,
Params,
Context
> {
name: string;
beforeExecute?: (context: Context) => Promise<Params>;
execute: (params: Params, context: Context) => AsyncGenerator<
YieldValue,
ReturnValue,
NextValue
>;
afterExecute?: (
result: ReturnValue,
context: Context
) => Promise<ReturnValue>;
}
Middleware Interface
Middlewares wrap the generator function:
type Middleware<
YieldValue = unknown,
ReturnValue = unknown,
NextValue = unknown
> = (
generator: AsyncGenerator<YieldValue, ReturnValue, NextValue>,
context: StepContext<AnyStateReducer>
) => AsyncGenerator<YieldValue, ReturnValue, NextValue>;
Examples
Basic usage
import { Agent } from '@agenite/agent';
import { Ollama } from '@agenite/ollama';
import { Calculator } from '@agenite/tool';
const agent = new Agent({
name: 'simple-agent',
provider: new Ollama({ model: 'llama3.2' }),
tools: [new Calculator()],
instructions: 'You are a helpful assistant.',
});
const result = await agent.execute({
messages: [
{
role: 'user',
content: [{ type: 'text', text: 'What is 137 * 456?' }],
},
],
});
console.log(result.messages[result.messages.length - 1].content);
With custom state
interface ChatState {
messages: BaseMessage[];
messageCount: number;
lastMessage: string;
}
const agent = new Agent<{
messageCount: (newValue: number, prevValue?: number) => number;
lastMessage: (newValue: string) => string;
}>({
name: 'stateful-agent',
provider: new Ollama({ model: 'llama3.2' }),
initialState: {
messages: [],
messageCount: 0,
lastMessage: '',
},
stateReducer: {
messageCount: (_, prev = 0) => prev + 1,
lastMessage: (newValue) => newValue,
},
});
With middleware
import { prettyLogger } from '@agenite/middleware-pretty-logger';
const agent = new Agent({
name: 'middleware-agent',
provider: new Ollama({ model: 'llama3.2' }),
middlewares: [
prettyLogger(),
// Custom middleware example
(generator, context) => {
return (async function* () {
for await (const value of generator) {
// Do something with each yielded value
console.log(`Event: ${value.type}`);
yield value;
}
})();
}
],
});
With custom steps
const agent = new Agent({
name: 'custom-steps-agent',
provider: new Ollama({ model: 'llama3.2' }),
steps: {
'custom.confirmation': {
name: 'custom.confirmation',
execute: async function* (params, context) {
const response = yield {
type: 'custom.needs-confirmation',
message: 'Do you want to proceed?',
};
if (response?.confirmed) {
return { next: 'agenite.llm-call', state: {} };
} else {
return { next: 'agenite.end', state: {} };
}
}
},
// Include default steps here if needed
'agenite.llm-call': LLMStep,
'agenite.tool-call': ToolStep,
},
// Start with the custom step instead of the default
startStep: 'custom.confirmation',
});
Next steps