AgentOp

Template System

Create reusable templates with HTML, CSS, and prompt configurations

Overview

AgentOp templates are versioned, reusable blueprints that define everything a browser AI agent needs: the HTML/CSS/JS interface that users interact with, the Python tool functions that execute in-browser via Pyodide (WebAssembly), the system and user prompt configuration, and the default Python packages to load. When someone creates an agent from a template, they receive a fully wired-up starting point — they only need to customise the Python logic and prompts for their specific use case.

This makes AgentOp templates a powerful accelerator for building browser-executable AI agents. Instead of writing HTML scaffolding, Pyodide bootstrapping, LangChain wiring, and WebLLM integration from scratch, you start from a working template and focus exclusively on the domain-specific Python code that makes your agent unique.

Template Components

1. Presentation Layer

  • HTML Code: Structure and layout of the agent interface
  • CSS Code: Styling and visual design
  • JavaScript Code: Client-side interactivity

2. Behavioral Defaults

  • Python Code: Default agent logic and tools
  • System Prompt: Agent personality and instructions
  • User Prompt Template: How to format user input
  • Few-Shot Examples: Example interactions
  • Prompt Variables: Configurable placeholders

3. Configuration

  • Default Packages: Python dependencies
  • Memory Settings: Conversation history configuration
  • Metadata: Name, description, tags, category

Creating a Template

Step 1: Navigate to Template Builder

Go to /templates/new/ to start creating a template.

Step 2: Fill Metadata

  • Name: Unique, descriptive name
  • Description: What agents built from this template will do
  • Category: chatbot, data-analysis, code-assistant, etc.
  • Tags: For discovery and organization

Step 3: Design the Interface

HTML Structure

Define the layout using template variables. Note the type="text/python" on the Python script tag — this tells the browser it is not JavaScript:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{agent_name}}</title>
    <style>{{css_code}}</style>
</head>
<body>
    <div class="container">
        <h1>{{agent_name}}</h1>
        <p class="description">{{description}}</p>

        <div id="chat-container">
            <div id="messages"></div>
            <input type="text" id="user-input" placeholder="Type a message...">
            <button id="send-btn">Send</button>
        </div>
    </div>

    <!-- Python code runs via Pyodide, not as native JS -->
    <script type="text/python" id="python-code">{{python_code}}</script>
    <script>{{js_code}}</script>
</body>
</html>

Template Variables

Use these placeholders that get replaced when generating agents:

  • {{agent_name}} - Agent's display name
  • {{description}} - Agent description
  • {{css_code}} - CSS styles from template
  • {{js_code}} - JavaScript from template
  • {{python_code}} - Python agent logic

CSS Styling

Style your template's interface:

body {
    font-family: system-ui, sans-serif;
    max-width: 800px;
    margin: 0 auto;
    padding: 20px;
    background: #f5f5f5;
}

.container {
    background: white;
    border-radius: 12px;
    padding: 24px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

#chat-container {
    margin-top: 20px;
}

#messages {
    height: 400px;
    overflow-y: auto;
    border: 1px solid #e5e5e5;
    border-radius: 8px;
    padding: 16px;
    margin-bottom: 16px;
}

#user-input {
    width: calc(100% - 100px);
    padding: 10px;
    border: 1px solid #e5e5e5;
    border-radius: 6px;
}

#send-btn {
    width: 80px;
    padding: 10px;
    background: #10b981;
    color: white;
    border: none;
    border-radius: 6px;
    cursor: pointer;
}

JavaScript Interactivity

Add client-side logic to wire up the UI. AgentOp injects a global initAgent() function that bootstraps Pyodide, loads packages, registers your Python tools, and starts the LLM. Your template JS typically handles UI events and delegates queries to the orchestrator:

// Initialize UI and wire up send button
document.addEventListener('DOMContentLoaded', function() {
    const input = document.getElementById('user-input');
    const sendBtn = document.getElementById('send-btn');
    const messages = document.getElementById('messages');

    sendBtn.addEventListener('click', sendMessage);
    input.addEventListener('keypress', function(e) {
        if (e.key === 'Enter') sendMessage();
    });

    async function sendMessage() {
        const userText = input.value.trim();
        if (!userText) return;

        appendMessage('user', userText);
        input.value = '';

        // process_user_query is the Python entry point injected by AgentOp.
        // It routes to the correct provider (OpenAI, Anthropic, or WebLLM)
        // and handles tool calling automatically.
        // Pass the input via pyodide.globals.set() to avoid string-escaping
        // issues with backslashes, newlines, or other special characters.
        try {
            const pyodide = window.pyodide;
            pyodide.globals.set('_user_input', userText);
            const result = await pyodide.runPythonAsync(
                'await process_user_query(_user_input)'
            );
            appendMessage('agent', result);
        } catch (err) {
            appendMessage('agent', 'Error: ' + err.message);
        }
    }

    function appendMessage(role, text) {
        const div = document.createElement('div');
        div.className = `message ${role}`;
        div.textContent = text;
        messages.appendChild(div);
        messages.scrollTop = messages.scrollHeight;
    }
});

💡 For most templates, you don’t need custom JS

AgentOp's orchestrator (initAgent()) already wires up Pyodide, tool registration, and the LLM. The JavaScript above is a minimal example — the real data-analysis template, for instance, uses the orchestrator directly and only adds JS for file-upload handling and dashboard rendering.

