Skip to main content

A library for agent and environment protocol interactions

Project description

Interaxions

A lightweight, extensible framework for orchestrating AI agents and evaluation environments on Kubernetes/Argo Workflows, inspired by HuggingFace Transformers.

Python 3.10+ License: MIT

โœจ Features

  • ๐ŸŽฏ XJob-Based Configuration โ€” Minimal, framework-neutral XJob schema
  • ๐Ÿš€ Dynamic Loading โ€” Load components from local paths or remote Git repositories via Auto* classes
  • ๐Ÿ”„ Unified Entry File โ€” Every repository exposes a single ix.py entry point
  • ๐Ÿ“ฆ Three-Layer Architecture โ€” Scaffolds, Environments, and Workflows as peers
  • ๐Ÿท๏ธ Version Control โ€” Git tags, branches, and commit hashes
  • ๐Ÿ”’ Multi-Process Safe โ€” File locking for concurrent cache access
  • ๐Ÿ’พ Smart Caching โ€” Three-level cache for optimal performance
  • ๐ŸŒ Flexible Git Sources โ€” GitHub, GitLab, Gitea, or any Git service via IX_ENDPOINT

๐Ÿš€ Quick Start

Installation

# Core
pip install interaxions

# With OSS storage support
pip install interaxions[oss]

# For development
pip install -e ".[dev]"

Defining a Job

XJob is the single source of truth for a unit of work. All component configurations (scaffold, environment, model, โ€ฆ) live inside workflow.params โ€” the workflow itself defines and validates what it needs.

from interaxions import AutoWorkflow
from interaxions.schemas import XJob, WorkflowConfig, RuntimeConfig

job = XJob(
    name="fix-django-bug",
    description="Run SWE-agent on a SWE-bench instance",
    tags=["swe-bench", "django"],
    labels={"priority": "high", "team": "research"},

    workflow=WorkflowConfig(
        repo_name_or_path="Qwen-Agent-Hub/SWE-rollout-verify-postprocess-workflow",
        revision="v1.0.0",
        params={
            # Each workflow defines its own params schema
            "scaffold": {
                "repo_name_or_path": "Qwen-Agent-Hub/SWE-agent",
                "revision": "v1.0.0",
                "params": {"max_iterations": 50},
            },
            "environment": {
                "repo_name_or_path": "Qwen-Agent-Hub/SWE-bench",
                "revision": "v1.0.0",
                "id": "django__django-12345",
                "params": {"fix_hack": True},
            },
            "model": {
                "type": "litellm",
                "provider": "openai",
                "model": "gpt-4o",
                "base_url": "https://api.openai.com/v1",
                "api_key": "sk-...",
            },
        },
    ),

    runtime=RuntimeConfig(
        namespace="experiments",
        service_account="argo-workflow",
        ttl_seconds_after_finished=3600,
        extra_params={
            "labels": {"env": "prod"},
            "node_selector": {"gpu": "true"},
        },
    ),
)

# Submit to Argo
workflow_template = AutoWorkflow.from_repo(
    job.workflow.repo_name_or_path,
    revision=job.workflow.revision,
)
argo_workflow = workflow_template.create_workflow(job)
argo_workflow.create()

๐Ÿ“š Core Concepts

XJob โ€” Framework-Neutral Configuration

XJob carries only what is universally required:

Field Type Description
job_id str (auto) Unique identifier (UUID, auto-generated)
name str Human-readable name
tags / labels list / dict Metadata for search and filtering
workflow WorkflowConfig Which workflow repo to load + all workflow-specific params
runtime RuntimeConfig Kubernetes / Argo Workflows settings
extra_params dict Arbitrary job-level extras (optional)

Design principle: XJob makes no assumptions about what a workflow needs. All component configs go into workflow.params; the workflow validates them with its own Pydantic model.

Three-Layer Architecture

XJob
 โ””โ”€โ”€ workflow.params
       โ”œโ”€โ”€ scaffold   โ†’ AutoScaffold  โ†’ BaseScaffold.create_task()
       โ”œโ”€โ”€ environmentโ†’ AutoEnvironmentโ†’ BaseEnvironment.get() + create_task()
       โ””โ”€โ”€ model      โ†’ workflow-defined

