API Reference
This section contains the API documentation for Agenix, automatically generated from the source code.
Package Overview
Agenix - A lightweight AI coding agent.
A minimal Python implementation inspired by pi-mono, supporting OpenAI and Anthropic LLMs with file operations, shell execution, Agent Skills, and Extensions.
## Programmatic Usage (SDK)
```python import asyncio from agenix import create_session
- async def main():
- session = await create_session(
api_key=”your-key”, model=”gpt-4o”
) response = await session.prompt(“What files are in the current directory?”) print(response)
## Extension System
Extensions can be placed in: - Global: ~/.agenix/extensions/ - Project: .agenix/extensions/
Example extension: ```python # ~/.agenix/extensions/my_tool.py async def setup(agenix):
from agenix.extensions import ToolDefinition, EventType
- async def my_execute(params, ctx):
return f”Result: {params}”
- agenix.register_tool(ToolDefinition(
name=”my_tool”, description=”My custom tool”, parameters={“type”: “object”}, execute=my_execute
))
- async agenix.create_session(api_key: str | None = None, base_url: str | None = None, model: str = 'gpt-4o', system_prompt: str | None = None, working_dir: str = '.', max_turns: int = 10, enable_extensions: bool = True) AgentSession[source]
Create an agent session for programmatic usage.
- Parameters:
api_key – API key for the LLM provider (or set OPENAI_API_KEY env var)
base_url – Optional API base URL
model – Model to use (default: gpt-4o)
system_prompt – Optional custom system prompt
working_dir – Working directory for file operations
max_turns – Maximum conversation turns per prompt
enable_extensions – Whether to load extensions
- Returns:
AgentSession instance
Example
>>> import asyncio >>> from agenix import create_session >>> >>> async def main(): ... session = await create_session( ... api_key="your-key", ... model="gpt-4o" ... ) ... response = await session.prompt("Hello!") ... print(response) ... >>> asyncio.run(main())
- class agenix.AgentSession(agent: Agent, tools: List[Any], extension_runner: ExtensionRunner | None = None, working_dir: str = '.')[source]
High-level agent session for programmatic usage.
Wraps the low-level Agent class with a simpler API.
- __init__(agent: Agent, tools: List[Any], extension_runner: ExtensionRunner | None = None, working_dir: str = '.')[source]
- async prompt(message: str) str[source]
Send a prompt to the agent and return the response.
- Parameters:
message – User message/prompt
- Returns:
Agent’s text response
- get_messages() List[UserMessage | AssistantMessage | ToolResultMessage | SystemMessage][source]
Get conversation history.
- Returns:
List of messages in the conversation
- class agenix.Agent(config: AgentConfig, tools: List[Tool] | None = None)[source]
Agent runtime with tool execution loop.
- subscribe(callback: Callable[[AgentStartEvent | AgentEndEvent | TurnStartEvent | TurnEndEvent | MessageStartEvent | MessageUpdateEvent | MessageEndEvent | ToolExecutionStartEvent | ToolExecutionUpdateEvent | ToolExecutionEndEvent], None]) Callable[[], None][source]
Subscribe to agent events.
- Returns:
Unsubscribe function
- async prompt(user_message: str) AsyncIterator[AgentStartEvent | AgentEndEvent | TurnStartEvent | TurnEndEvent | MessageStartEvent | MessageUpdateEvent | MessageEndEvent | ToolExecutionStartEvent | ToolExecutionUpdateEvent | ToolExecutionEndEvent][source]
Process a user prompt through the agent loop.
- Parameters:
user_message – User’s message
- Yields:
Agent events
- get_messages() List[UserMessage | AssistantMessage | ToolResultMessage | SystemMessage][source]
Get conversation messages.
- class agenix.AgentConfig(model: str, api_key: str, base_url: str | None = None, system_prompt: str | None = None, max_turns: int = 10, max_tool_calls_per_turn: int = 20, max_tokens: int = 16384, skill_dirs: List[str] | None = None)[source]
Agent configuration.
- agenix.get_provider(provider_name: str, **kwargs) LLMProvider[source]
Get LLM provider by name.
- class agenix.SessionManager(session_dir: str = '.agenix')[source]
Manage persistent agent sessions.
- create_session(name: str | None = None) str[source]
Create a new session.
- Parameters:
name – Optional session name
- Returns:
Session ID
- save_message(session_id: str, message: UserMessage | AssistantMessage | ToolResultMessage | SystemMessage) None[source]
Save a message to session.
- Parameters:
session_id – Session ID
message – Message to save
- load_session(session_id: str) List[UserMessage | AssistantMessage | ToolResultMessage | SystemMessage][source]
Load session messages.
- Parameters:
session_id – Session ID
- Returns:
List of messages
- class agenix.Skill(name: str, description: str, file_path: str, content: str, license: str | None = None, compatibility: str | None = None, allowed_tools: List[str] | None = None, metadata: Dict[str, ~typing.Any]=<factory>, disable_model_invocation: bool = False)[source]
Represents a skill with its metadata and content.
A skill extends Claude’s capabilities by providing specialized knowledge or workflows. Skills follow the Anthropic Agent Skills standard.
Examples
>>> skill = Skill( ... name="pdf", ... description="PDF manipulation toolkit", ... file_path="/skills/pdf/SKILL.md", ... content="---\nname: pdf\n...", ... allowed_tools=["Bash(pdf:*)"] ... ) >>> print(skill.name) 'pdf'
- class agenix.SkillManager(skill_dirs: List[str] | None = None)[source]
Manages discovery, loading, and access to skills.
The SkillManager discovers skills from configured directories, parses their frontmatter, validates them according to the Agent Skills standard, and provides access to skill metadata and content.
Skill discovery looks for: - Direct .md files in the root of skill directories - SKILL.md files in subdirectories (subdirectory name should match skill name)
Default skill directories (if no custom dirs specified): - Global: ~/.agenix/skills/ - Project: .agenix/skills/
Examples
>>> # Use default directories >>> manager = SkillManager() >>> print(len(manager.list_skills())) 5
>>> # Custom directories >>> manager = SkillManager(skill_dirs=['/my/skills', '/other/skills']) >>> skill = manager.get_skill('pdf') >>> content = manager.load_skill_content('pdf')
>>> # Generate summary for system prompt >>> summary = manager.get_skills_summary() >>> print(summary) <available_skills> <skill name="pdf"> PDF manipulation toolkit... </skill> </available_skills>
- __init__(skill_dirs: List[str] | None = None)[source]
Initialize skill manager and load skills.
- Parameters:
skill_dirs – List of directories to search for skills. If None, uses default directories (~/.agenix/skills/ and .agenix/skills/)
Examples
>>> manager = SkillManager() # Use defaults >>> manager = SkillManager(skill_dirs=['/custom/path']) # Custom
- get_skill(name: str) Skill | None[source]
Get a skill by name.
- Parameters:
name – Skill name
- Returns:
Skill object if found, None otherwise
Examples
>>> manager = SkillManager(skill_dirs=['/skills']) >>> skill = manager.get_skill('pdf') >>> if skill: ... print(skill.description)
- list_skills() List[Skill][source]
List all available skills.
- Returns:
List of all loaded Skill objects
Examples
>>> manager = SkillManager() >>> for skill in manager.list_skills(): ... print(f"{skill.name}: {skill.description}")
- get_skills_summary() str[source]
Get a summary of available skills for system prompt.
Generates an XML-formatted summary of skills that are not disabled. This summary is injected into the system prompt to make Claude aware of available skills.
- Returns:
XML-formatted string with skill names and descriptions, or empty string if no visible skills
Examples
>>> manager = SkillManager(skill_dirs=['/skills']) >>> summary = manager.get_skills_summary() >>> print(summary) <available_skills> <skill name="pdf"> PDF manipulation toolkit... </skill> </available_skills>
Note
Skills with disable_model_invocation=True are excluded from the summary. These skills exist but are not shown to the model.
- load_skill_content(name: str) str | None[source]
Load full content of a skill.
Returns the complete markdown content including frontmatter. This is used for progressive disclosure - only loading full skill content when the model needs it.
- Parameters:
name – Skill name
- Returns:
Full skill markdown content, or None if skill not found
Examples
>>> manager = SkillManager(skill_dirs=['/skills']) >>> content = manager.load_skill_content('pdf') >>> if content: ... print("Loaded skill documentation")
- add_skill_dir(directory: str)[source]
Add a skill directory and load skills from it.
Dynamically adds a new skill directory to search and discovers any skills in that directory.
- Parameters:
directory – Path to skill directory
Examples
>>> manager = SkillManager() >>> manager.add_skill_dir('/custom/skills') >>> print(len(manager.list_skills()))
- class agenix.UserMessage(role: Literal['user'] = 'user', content: str | List[TextContent | ImageContent] = '', timestamp: float = <factory>)[source]
User message.
- content: str | List[TextContent | ImageContent] = ''
- __init__(role: Literal['user'] = 'user', content: str | List[TextContent | ImageContent] = '', timestamp: float = <factory>) None
- class agenix.AssistantMessage(role: Literal['assistant'] = 'assistant', content: str | List[TextContent | ToolCall] = '', tool_calls: List[ToolCall] = <factory>, model: str = '', usage: Usage | None = None, stop_reason: str | None = None, timestamp: float = <factory>)[source]
Assistant message with tool calls and metadata.
- content: str | List[TextContent | ToolCall] = ''
- class agenix.ToolResultMessage(role: Literal['tool'] = 'tool', tool_call_id: str = '', name: str = '', content: str | List[TextContent | ImageContent] = '', is_error: bool = False, timestamp: float = <factory>)[source]
Tool execution result.
- content: str | List[TextContent | ImageContent] = ''
- class agenix.TextContent(type: Literal['text'] = 'text', text: str = '')[source]
Text content block.
- class agenix.ImageContent(type: Literal['image'] = 'image', source: Dict[str, ~typing.Any]=<factory>)[source]
Image content block.
- class agenix.ToolCall(id: str, name: str, arguments: Dict[str, Any])[source]
Tool call from assistant.
Core Modules
Agent
Agent runtime with tool execution loop.
- class agenix.core.agent.AgentConfig(model: str, api_key: str, base_url: str | None = None, system_prompt: str | None = None, max_turns: int = 10, max_tool_calls_per_turn: int = 20, max_tokens: int = 16384, skill_dirs: List[str] | None = None)[source]
Bases:
objectAgent configuration.
- class agenix.core.agent.Agent(config: AgentConfig, tools: List[Tool] | None = None)[source]
Bases:
objectAgent runtime with tool execution loop.
- messages: List[UserMessage | AssistantMessage | ToolResultMessage | SystemMessage]
- subscribers: List[Callable[[AgentStartEvent | AgentEndEvent | TurnStartEvent | TurnEndEvent | MessageStartEvent | MessageUpdateEvent | MessageEndEvent | ToolExecutionStartEvent | ToolExecutionUpdateEvent | ToolExecutionEndEvent], None]]
- subscribe(callback: Callable[[AgentStartEvent | AgentEndEvent | TurnStartEvent | TurnEndEvent | MessageStartEvent | MessageUpdateEvent | MessageEndEvent | ToolExecutionStartEvent | ToolExecutionUpdateEvent | ToolExecutionEndEvent], None]) Callable[[], None][source]
Subscribe to agent events.
- Returns:
Unsubscribe function
- async prompt(user_message: str) AsyncIterator[AgentStartEvent | AgentEndEvent | TurnStartEvent | TurnEndEvent | MessageStartEvent | MessageUpdateEvent | MessageEndEvent | ToolExecutionStartEvent | ToolExecutionUpdateEvent | ToolExecutionEndEvent][source]
Process a user prompt through the agent loop.
- Parameters:
user_message – User’s message
- Yields:
Agent events
- get_messages() List[UserMessage | AssistantMessage | ToolResultMessage | SystemMessage][source]
Get conversation messages.
LLM Provider
Unified LLM interface supporting multiple providers.
- class agenix.core.llm.StreamEvent(type: str, delta: str = '', tool_call: ToolCall | None = None, finish_reason: str | None = None)[source]
Bases:
objectLLM stream event.
- class agenix.core.llm.LLMProvider(api_key: str | None = None, base_url: str | None = None)[source]
Bases:
ABCAbstract LLM provider interface.
- abstractmethod async stream(model: str, messages: List[UserMessage | AssistantMessage | ToolResultMessage | SystemMessage], system_prompt: str | None = None, tools: List[Dict[str, Any]] | None = None, max_tokens: int = 4096) AsyncIterator[StreamEvent][source]
Stream LLM responses.
- abstractmethod async complete(model: str, messages: List[UserMessage | AssistantMessage | ToolResultMessage | SystemMessage], system_prompt: str | None = None, tools: List[Dict[str, Any]] | None = None, max_tokens: int = 4096) AssistantMessage[source]
Complete LLM request (non-streaming).
- class agenix.core.llm.OpenAIProvider(api_key: str | None = None, base_url: str | None = None)[source]
Bases:
LLMProviderOpenAI/compatible API provider.
- async stream(model: str, messages: List[UserMessage | AssistantMessage | ToolResultMessage | SystemMessage], system_prompt: str | None = None, tools: List[Dict[str, Any]] | None = None, max_tokens: int = 4096) AsyncIterator[StreamEvent][source]
Stream OpenAI responses.
- async complete(model: str, messages: List[UserMessage | AssistantMessage | ToolResultMessage | SystemMessage], system_prompt: str | None = None, tools: List[Dict[str, Any]] | None = None, max_tokens: int = 4096) AssistantMessage[source]
Complete OpenAI request.
- class agenix.core.llm.AnthropicProvider(api_key: str | None = None, base_url: str | None = None)[source]
Bases:
LLMProviderAnthropic Claude API provider.
- async stream(model: str, messages: List[UserMessage | AssistantMessage | ToolResultMessage | SystemMessage], system_prompt: str | None = None, tools: List[Dict[str, Any]] | None = None, max_tokens: int = 4096) AsyncIterator[StreamEvent][source]
Stream Anthropic responses.
- async complete(model: str, messages: List[UserMessage | AssistantMessage | ToolResultMessage | SystemMessage], system_prompt: str | None = None, tools: List[Dict[str, Any]] | None = None, max_tokens: int = 4096) AssistantMessage[source]
Complete Anthropic request.
- agenix.core.llm.get_provider(provider_name: str, **kwargs) LLMProvider[source]
Get LLM provider by name.
Messages
Message types for agent communication.
- class agenix.core.messages.TextContent(type: Literal['text'] = 'text', text: str = '')[source]
Bases:
objectText content block.
- class agenix.core.messages.ImageContent(type: Literal['image'] = 'image', source: Dict[str, ~typing.Any]=<factory>)[source]
Bases:
objectImage content block.
- class agenix.core.messages.ToolCall(id: str, name: str, arguments: Dict[str, Any])[source]
Bases:
objectTool call from assistant.
- class agenix.core.messages.Usage(input_tokens: int = 0, output_tokens: int = 0, cache_read_tokens: int = 0, cache_write_tokens: int = 0, total_cost: float = 0.0)[source]
Bases:
objectToken usage statistics.
- class agenix.core.messages.UserMessage(role: Literal['user'] = 'user', content: str | List[TextContent | ImageContent] = '', timestamp: float = <factory>)[source]
Bases:
objectUser message.
- content: str | List[TextContent | ImageContent] = ''
- __init__(role: Literal['user'] = 'user', content: str | List[TextContent | ImageContent] = '', timestamp: float = <factory>) None
- class agenix.core.messages.AssistantMessage(role: Literal['assistant'] = 'assistant', content: str | List[TextContent | ToolCall] = '', tool_calls: List[ToolCall] = <factory>, model: str = '', usage: Usage | None = None, stop_reason: str | None = None, timestamp: float = <factory>)[source]
Bases:
objectAssistant message with tool calls and metadata.
- content: str | List[TextContent | ToolCall] = ''
- class agenix.core.messages.ToolResultMessage(role: Literal['tool'] = 'tool', tool_call_id: str = '', name: str = '', content: str | List[TextContent | ImageContent] = '', is_error: bool = False, timestamp: float = <factory>)[source]
Bases:
objectTool execution result.
- content: str | List[TextContent | ImageContent] = ''
- class agenix.core.messages.SystemMessage(role: Literal['system'] = 'system', content: str = '')[source]
Bases:
objectSystem message (for context).
- class agenix.core.messages.Context(system_prompt: str | None = None, messages: List[UserMessage | AssistantMessage | ToolResultMessage | SystemMessage] = <factory>, tools: Dict[str, ~typing.Any]]=<factory>)[source]
Bases:
objectConversation context.
- messages: List[UserMessage | AssistantMessage | ToolResultMessage | SystemMessage]
- __init__(system_prompt: str | None = None, messages: List[UserMessage | AssistantMessage | ToolResultMessage | SystemMessage] = <factory>, tools: Dict[str, ~typing.Any]]=<factory>) None
- class agenix.core.messages.AgentEvent(type: str, timestamp: float = <factory>)[source]
Bases:
objectBase class for agent events.
- class agenix.core.messages.AgentStartEvent(type: Literal['agent_start'] = 'agent_start', timestamp: float = <factory>)[source]
Bases:
AgentEventAgent started processing.
- class agenix.core.messages.AgentEndEvent(type: Literal['agent_end'] = 'agent_end', timestamp: float = <factory>, messages: List[UserMessage | AssistantMessage | ToolResultMessage | SystemMessage] = <factory>)[source]
Bases:
AgentEventAgent finished processing.
- messages: List[UserMessage | AssistantMessage | ToolResultMessage | SystemMessage]
- __init__(type: Literal['agent_end'] = 'agent_end', timestamp: float = <factory>, messages: List[UserMessage | AssistantMessage | ToolResultMessage | SystemMessage] = <factory>) None
- class agenix.core.messages.TurnStartEvent(type: Literal['turn_start'] = 'turn_start', timestamp: float = <factory>)[source]
Bases:
AgentEventTurn started.
- class agenix.core.messages.TurnEndEvent(type: Literal['turn_end'] = 'turn_end', timestamp: float = <factory>, message: AssistantMessage | None = None, tool_results: List[ToolResultMessage] = <factory>)[source]
Bases:
AgentEventTurn ended.
- message: AssistantMessage | None = None
- tool_results: List[ToolResultMessage]
- __init__(type: Literal['turn_end'] = 'turn_end', timestamp: float = <factory>, message: AssistantMessage | None = None, tool_results: List[ToolResultMessage] = <factory>) None
- class agenix.core.messages.MessageStartEvent(type: Literal['message_start'] = 'message_start', timestamp: float = <factory>, message: AssistantMessage | None = None)[source]
Bases:
AgentEventMessage streaming started.
- message: AssistantMessage | None = None
- class agenix.core.messages.MessageUpdateEvent(type: Literal['message_update'] = 'message_update', timestamp: float = <factory>, message: AssistantMessage | None = None, delta: str = '')[source]
Bases:
AgentEventMessage content updated.
- message: AssistantMessage | None = None
- class agenix.core.messages.MessageEndEvent(type: Literal['message_end'] = 'message_end', timestamp: float = <factory>, message: AssistantMessage | None = None)[source]
Bases:
AgentEventMessage streaming ended.
- message: AssistantMessage | None = None
- class agenix.core.messages.ToolExecutionStartEvent(type: Literal['tool_execution_start'] = 'tool_execution_start', timestamp: float = <factory>, tool_call_id: str = '', tool_name: str = '', args: Dict[str, ~typing.Any]=<factory>)[source]
Bases:
AgentEventTool execution started.
- class agenix.core.messages.ToolExecutionUpdateEvent(type: Literal['tool_execution_update'] = 'tool_execution_update', timestamp: float = <factory>, tool_call_id: str = '', tool_name: str = '', partial_result: Any = None)[source]
Bases:
AgentEventTool execution progress update.
- class agenix.core.messages.ToolExecutionEndEvent(type: Literal['tool_execution_end'] = 'tool_execution_end', timestamp: float = <factory>, tool_call_id: str = '', tool_name: str = '', result: str | ToolResult | Any = None, is_error: bool = False)[source]
Bases:
AgentEventTool execution completed.
- result: str | ToolResult | Any = None
Session Management
Session management with persistence.
- class agenix.core.session.SessionManager(session_dir: str = '.agenix')[source]
Bases:
objectManage persistent agent sessions.
- create_session(name: str | None = None) str[source]
Create a new session.
- Parameters:
name – Optional session name
- Returns:
Session ID
- save_message(session_id: str, message: UserMessage | AssistantMessage | ToolResultMessage | SystemMessage) None[source]
Save a message to session.
- Parameters:
session_id – Session ID
message – Message to save
- load_session(session_id: str) List[UserMessage | AssistantMessage | ToolResultMessage | SystemMessage][source]
Load session messages.
- Parameters:
session_id – Session ID
- Returns:
List of messages
Skills
Skill management system following the Anthropic Agent Skills standard.
This module implements the Agent Skills specification, providing discovery, loading, and management of skills that extend Claude’s capabilities.
Skills are defined using markdown files with YAML frontmatter containing: - name (required): Unique identifier (lowercase, hyphens, 1-64 chars) - description (required): Brief description of what the skill does - license (optional): License terms for the skill - compatibility (optional): Compatibility requirements - allowed-tools (optional): List of tools the skill can use - disable-model-invocation (optional): If true, skill is not shown to model - metadata (optional): Additional custom metadata
Examples
>>> manager = SkillManager(skill_dirs=['/path/to/skills'])
>>> skill = manager.get_skill('pdf')
>>> print(skill.description)
'PDF manipulation toolkit...'
- class agenix.core.skills.Skill(name: str, description: str, file_path: str, content: str, license: str | None = None, compatibility: str | None = None, allowed_tools: List[str] | None = None, metadata: Dict[str, ~typing.Any]=<factory>, disable_model_invocation: bool = False)[source]
Bases:
objectRepresents a skill with its metadata and content.
A skill extends Claude’s capabilities by providing specialized knowledge or workflows. Skills follow the Anthropic Agent Skills standard.
Examples
>>> skill = Skill( ... name="pdf", ... description="PDF manipulation toolkit", ... file_path="/skills/pdf/SKILL.md", ... content="---\nname: pdf\n...", ... allowed_tools=["Bash(pdf:*)"] ... ) >>> print(skill.name) 'pdf'
- class agenix.core.skills.SkillManager(skill_dirs: List[str] | None = None)[source]
Bases:
objectManages discovery, loading, and access to skills.
The SkillManager discovers skills from configured directories, parses their frontmatter, validates them according to the Agent Skills standard, and provides access to skill metadata and content.
Skill discovery looks for: - Direct .md files in the root of skill directories - SKILL.md files in subdirectories (subdirectory name should match skill name)
Default skill directories (if no custom dirs specified): - Global: ~/.agenix/skills/ - Project: .agenix/skills/
Examples
>>> # Use default directories >>> manager = SkillManager() >>> print(len(manager.list_skills())) 5
>>> # Custom directories >>> manager = SkillManager(skill_dirs=['/my/skills', '/other/skills']) >>> skill = manager.get_skill('pdf') >>> content = manager.load_skill_content('pdf')
>>> # Generate summary for system prompt >>> summary = manager.get_skills_summary() >>> print(summary) <available_skills> <skill name="pdf"> PDF manipulation toolkit... </skill> </available_skills>
- __init__(skill_dirs: List[str] | None = None)[source]
Initialize skill manager and load skills.
- Parameters:
skill_dirs – List of directories to search for skills. If None, uses default directories (~/.agenix/skills/ and .agenix/skills/)
Examples
>>> manager = SkillManager() # Use defaults >>> manager = SkillManager(skill_dirs=['/custom/path']) # Custom
- get_skill(name: str) Skill | None[source]
Get a skill by name.
- Parameters:
name – Skill name
- Returns:
Skill object if found, None otherwise
Examples
>>> manager = SkillManager(skill_dirs=['/skills']) >>> skill = manager.get_skill('pdf') >>> if skill: ... print(skill.description)
- list_skills() List[Skill][source]
List all available skills.
- Returns:
List of all loaded Skill objects
Examples
>>> manager = SkillManager() >>> for skill in manager.list_skills(): ... print(f"{skill.name}: {skill.description}")
- get_skills_summary() str[source]
Get a summary of available skills for system prompt.
Generates an XML-formatted summary of skills that are not disabled. This summary is injected into the system prompt to make Claude aware of available skills.
- Returns:
XML-formatted string with skill names and descriptions, or empty string if no visible skills
Examples
>>> manager = SkillManager(skill_dirs=['/skills']) >>> summary = manager.get_skills_summary() >>> print(summary) <available_skills> <skill name="pdf"> PDF manipulation toolkit... </skill> </available_skills>
Note
Skills with disable_model_invocation=True are excluded from the summary. These skills exist but are not shown to the model.
- load_skill_content(name: str) str | None[source]
Load full content of a skill.
Returns the complete markdown content including frontmatter. This is used for progressive disclosure - only loading full skill content when the model needs it.
- Parameters:
name – Skill name
- Returns:
Full skill markdown content, or None if skill not found
Examples
>>> manager = SkillManager(skill_dirs=['/skills']) >>> content = manager.load_skill_content('pdf') >>> if content: ... print("Loaded skill documentation")
- add_skill_dir(directory: str)[source]
Add a skill directory and load skills from it.
Dynamically adds a new skill directory to search and discovers any skills in that directory.
- Parameters:
directory – Path to skill directory
Examples
>>> manager = SkillManager() >>> manager.add_skill_dir('/custom/skills') >>> print(len(manager.list_skills()))
SDK
Programmatic SDK for using agenix as a library.
Example usage:
```python import asyncio from agenix import create_session
- async def main():
# Create a session session = await create_session(
api_key=”your-api-key”, model=”gpt-4o”, working_dir=”/path/to/project”
)
# Send a prompt response = await session.prompt(“What files are in the current directory?”) print(response)
# Continue conversation response = await session.prompt(“Can you read the README?”) print(response)
# Get conversation history messages = session.get_messages() print(f”Conversation has {len(messages)} messages”)
- if __name__ == “__main__”:
asyncio.run(main())
- async agenix.sdk.create_session(api_key: str | None = None, base_url: str | None = None, model: str = 'gpt-4o', system_prompt: str | None = None, working_dir: str = '.', max_turns: int = 10, enable_extensions: bool = True) AgentSession[source]
Create an agent session for programmatic usage.
- Parameters:
api_key – API key for the LLM provider (or set OPENAI_API_KEY env var)
base_url – Optional API base URL
model – Model to use (default: gpt-4o)
system_prompt – Optional custom system prompt
working_dir – Working directory for file operations
max_turns – Maximum conversation turns per prompt
enable_extensions – Whether to load extensions
- Returns:
AgentSession instance
Example
>>> import asyncio >>> from agenix import create_session >>> >>> async def main(): ... session = await create_session( ... api_key="your-key", ... model="gpt-4o" ... ) ... response = await session.prompt("Hello!") ... print(response) ... >>> asyncio.run(main())
- class agenix.sdk.AgentSession(agent: Agent, tools: List[Any], extension_runner: ExtensionRunner | None = None, working_dir: str = '.')[source]
Bases:
objectHigh-level agent session for programmatic usage.
Wraps the low-level Agent class with a simpler API.
- __init__(agent: Agent, tools: List[Any], extension_runner: ExtensionRunner | None = None, working_dir: str = '.')[source]
- async prompt(message: str) str[source]
Send a prompt to the agent and return the response.
- Parameters:
message – User message/prompt
- Returns:
Agent’s text response
- get_messages() List[UserMessage | AssistantMessage | ToolResultMessage | SystemMessage][source]
Get conversation history.
- Returns:
List of messages in the conversation
- async agenix.sdk.create_aos_session(api_key: str | None = None, base_url: str | None = None, model: str = 'gpt-4o', system_prompt: str | None = None, working_dir: str = '.', max_turns: int = 10, enable_extensions: bool = True, node_id: str = 'local', agent_id: str = 'main') AOSAgentSession[source]
Create an AOS agent session for programmatic usage.
Uses the Agent OS architecture with MessageBus, DirectChannel, and AOSAgentRuntime.
- Parameters:
api_key – API key for the LLM provider (or set OPENAI_API_KEY env var)
base_url – Optional API base URL
model – Model to use (default: gpt-4o)
system_prompt – Optional custom system prompt
working_dir – Working directory for file operations
max_turns – Maximum conversation turns per prompt
enable_extensions – Whether to load extensions
node_id – Node ID for AOS addressing (default: “local”)
agent_id – Agent ID for AOS addressing (default: “main”)
- Returns:
AOSAgentSession instance
Example
>>> import asyncio >>> from agenix import create_aos_session >>> >>> async def main(): ... session = await create_aos_session( ... api_key="your-key", ... model="gpt-4o" ... ) ... response = await session.prompt("Hello!") ... print(response) ... await session.close() ... >>> asyncio.run(main())
- class agenix.sdk.AOSAgentSession(bus: Any, channel: Any, runtime: Any, agent_address: Any, tools: List[Any], extension_runner: ExtensionRunner | None = None, working_dir: str = '.')[source]
Bases:
objectHigh-level AOS agent session for programmatic usage.
Uses the Agent OS architecture with MessageBus, DirectChannel, and AOSAgentRuntime. Provides the same API as AgentSession but with AOS benefits: - Better modularity and separation of concerns - Support for multiple channels and agents - Network-ready architecture - Enhanced observability
- __init__(bus: Any, channel: Any, runtime: Any, agent_address: Any, tools: List[Any], extension_runner: ExtensionRunner | None = None, working_dir: str = '.')[source]
- async prompt(message: str) str[source]
Send a prompt to the agent and return the response.
- Parameters:
message – User message/prompt
- Returns:
Agent’s text response
- get_messages() List[UserMessage | AssistantMessage | ToolResultMessage | SystemMessage][source]
Get conversation history.
- Returns:
List of messages in the conversation
- class agenix.sdk.ToolDefinition(name: str, description: str, parameters: Dict[str, Any], execute: Callable[[...], Awaitable[str]])[source]
Bases:
objectDefinition for a custom tool.
- class agenix.sdk.CommandDefinition(name: str, description: str, handler: Callable[[ExtensionContext, str], Awaitable[None]])[source]
Bases:
objectDefinition for a custom command.
- class agenix.sdk.ExtensionAPI(*args, **kwargs)[source]
Bases:
ProtocolAPI provided to extensions during setup.
Extensions use this to register tools, commands, and event handlers.
- register_tool(tool: ToolDefinition) None[source]
Register a custom tool that the LLM can call.
- register_command(command: CommandDefinition) None[source]
Register a custom command.
- on(event_type: EventType, handler: Callable[[Event, ExtensionContext], Awaitable[None]]) None[source]
Subscribe to an event.
- __init__(*args, **kwargs)
- class agenix.sdk.EventType(value)[source]
-
Agent lifecycle event types.
- SESSION_START = 'session_start'
- SESSION_END = 'session_end'
- AGENT_START = 'agent_start'
- AGENT_END = 'agent_end'
- TURN_START = 'turn_start'
- TURN_END = 'turn_end'
- TOOL_CALL = 'tool_call'
- TOOL_RESULT = 'tool_result'
- USER_INPUT = 'user_input'
CLI
Main entry point for agenix.
- agenix.cli.get_default_system_prompt(tools: list) str[source]
Get default system prompt with dynamic guidelines based on available tools.
- Parameters:
tools – List of available tool instances
- agenix.cli.validate_config(args, renderer: CLIRenderer = None) tuple[source]
Validate configuration and return api_key, base_url, model.
- Parameters:
args – Command-line arguments
renderer – CLI renderer for interactive input (optional)
- Returns:
(api_key, base_url, model)
- Return type:
- Raises:
ValueError – If configuration is invalid and no renderer provided
- async agenix.cli.process_single_message(agent, message: str, renderer: CLIRenderer)[source]
Process a single message in non-interactive mode.
Tools
Base Tool
Base tool interface.
- class agenix.tools.base.ToolResult(content: str | List[TextContent | ImageContent], details: Dict[str, Any] | None = None, is_error: bool = False)[source]
Bases:
objectTool execution result.
- content: str | List[TextContent | ImageContent]
- class agenix.tools.base.Tool(name: str, description: str, parameters: Dict[str, Any])[source]
Bases:
ABCAbstract tool interface.
- abstractmethod async execute(tool_call_id: str, arguments: Dict[str, Any], on_update: Callable[[str], None] | None = None) ToolResult[source]
Execute the tool with given arguments.
- Parameters:
tool_call_id – Unique ID for this tool call
arguments – Tool arguments (must be a dict)
on_update – Optional callback for progress updates
- Returns:
ToolResult with content and optional details
Read Tool
Read file tool.
Write Tool
Write file tool.
Edit Tool
Edit file tool with exact string replacement.
Bash Tool
Bash command execution tool.
Grep Tool
Grep/search tool.
Extensions System
Extension Types
Extension system types and interfaces.
Extensions are Python modules that can: - Subscribe to agent lifecycle events - Register custom LLM-callable tools - Register custom commands - Access agent context and UI primitives
- class agenix.extensions.types.EventType(value)[source]
-
Agent lifecycle event types.
- SESSION_START = 'session_start'
- SESSION_END = 'session_end'
- AGENT_START = 'agent_start'
- AGENT_END = 'agent_end'
- TURN_START = 'turn_start'
- TURN_END = 'turn_end'
- TOOL_CALL = 'tool_call'
- TOOL_RESULT = 'tool_result'
- USER_INPUT = 'user_input'
- class agenix.extensions.types.Event(type: EventType, data: Dict[str, Any])[source]
Bases:
objectBase event class.
- class agenix.extensions.types.AgentStartEvent(prompt: str)[source]
Bases:
EventFired when agent loop starts.
- class agenix.extensions.types.AgentEndEvent(messages: List[Any])[source]
Bases:
EventFired when agent loop ends.
- class agenix.extensions.types.TurnStartEvent(turn_index: int)[source]
Bases:
EventFired at the start of each turn.
- class agenix.extensions.types.TurnEndEvent(turn_index: int, message: Any)[source]
Bases:
EventFired at the end of each turn.
- class agenix.extensions.types.ToolCallEvent(tool_name: str, args: Dict[str, Any])[source]
Bases:
EventFired before a tool executes.
- class agenix.extensions.types.ToolResultEvent(tool_name: str, result: Any, is_error: bool)[source]
Bases:
EventFired after a tool executes.
- class agenix.extensions.types.UserInputEvent(text: str)[source]
Bases:
EventFired when user provides input.
- class agenix.extensions.types.ExtensionContext(agent: Agent, cwd: str, tools: List[Tool])[source]
Bases:
objectContext passed to extension event handlers.
Provides access to agent state and operations.
- class agenix.extensions.types.ToolDefinition(name: str, description: str, parameters: Dict[str, Any], execute: Callable[[...], Awaitable[str]])[source]
Bases:
objectDefinition for a custom tool.
- class agenix.extensions.types.CommandDefinition(name: str, description: str, handler: Callable[[ExtensionContext, str], Awaitable[None]])[source]
Bases:
objectDefinition for a custom command.
- class agenix.extensions.types.ExtensionAPI(*args, **kwargs)[source]
Bases:
ProtocolAPI provided to extensions during setup.
Extensions use this to register tools, commands, and event handlers.
- register_tool(tool: ToolDefinition) None[source]
Register a custom tool that the LLM can call.
- register_command(command: CommandDefinition) None[source]
Register a custom command.
- on(event_type: EventType, handler: Callable[[Event, ExtensionContext], Awaitable[None]]) None[source]
Subscribe to an event.
- __init__(*args, **kwargs)
- class agenix.extensions.types.LoadedExtension(path: str, name: str, tools: Dict[str, ToolDefinition], commands: Dict[str, CommandDefinition], handlers: Dict[EventType, List[Callable[[Event, ExtensionContext], Awaitable[None]]]])[source]
Bases:
objectA loaded extension with its registered items.
- tools: Dict[str, ToolDefinition]
- commands: Dict[str, CommandDefinition]
Extension Loader
Extension loader - discovers and loads Python extension modules.
- class agenix.extensions.loader.ExtensionLoaderAPI(extension: LoadedExtension)[source]
Bases:
objectImplementation of ExtensionAPI for use during extension loading.
- __init__(extension: LoadedExtension)[source]
- register_tool(tool: ToolDefinition) None[source]
Register a custom tool.
- register_command(command: CommandDefinition) None[source]
Register a custom command.
- on(event_type: EventType, handler: Callable[[Event, ExtensionContext], Awaitable[None]] | None = None)[source]
Subscribe to an event.
Can be used as a decorator or direct call:
# As decorator: @agenix.on(EventType.SESSION_START) async def handler(event, ctx):
pass
# Direct call: agenix.on(EventType.SESSION_START, handler)
- agenix.extensions.loader.discover_extensions(directory: str) List[str][source]
Discover extension files in a directory.
Returns list of absolute paths to .py files.
- agenix.extensions.loader.load_extension_module(file_path: str) Callable[[ExtensionAPI], Awaitable[None]] | None[source]
Load a Python extension module and return its setup function.
- Returns:
The setup() function from the module, or None if not found.
- async agenix.extensions.loader.load_extension(file_path: str) LoadedExtension | None[source]
Load an extension from a file path.
- Returns:
LoadedExtension instance, or None if loading failed.
- async agenix.extensions.loader.discover_and_load_extensions(cwd: str, agenix_dir: str | None = None) List[LoadedExtension][source]
Discover and load extensions from standard locations.
Loads from (in order): 1. Global: ~/.agenix/extensions/ 2. Project: .agenix/extensions/
- Parameters:
cwd – Current working directory (for project-local extensions)
agenix_dir – Global agenix directory (default: ~/.agenix)
- Returns:
List of successfully loaded extensions.
Extension Runner
Extension runner - executes extensions and manages their lifecycle.
- class agenix.extensions.runner.ExtensionRunner(extensions: List[LoadedExtension], context: ExtensionContext)[source]
Bases:
objectManages execution of loaded extensions.
- __init__(extensions: List[LoadedExtension], context: ExtensionContext)[source]
- get_tools() Dict[str, ToolDefinition][source]
Get all registered custom tools from extensions.
- get_commands() Dict[str, CommandDefinition][source]
Get all registered commands from extensions.
- async emit(event: Event) None[source]
Emit an event to all registered handlers.
- Parameters:
event – The event to emit.
- async execute_command(command_name: str, args: str) bool[source]
Execute a registered extension command.
- Parameters:
command_name – Name of the command
args – Command arguments as string
- Returns:
True if command was found and executed, False otherwise.
UI Components
CLI Interface
CLI interface for agenix.
- class agenix.ui.cli.CLIRenderer[source]
Bases:
objectRender agent events to terminal.
- render_event(event: AgentStartEvent | AgentEndEvent | TurnStartEvent | TurnEndEvent | MessageStartEvent | MessageUpdateEvent | MessageEndEvent | ToolExecutionStartEvent | ToolExecutionUpdateEvent | ToolExecutionEndEvent) None[source]
Render an event to the console.
- render_message(role: str, content: str, is_error: bool = False) None[source]
Render a complete message in a box.
- render_welcome(model: str = None, tools=None, skills=None) None[source]
Render welcome banner with ASCII art.
- prompt_config_input(field_name: str, description: str, is_secret: bool = False) str[source]
Prompt user for configuration input.
- Parameters:
field_name – Name of the configuration field
description – Description of what this field is for
is_secret – If True, input will be hidden
- Returns:
The user input
- class agenix.ui.cli.CLI(renderer: CLIRenderer | None = None)[source]
Bases:
objectMain CLI interface.
- __init__(renderer: CLIRenderer | None = None)[source]
- run_interactive(agent, tools=None, model=None, skills=None, show_welcome=True) None[source]
Run interactive chat loop.