Step 4: Configure Prompts

System Prompt

Define the agent's role and behavior:

You are a helpful assistant specializing in {{domain}}.
Your goal is to provide accurate and helpful information.

Guidelines:
- Be concise and clear
- Use tools when appropriate
- Ask clarifying questions if needed
- Stay within your domain of expertise

User Prompt Template

User: {input}

Context: {context}

Please provide a helpful response.

Prompt Variables

Define configurable variables in JSON format:

{
  "domain": {
    "type": "string",
    "default": "general assistance",
    "description": "The agent's area of expertise"
  },
  "tone": {
    "type": "string",
    "default": "professional",
    "options": ["professional", "casual", "formal"]
  }
}

Step 5: Add Default Python Code

Provide starter Python tool functions for agents using this template. AgentOp handles all LangChain / LangChain.js infrastructure automatically — template code only needs to define the async tool functions and export their schemas via get_tool_schemas():

import json

# Define async tool functions the agent can call.
# Use 'async def' — Pyodide runs these asynchronously.
# The docstring is used as the tool description sent to the LLM.
async def example_tool(query: str) -> str:
    """Process the user query and return a helpful result. Customize this for your use case."""
    # Replace with your real implementation (e.g. file parsing, API call, calculation)
    return f"Processed: {query}"

async def another_tool(input_text: str, max_results: int = 5) -> str:
    """Perform a secondary action with an optional result limit. Returns JSON-formatted output."""
    results = [f"item {i}" for i in range(max_results)]
    return json.dumps({"results": results})

def get_tool_schemas():
    """Return OpenAI-compatible function schemas for the JS\u2194Python bridge."""
    return [
        {
            "type": "function",
            "function": {
                "name": "example_tool",
                "description": "Process the user query and return a helpful result.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "query": {"type": "string", "description": "The query to process"}
                    },
                    "required": ["query"]
                }
            }
        },
        {
            "type": "function",
            "function": {
                "name": "another_tool",
                "description": "Perform a secondary action with an optional result limit.",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "input_text": {"type": "string", "description": "Text to process"},
                        "max_results": {"type": "integer", "description": "Max results to return (default 5)"}
                    },
                    "required": ["input_text"]
                }
            }
        }
    ]
# AgentOp injects the full LangChain orchestration around your code automatically.

💡 How tool functions work

You define async Python functions and a get_tool_schemas() function that describes them in OpenAI function-calling format. AgentOp's JavaScript↔Python bridge dispatches LLM tool calls to the correct Python function via Pyodide, then returns the result back to the LLM. No AgentExecutor or @tool decorator needed.

Step 6: Configure Packages

Specify default Python packages for agents built from this template:

{
  "pyodide_builtins": ["micropip"],
  "pypi_packages": {
    "python-dateutil": ">=2.8.0",
    "pyyaml": "*"
  }
}

💡 LangChain is auto-injected

Do not add langchain, langchain_openai, or langchain_anthropic here. AgentOp injects the correct LangChain packages automatically based on the provider chosen at agent-creation time. Only list packages your Python tool functions actually import.

Step 7: Preview and Test

Use the preview feature to see how your template looks with sample data. The preview runs in a sandboxed iframe for safety.

Step 8: Publish

Save your template and set it to "Active" to make it available for agent creation.

Template Versioning

Creating Versions

Templates support prompt versioning to track changes over time:

  1. Edit a template's prompts
  2. Click "Save as New Version"
  3. Add a description of changes
  4. The version is saved with a sequential number

Managing Versions

  • View History: See all saved versions
  • Compare: Diff two versions side-by-side
  • Activate: Restore an older version
  • Description: Each version has a change log

💡 Version Control Best Practices

Create a new version before making major prompt changes. This allows you to roll back if the changes don't work as expected.

Using Templates

When Creating Agents

When creating a new agent, you select a template which provides:

  • Initial HTML structure and styling
  • Default Python code to customize
  • Prompt configurations
  • Recommended packages

Customizing from Templates

After selecting a template, you can customize everything:

  • Modify the Python code
  • Adjust prompts and variables
  • Add or remove packages
  • Change metadata

Template Independence

Agents created from a template are independent. Changes to the template don't affect existing agents (only new agents created from it).

Best Practices

Template Design

  • Keep HTML structure simple and semantic
  • Use CSS variables for easy theming
  • Make layouts responsive for mobile devices
  • Include accessibility features (ARIA labels, keyboard navigation)

Code Quality

  • Provide well-commented default Python code
  • Include error handling examples
  • Use clear tool names and descriptions
  • Keep default implementations simple but functional

Prompts

  • Make system prompts clear and specific
  • Use variables for customizable parts
  • Provide helpful few-shot examples
  • Document variable options and defaults

Documentation

  • Write clear template descriptions
  • Explain what variables do
  • List required vs. optional packages
  • Include usage examples in the description

Sharing Templates

Public vs. System Templates

  • Public Templates: Created by users, visible to all
  • System Templates: Curated by AgentOp team, cannot be deleted

Template Marketplace

Popular templates appear in the template marketplace, sorted by:

  • Usage count (agents created from template)
  • Recently updated
  • Category
  • Creator

Next Steps