Scaffold (BaseScaffold)

  • Wraps an AI agent (e.g. SWE-agent)
  • Implements create_task(job, environment) โ†’ hera.Task

Environment (BaseEnvironment)

  • Wraps a benchmark / evaluation dataset
  • Implements get(id) โ†’ Environment (pure data) and create_task(job, environment) โ†’ hera.Task
  • Credentials (OSS keys, API tokens) are read from environment variables, never passed as parameters

Workflow (BaseWorkflow)

  • Orchestrates scaffolds and environments into a full Argo Workflow DAG
  • Implements create_workflow(job) โ†’ hera.Workflow
  • Defines and validates its own workflow.params schema

Auto Classes โ€” Dynamic Loading

All three Auto classes share the same interface:

from interaxions import AutoScaffold, AutoEnvironment, AutoWorkflow

# From a remote Git repository (uses IX_ENDPOINT, default: GitHub)
scaffold  = AutoScaffold.from_repo("username/swe-agent", revision="v1.0.0")
env_task  = AutoEnvironment.from_repo("username/swe-bench", revision="v2.0.0")
workflow  = AutoWorkflow.from_repo("username/swe-rollout-verify")

# From a local path (for development / testing)
scaffold  = AutoScaffold.from_repo("./my-agent")
env_task  = AutoEnvironment.from_repo("/abs/path/to/my-bench")
workflow  = AutoWorkflow.from_repo("./my-workflow")

# Private repositories
scaffold  = AutoScaffold.from_repo(
    "company/private-agent",
    username="your-username",
    token="ghp_xxxx",          # or read from env var
)

Loading rules:

  • If the path contains /, ., or ~ โ†’ treated as a filesystem path or remote org/repo
  • Simple names without path separators are treated as remote org/repo (with IX_ENDPOINT as host)
  • Results are cached; pinned revisions (revision="v1.0.0") are cache-hit on repeat calls

Repository Structure

Every ix-hub repository must contain:

my-component/
โ”œโ”€โ”€ config.yaml      # Required โ€” repo metadata
โ””โ”€โ”€ ix.py            # Required โ€” exactly one class inheriting from the base class

config.yaml minimum:

repo_type: scaffold   # or: environment | workflow
type: my-component    # arbitrary identifier, becomes config.type

ix.py pattern (scaffold example):

from interaxions.scaffolds.base_scaffold import BaseScaffold, BaseScaffoldConfig

class MyScaffoldConfig(BaseScaffoldConfig):
    type: str = "my-scaffold"
    image: str = "my-agent:latest"

class MyScaffold(BaseScaffold):
    config_class = MyScaffoldConfig
    config: MyScaffoldConfig

    def create_task(self, job, environment, **kwargs):
        ...

ix.py pattern (environment example):

import os
from interaxions.environments.base_environment import BaseEnvironment, BaseEnvironmentConfig
from interaxions.schemas.task import Environment

class MyBenchConfig(BaseEnvironmentConfig):
    type: str = "my-bench"

class MyBench(BaseEnvironment):
    config_class = MyBenchConfig

    def get(self, id: str) -> Environment:
        # Read credentials from environment variables
        oss_key = os.environ["OSS_ACCESS_KEY_ID"]
        data = load_from_oss(id, oss_key)
        return Environment(id=id, type=self.config.type, data=data)

    def create_task(self, job, environment, **kwargs):
        ...

ix.py pattern (workflow example):

from pydantic import BaseModel
from interaxions.hub import AutoScaffold, AutoEnvironment
from interaxions.schemas import ScaffoldConfig, EnvironmentConfig
from interaxions.schemas.task import Environment
from interaxions.workflows.base_workflow import BaseWorkflow, BaseWorkflowConfig

class MyWorkflowParams(BaseModel):
    scaffold: ScaffoldConfig
    environment: EnvironmentConfig

class MyWorkflowConfig(BaseWorkflowConfig):
    type: str = "my-workflow"

