AXAR AI Framework

repository·main·Indexed 41 days ago

https://github.com/axar-ai/axar

A lightweight, type-first TypeScript framework for building production-ready agentic applications powered by LLMs. AXAR uses decorators and dependency injection to provide explicit control over model behavior, tools, and structured data. Key features include @model for LLM configuration, @tool for external system interaction, and @schema for structured input/output validation. Version 0.0.7.

Tokens
8.2K
Snippets
29
Records
41
Agent score
51%

What's inside AXAR

  1. How AXAR agents work: Tools, Schemas, and Dynamic Prompts

    main

    AXAR agents can be extended with advanced features to create robust applications:

    • Structured Data (@schema, @output): Use the @schema() decorator to define classes for structured inputs or outputs. Use @property() to describe fields. The @output(SchemaClass) decorator on an agent ensures the LLM returns data matching that schema.
    • Tools (@tool): Define methods within your agent class and decorate them with @tool("description"). These methods become functions the agent can call to interact with external systems.
    • Dynamic Prompts (@systemPrompt): You can define methods decorated with @systemPrompt() that return a Promise<string>. AXAR will call these methods to inject dynamic context into the system prompt at runtime.
    • Dependency Injection: Since agents are standard TypeScript classes, you can use constructor injection to pass database connections, API clients, or other services into your agent.
    @schema()
    export class SupportResponse {
      @property('Human-readable advice to give to the customer.')
      support_advice!: string;
    
      @property("Whether to block customer's card.")
      block_card!: boolean;
    }
    
    @model('openai:gpt-4o-mini')
    @output(SupportResponse)
    export class SupportAgent extends Agent<string, SupportResponse> {
      constructor(private db: DatabaseConn) { super(); }
    
      @systemPrompt()
      async getCustomerContext(): Promise<string> {
        return `Context from DB`;
      }
    
      @tool("Get balance")
      async customerBalance(params: any): Promise<number> {
        return 123.45;
      }
    }
  2. Quickstart: Create a minimal AXAR agent

    main

    To create a basic agent, extend the Agent class and use decorators to define the model and system prompt. The Agent class is generic, taking the input type and output type as parameters (e.g., Agent<string, string>).

    import { model, systemPrompt, Agent } from '@axarai/axar';
    
    // Define the agent.
    @model('openai:gpt-4o-mini')
    @systemPrompt('Be concise, reply with one sentence')
    export class SimpleAgent extends Agent<string, string> {}
    
    // Run the agent.
    async function main() {
      const response = await new SimpleAgent().run(
        'Where does "hello world" come from?',
      );
      console.log(response);
    }
    
    main().catch(console.error);
  3. Setup and run AXAR examples

    main

    To run the provided examples in the AXAR repository, ensure you have Node.js (v18+) and an OpenAI API key. Follow these steps to install dependencies, build the project, and execute a specific example file using ts-node.

    # 1. Install dependencies
    npm install
    
    # 2. Build the project
    npm run build
    
    # 3. Set your OpenAI API key
    export OPENAI_API_KEY='your_api_key'
    
    # 4. Run a specific example
    npx ts-node examples/simple-agent.ts
  4. Install and configure AXAR for a new project

    main

    Follow these steps to set up a new AXAR project using npm and ts-node:

    1. Initialize project and install dependencies:
    mkdir axar-demo
    cd axar-demo
    npm init -y
    npm i @axarai/axar ts-node typescript
    npx tsc --init
    1. Configure tsconfig.json: AXAR requires specific compiler options for decorators to work. Ensure your tsconfig.json includes:
    {
      "compilerOptions": {
        "strict": true,
        "module": "CommonJS",
        "target": "es2020",
        "esModuleInterop": true,
        "experimentalDecorators": true,
        "emitDecoratorMetadata": true
      }
    }
    1. Run your agent: Set your provider's API key as an environment variable and use ts-node to execute your script:
    export OPENAI_API_KEY="sk-proj-YOUR-API-KEY"
    npx ts-node text-agent.ts
    WARNING

    AXAR currently requires ts-node because tsx does not yet fully support experimental decorators.

  5. Define input and output shapes with InputOutputType

    main

    When defining the schema for an agent's inputs or outputs, use the InputOutputType type. This allows you to specify the expected data structure using several methods:

    • Zod Schemas: Use z.object({...}) for complex validation.
    • Schema Constructors: Use custom schema constructors.
    • Primitives: Use standard JavaScript constructors like String, Number, or Boolean for simple types.
  6. Configure property-level options

    main

    You can provide metadata for individual properties within a schema using PropertyOptions. This is used to describe specific fields.

    Available options:

    • description: A human-readable description of the property.
    • example: An example value for the property.
    const propertyOptions: PropertyOptions = {
      description: 'The primary email address of the user',
      example: 'dev@axar.ai'
    };
  7. Configure schema-level options

    main

    When defining a schema, you can provide metadata for the entire schema using SchemaOptions. This is typically used with schema-level decorators to provide context for documentation or examples.

    Available options:

    • description: A human-readable description of the schema.
    • example: An example value representing valid schema data.
    • deprecated: A boolean indicating if the schema is deprecated.
    const options: SchemaOptions = {
      description: 'A schema representing a user profile',
      example: { id: '123', email: 'user@example.com' },
      deprecated: false
    };
  8. Configure agent execution with OutputConfig

    main

    The OutputConfig interface defines the parameters for running an agent and handling its output. It includes core execution settings and model-specific sampling parameters.

    Core Execution Fields:

    • model: The LanguageModelV1 instance to use.
    • messages: An array of CoreMessage[] representing the conversation history.
    • tools: A record of CoreTool objects available to the agent.
    • maxSteps: The maximum number of steps (including tool calls) allowed in a single execution.
    • toolChoice: Set to 'auto' to allow the model to use tools, or 'none' to disable tool usage.
    • maxRetries: Maximum number of retries for failed requests.

    Model Sampling Parameters:

    • maxTokens: Maximum number of tokens to generate.
    • temperature: Sampling temperature (0 to 1).
    • topP: Nucleus sampling.
    • topK: Top-K sampling.
    • presencePenalty: Penalty for token presence (-2.0 to 2.0).
    • frequencyPenalty: Penalty for token frequency (-2.0 to 2.0).

    Experimental Features:

    • experimental_telemetry: Configuration for telemetry with isEnabled (boolean) and functionId (string).
    • experimental_output: Configuration for experimental output handling.
  9. Configure language model parameters with ModelConfig

    main

    Use ModelConfig to fine-tune the behavior of the underlying language model. This is a subset of the full agent configuration focused specifically on generation and sampling.

    KeyTypeDescription
    maxTokensnumberMaximum number of tokens to generate
    temperaturenumberSampling temperature (0 to 1). Use either temperature or topP, not both
    topPnumberNucleus sampling. Use either temperature or topP, not both
    topKnumberTop K options for each subsequent token
    presencePenaltynumberPenalty for token presence (-2.0 to 2.0)
    frequencyPenaltynumberPenalty for token frequency (-2.0 to 2.0)
    maxRetriesnumberMaximum number of retries for failed requests
    maxStepsnumberMaximum number of steps in a conversation
    toolChoice'auto' | 'none'Tool choice mode
  10. Reference: Agent Decorators and Schema Annotations

    main

    The following decorators are used to configure agent behavior and data structures:

    Agent Configuration:

    • @model(modelName: string): Specifies the LLM model to use (e.g., 'openai:gpt-4o-mini').
    • @systemPrompt(prompt?: string | (() => Promise<string>)): Sets the system-level instructions. If a method is decorated with this, it provides dynamic context.
    • @output(schemaClass: any): Defines the expected structured output format for the agent.
    • @tool(description: string): Marks a class method as a tool available to the agent.

    Schema and Property Annotations:

    • @schema(): Marks a class as a structured data schema.
    • @property(description: string): Describes a field within a schema.
    • @optional(): Marks a property as optional.
    • @min(value: number) / @max(value: number): Defines numeric constraints for schema properties.
  11. Add system prompts with @systemPrompt

    main

    The @systemPrompt decorator allows you to provide instructions to the LLM. It can be used in two ways:

    1. Class-level (Static): Pass a string to the decorator on the class. This prompt is prepended to the list of system prompts for the class.
    2. Method-level (Dynamic): Apply the decorator to a method without arguments. The method must return a string or a Promise<string>. This allows you to generate prompts dynamically based on the agent's state.
    // Static class-level prompt
    @systemPrompt("Static system prompt.")
    class ExampleClass {
      // Class implementation
    }
    
    // Dynamic method-level prompt
    class ExampleClass {
      @systemPrompt
      async dynamicPromptMethod(): Promise<string> {
        return "Dynamic system prompt from the method.";
      }
    }