class MyWorkflow(BaseWorkflow):
    config_class = MyWorkflowConfig

    def create_workflow(self, job, **kwargs):
        params = MyWorkflowParams(**job.workflow.params)

        scaffold  = AutoScaffold.from_repo(params.scaffold.repo_name_or_path)
        env_task  = AutoEnvironment.from_repo(params.environment.repo_name_or_path)
        env: Environment = env_task.get(params.environment.id)

        scaffold_task = scaffold.create_task(job, env)
        verify_task   = env_task.create_task(job, env)

        with hera.Workflow(name=..., namespace=job.runtime.namespace) as wf:
            scaffold_task >> verify_task

        return wf

๐Ÿ”ง Environment Variables

Variable Description Default
IX_HOME Base directory for Interaxions data ~/.interaxions
IX_HUB_CACHE Cache directory for hub modules ~/.interaxions/hub
IX_OFFLINE Disable all network access false
IX_ENDPOINT Git service base URL for remote repos https://github.com

Component credentials (OSS keys, HF tokens, API keys) are not stored in XJob. Environment repo maintainers read them from their own environment variables at runtime.


๐Ÿ“ฆ Schema Reference

WorkflowConfig

WorkflowConfig(
    repo_name_or_path="org/repo",   # required
    revision="v1.0.0",              # optional Git ref
    username=None,                  # optional auth
    token=None,                     # optional auth
    params={},                      # workflow-defined; shape is up to the workflow
)

RuntimeConfig

RuntimeConfig(
    namespace="experiments",        # required Kubernetes namespace
    service_account=None,           # optional
    image_pull_policy="IfNotPresent",
    active_deadline_seconds=None,
    ttl_seconds_after_finished=None,
    extra_params={
        "labels": {...},
        "annotations": {...},
        "node_selector": {...},
        "tolerations": [...],
        "priority_class_name": "...",
    },
)

ScaffoldConfig / EnvironmentConfig

Standard vocabulary types you can use inside workflow.params:

from interaxions.schemas import ScaffoldConfig, EnvironmentConfig

scaffold_cfg = ScaffoldConfig(
    repo_name_or_path="org/swe-agent",
    revision="v1.0.0",
    params={"max_iterations": 50},
)

env_cfg = EnvironmentConfig(
    repo_name_or_path="org/swe-bench",
    id="django__django-12345",       # required instance id
    params={"fix_hack": True},
)

Environment (data carrier)

Returned by BaseEnvironment.get(id):

from interaxions.schemas.task import Environment

env = env_task.get("django__django-12345")
env.id       # "django__django-12345"
env.type     # "swe-bench"
env.data     # {"problem_statement": "...", "repo": "...", ...}

Workflows can define typed subclasses for safe field access:

class SWEEnvironment(Environment):
    fix_hack: bool = False

    @classmethod
    def from_environment(cls, env: Environment, env_config: EnvironmentConfig) -> "SWEEnvironment":
        return cls(
            id=env.id, type=env.type, data=env.data,
            fix_hack=env_config.params.get("fix_hack", False),
        )

๐Ÿงช Testing

# Run all tests
pytest

# By category
pytest -m unit          # Fast isolated unit tests
pytest -m integration   # Component loading tests (local repos)
pytest -m e2e           # End-to-end pipeline tests

# With coverage
pytest --cov=interaxions --cov-report=html
open htmlcov/index.html

The test suite uses local mock repositories in tests/fixtures/mock_repos/ (no network access required):

Mock Repo Entry Class Purpose
test-scaffold/ TestScaffold Test AutoScaffold loading
test-environment/ TestEnvironment Test AutoEnvironment loading + get()
test-workflow/ TestWorkflow Test AutoWorkflow loading + template loading

๐Ÿ“ Project Structure

interaxions/
โ”œโ”€โ”€ scaffolds/
โ”‚   โ”œโ”€โ”€ base_scaffold.py        # BaseScaffold + BaseScaffoldConfig
โ”‚   โ””โ”€โ”€ __init__.py
โ”œโ”€โ”€ environments/
โ”‚   โ”œโ”€โ”€ base_environment.py     # BaseEnvironment + BaseEnvironmentConfig
โ”‚   โ””โ”€โ”€ __init__.py
โ”œโ”€โ”€ workflows/
โ”‚   โ”œโ”€โ”€ base_workflow.py        # BaseWorkflow + BaseWorkflowConfig
โ”‚   โ””โ”€โ”€ __init__.py
โ”œโ”€โ”€ schemas/
โ”‚   โ”œโ”€โ”€ job.py                  # XJob
โ”‚   โ”œโ”€โ”€ workflow.py             # WorkflowConfig
โ”‚   โ”œโ”€โ”€ runtime.py              # RuntimeConfig
โ”‚   โ”œโ”€โ”€ scaffold.py             # ScaffoldConfig
โ”‚   โ”œโ”€โ”€ environment.py          # EnvironmentConfig
โ”‚   โ”œโ”€โ”€ task.py                 # Environment (data carrier)
โ”‚   โ””โ”€โ”€ models.py               # OpenAIModel, AnthropicModel, LiteLLMModel
โ””โ”€โ”€ hub/
    โ”œโ”€โ”€ auto.py                 # AutoScaffold, AutoEnvironment, AutoWorkflow
    โ”œโ”€โ”€ hub_manager.py          # Git clone / checkout / caching
    โ””โ”€โ”€ constants.py

tests/
โ”œโ”€โ”€ unit/                       # Schema and model unit tests
โ”œโ”€โ”€ integration/                # Auto* loading tests (local mock repos)
โ”œโ”€โ”€ e2e/                        # Full pipeline tests
โ”œโ”€โ”€ fixtures/
โ”‚   โ””โ”€โ”€ mock_repos/
โ”‚       โ”œโ”€โ”€ test-scaffold/      # ix.py + config.yaml
โ”‚       โ”œโ”€โ”€ test-environment/   # ix.py + config.yaml
โ”‚       โ””โ”€โ”€ test-workflow/      # ix.py + config.yaml + templates/
โ””โ”€โ”€ conftest.py

๐Ÿ”„ Development

# Setup
git clone https://github.com/Hambaobao/interaxions.git
cd interaxions
pip install -e ".[dev]"

# Test
pytest -m unit          # fastest
pytest                  # all tests

# Coverage
pytest --cov=interaxions --cov-report=term-missing

๐Ÿ“– Documentation


๐Ÿค Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Ensure all tests pass: pytest
  5. Submit a pull request

๐Ÿ“„ License

MIT License โ€” see LICENSE for details.

๐Ÿ™ Acknowledgments


Made with โค๏ธ for the AI agent research community

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

interaxions-0.0.10.tar.gz (46.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

interaxions-0.0.10-py3-none-any.whl (34.4 kB view details)

Uploaded Python 3

File details

Details for the file interaxions-0.0.10.tar.gz.

File metadata

  • Download URL: interaxions-0.0.10.tar.gz
  • Upload date:
  • Size: 46.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for interaxions-0.0.10.tar.gz
Algorithm Hash digest
SHA256 f3ac88ed2f01abbcaa58b7e9b62a4fb7e74ca1c1894c8939750d0470681b80e1
MD5 022c48b71a8acce15720ea128d8fe147
BLAKE2b-256 a0c199e4244af72b529bff96ef2f5d089f98e5d12354250f900530fae3afd73e

See more details on using hashes here.

Provenance

The following attestation bundles were made for interaxions-0.0.10.tar.gz:

Publisher: python-publish.yaml on Hambaobao/interaxions

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file interaxions-0.0.10-py3-none-any.whl.

File metadata

  • Download URL: interaxions-0.0.10-py3-none-any.whl
  • Upload date:
  • Size: 34.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for interaxions-0.0.10-py3-none-any.whl
Algorithm Hash digest
SHA256 83562269a2c576885c90bd8524acecaa73678e70c9eef5590ef3c0333f7522a3
MD5 1b9276ae06c1c1f0686b55e8e7023b8e
BLAKE2b-256 26b6c6ca3cd75d350f6d551feff9592eac343419f74c45fb18d4a806bbcb3f16

See more details on using hashes here.

Provenance

The following attestation bundles were made for interaxions-0.0.10-py3-none-any.whl:

Publisher: python-publish.yaml on Hambaobao/interaxions

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page