Agents and Interactions Guide

This guide provides a comprehensive overview of Agents and Interactions in Maitento - the core building blocks for creating AI-powered workflows that can collaborate, solve problems, and automate complex tasks.


Table of Contents

  1. What are Agents
  2. AI Models
  3. Interaction Types
  4. Creating and Configuring Agents
  5. Running Interactions
  6. API Reference Summary
  7. SDK Usage Examples
  8. Shell Commands

What are Agents

Agents are reusable, versioned AI entities that serve as the intelligent building blocks of Maitento. Each agent encapsulates:

  • An AI Model: The underlying language model (Claude, GPT, etc.) that powers the agent’s intelligence
  • A System Prompt: Instructions that define the agent’s behavior, personality, and expertise
  • External Operations: Tools and functions the agent can invoke to interact with external systems
  • A Summary: A description used by other agents to understand this agent’s capabilities in multi-agent scenarios

Key Characteristics

FeatureDescription
VersioningEvery configuration change creates a new version, preserving history
Multi-TenancyAgents are scoped to tenants and namespaces for isolation
Immutable VersionsOnce created, a version cannot be modified
Audit TrailComplete history of all versions with timestamps

Agent Lifecycle

Creation → Active → Updated → [New Version Created] → Active

                         [Old Version Disabled]

States:

  • Created: Initial version (version 1) is created with enabled status
  • Active: Agent is available for use in interactions
  • Updated: New version created; previous version remains in history
  • Disabled: Version marked as disabled; won’t be selected for new uses
  • Deleted: Agent entity soft-deleted with timestamp

Agent Versioning

Agents support unlimited versions, enabling iterative improvements while maintaining backward compatibility:

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "customer-support-agent",
  "versions": [
    {
      "version": 2,
      "date": "2024-01-20T16:45:00Z",
      "isDisabled": false,
      "aiModelId": "cc0e8400-e29b-41d4-a716-446655440007",
      "systemPrompt": "You are an advanced customer support agent...",
      "summaryForOtherAgents": "Advanced customer support agent"
    },
    {
      "version": 1,
      "date": "2024-01-15T10:00:00Z",
      "isDisabled": true,
      "aiModelId": "990e8400-e29b-41d4-a716-446655440004",
      "systemPrompt": "You are a helpful customer support agent...",
      "summaryForOtherAgents": "Handles customer inquiries"
    }
  ]
}

AI Models

Maitento provides a provider-agnostic framework supporting multiple AI providers with different capabilities.

Supported Providers

OpenAI Models

ModelTypeUse Case
gpt-5.1InteractionAdvanced reasoning and text generation
gpt-4oInteractionGPT-4 Omni - balanced performance
gpt-4o-miniInteractionCost-effective for simpler tasks
o3InteractionOpenAI O3 reasoning model
o3-miniInteractionLightweight reasoning
text-embedding-3-largeEmbeddingDocument vectorization and semantic search
gpt-image-1Image GenerationImage synthesis from text

Anthropic Models

ModelTypeUse Case
claude-opus-4-5InteractionMost capable Claude model
claude-sonnet-4-5InteractionBalanced performance and cost
claude-haiku-4-5InteractionFast, cost-effective responses

Model Types

TypeInterfaceDescription
InteractionIInteractionAiModelChat/conversation models for agent interactions
EmbeddingIEmbeddingsAiModelText embedding generation for semantic search
Image GenerationIImageGenerationAiModelImage synthesis from text prompts
Image DescribingIImageDescribingAiModelImage understanding and captioning

Model Configuration

Models are configured at the system level and made available to agents via their unique identifiers:

{
  "openAi": {
    "apiKey": "sk-...",
    "organisationId": "org-..."
  },
  "anthropic": {
    "apiKey": "sk-ant-..."
  }
}

Interaction Types

Interactions are conversation-based workflows that orchestrate AI agents collaborating on tasks. Maitento supports four distinct interaction patterns.

OneShot Interactions

Purpose: Single-agent, single-turn task execution

CharacteristicValue
AgentsSingle (exactly 1)
TurnsSingle
CollaborationN/A
Use CasesData extraction, analysis, format conversion

Configuration:

{
  "name": "document-summarizer",
  "prompt": "Summarize the following document: {{document}}",
  "solutionSchema": "{\"type\": \"object\", \"properties\": {\"summary\": {\"type\": \"string\"}}}",
  "agent": {
    "name": "summarizer",
    "agent": { "id": "...", "version": 1 }
  }
}

RoundRobin Interactions

Purpose: Multi-agent collaborative discussion with turn-taking

CharacteristicValue
AgentsMultiple (2+, or 1+ with human)
TurnsMultiple rounds
CollaborationAgents see each other’s messages
FeaturesVoting, direct questioning, solution proposals
Human-in-LoopOptional human participation

Configuration:

{
  "name": "code-review-discussion",
  "prompt": "Review the following code: {{code}}",
  "agents": [
    { "name": "security-reviewer", "agent": { "id": "...", "version": 1 } },
    { "name": "performance-reviewer", "agent": { "id": "...", "version": 1 } }
  ],
  "isVotingAllowed": true,
  "isDirectQuestioningAllowed": true,
  "isSolutionProposalAllowed": true,
  "humanSettings": {
    "chatMode": "GoesLast",
    "includeInVotes": true,
    "includeInSolutions": true
  },
  "maximumNoActionLoops": 3
}

Managed Interactions

Purpose: Hierarchical control with a manager agent coordinating workers

CharacteristicValue
Agents1 Manager + 1+ Workers
ControlManager directs workers
Use CasesComplex multi-step workflows

Configuration:

{
  "name": "project-workflow",
  "prompt": "Complete the following task: {{task}}",
  "managerAgent": {
    "name": "project-manager",
    "agent": { "id": "...", "version": 1 }
  },
  "agents": [
    { "name": "developer", "agent": { "id": "...", "version": 1 } },
    { "name": "tester", "agent": { "id": "...", "version": 1 } }
  ]
}

Routed Interactions

Purpose: Dynamic agent assignment via a routing agent

CharacteristicValue
Agents1 Router + 1+ Available Agents
RoutingRouter decides which agent handles each request
Use CasesCustomer support triage, dynamic task delegation

Configuration:

{
  "name": "support-router",
  "prompt": "Handle the following request: {{request}}",
  "routingAgent": {
    "name": "router",
    "agent": { "id": "...", "version": 1 }
  },
  "agents": [
    { "name": "billing-support", "agent": { "id": "...", "version": 1 } },
    { "name": "technical-support", "agent": { "id": "...", "version": 1 } }
  ]
}

Interaction Type Comparison

FeatureOneShotRoundRobinManagedRouted
Agent Count12+ (or 1+ with human)1 manager + 1+ workers1 router + 1+ targets
Turn StructureSingleRound-robin loopManager-directedRouter-selected
Human ParticipationN/AConfigurableN/AN/A
VotingNoOptionalNoNo
Solution ProposalsSingle outputConsensus-basedManager decidesSelected agent responds

Creating and Configuring Agents

Via API

Create Agent:

POST /namespaces/production/agents
Content-Type: application/json
Authorization: Bearer <token>

{
  "name": "customer-support-agent",
  "aiModelId": "990e8400-e29b-41d4-a716-446655440004",
  "systemPrompt": "You are a helpful customer support agent. Your role is to assist customers with their inquiries, resolve issues, and provide information about our products and services.",
  "summaryForOtherAgents": "Handles customer inquiries, resolves support issues, and provides product information",
  "externalOperationReferences": [
    {
      "externalOperationId": "aa0e8400-e29b-41d4-a716-446655440005",
      "promptGuidance": "Use this operation to look up customer information"
    }
  ]
}

Update Agent (creates new version):

PUT /agents/by-id/550e8400-e29b-41d4-a716-446655440000
Content-Type: application/json
Authorization: Bearer <token>

{
  "name": "customer-support-agent",
  "aiModelId": "cc0e8400-e29b-41d4-a716-446655440007",
  "systemPrompt": "You are an advanced customer support agent with enhanced capabilities...",
  "summaryForOtherAgents": "Advanced customer support agent with enhanced problem-solving",
  "externalOperationReferences": []
}

Via SDK

using var client = MaitentoClient.Create("your-api-key");

// Create an agent
Agent supportAgent = await client.Agents.CreateAsync(
    namespaceName: "production",
    name: "Support Assistant",
    aiModelId: Guid.Parse("550e8400-e29b-41d4-a716-446655440001"),
    systemPrompt: @"You are a helpful customer support assistant.
Your role is to:
- Answer customer questions about our products
- Help troubleshoot common issues
- Escalate complex problems to human agents",
    summaryForOtherAgents: "Handles customer inquiries and support requests"
);

Console.WriteLine($"Created agent: {supportAgent.Name} (ID: {supportAgent.Id})");

// Update an agent
Agent updated = await client.Agents.UpdateAsync(
    id: supportAgent.Id,
    name: "Enhanced Support Assistant",
    aiModelId: supportAgent.Versions[0].AiModelId,
    systemPrompt: "Updated system prompt...",
    summaryForOtherAgents: "Enhanced support assistant"
);

Console.WriteLine($"Updated to version: {updated.Versions.Max(v => v.Version)}");

Via Shell

# Create an agent
> agent-create customer-support \
    --ai-model-id 12345678-1234-1234-1234-123456789012 \
    --system-prompt "You are a helpful customer support agent." \
    --summary "Handles customer inquiries and support tickets"

Agent 'customer-support' created (a1b2c3d4-e5f6-7890-abcd-ef1234567890)

# Update an agent
> agent-update customer-support \
    --system-prompt "You are an enhanced customer support agent with improved capabilities."

Agent 'customer-support' updated (a1b2c3d4-e5f6-7890-abcd-ef1234567890)

# List agents
> agent-list --namespace production

# Get agent details
> agent-get customer-support --namespace production

Running Interactions

Interaction Process Lifecycle

New → Running → [HumanInteractionRequired] → HumanInteractionComplete → Finished
         ↓                                           ↓
       Error                                       Killed
StatusDescription
NewProcess created, not yet started
RunningActively executing
HumanInteractionRequiredWaiting for human input
HumanInteractionCompleteHuman responded, resuming
FinishedSuccessfully completed
ErrorFailed with error
KilledManually terminated

Starting an Interaction via API

By ID:

PUT /interactions/processes/by-id/550e8400-e29b-41d4-a716-446655440000/start
Content-Type: application/json
Authorization: Bearer <token>

{
  "inputs": [
    { "name": "document", "value": "Document content to summarize..." }
  ]
}

By Name:

PUT /namespaces/production/interactions/by-name/document-summarizer/start
Content-Type: application/json
Authorization: Bearer <token>

{
  "inputs": [
    { "name": "document", "value": "Document content to summarize..." }
  ]
}

Human-in-the-Loop Operations

Add a message:

POST /interactions/processes/by-id/{processId}/add-message
Content-Type: application/json

{
  "message": "I agree with the security concerns raised.",
  "messageAuthorName": "John Smith",
  "messageAuthorId": "880e8400-e29b-41d4-a716-446655440017"
}

Vote Yes:

POST /interactions/processes/by-id/{processId}/vote/yes
Content-Type: application/json

{
  "messageAuthorName": "John Smith",
  "messageAuthorId": "880e8400-e29b-41d4-a716-446655440017"
}

Vote No:

POST /interactions/processes/by-id/{processId}/vote/no
Content-Type: application/json

{
  "messageAuthorName": "Jane Doe",
  "messageAuthorId": "990e8400-e29b-41d4-a716-446655440018",
  "reason": "The proposed solution does not address performance concerns."
}

API Reference Summary

Agents API

MethodEndpointDescription
GET/agentsGet all agents in tenant
GET/namespaces/{ns}/agentsGet agents in namespace
GET/agents/by-id/{id}Get agent by ID
GET/namespaces/{ns}/agents/by-name/{name}Get agent by name
POST/namespaces/{ns}/agentsCreate agent
PUT/agents/by-id/{id}Update agent

AI Models API

MethodEndpointDescription
GET/ai-modelsList all available AI models

Interactions API

MethodEndpointDescription
GET/interactionsGet all interactions
GET/namespaces/{ns}/interactionsGet interactions in namespace
GET/interactions/by-id/{id}Get interaction by ID
GET/namespaces/{ns}/interactions/by-name/{name}Get interaction by name
POST/namespaces/{ns}/interactions/one-shotCreate OneShot interaction
PUT/interactions/one-shot/by-id/{id}Update OneShot interaction
POST/namespaces/{ns}/interactions/round-robinCreate RoundRobin interaction
PUT/interactions/round-robin/by-id/{id}Update RoundRobin interaction
POST/namespaces/{ns}/interactions/managedCreate Managed interaction
PUT/interactions/managed/by-id/{id}Update Managed interaction
POST/namespaces/{ns}/interactions/routedCreate Routed interaction
PUT/interactions/routed/by-id/{id}Update Routed interaction

Interaction Processes API

MethodEndpointDescription
GET/interactions/processesGet all processes
GET/interactions/processes/by-id/{id}Get process by ID
GET/namespaces/{ns}/interactions/processesGet active processes in namespace
PUT/interactions/processes/by-id/{id}/startStart process by interaction ID
PUT/namespaces/{ns}/interactions/by-name/{name}/startStart process by name
POST/interactions/processes/by-id/{id}/add-messageAdd human message
POST/interactions/processes/by-id/{id}/vote/yesCast yes vote
POST/interactions/processes/by-id/{id}/vote/noCast no vote

SDK Usage Examples

Agent Management

using Maitento.Sdk;
using Maitento.Sdk.Services;
using Maitento.Entities.Agents;

// Initialize client
await using IMaitentoClient client = MaitentoClient.Create("your-api-key");

// List all agents in a namespace
Agent[] agents = await client.Agents.GetAllInNamespaceAsync("production");
foreach (var agent in agents)
{
    Console.WriteLine($"Agent: {agent.Name} (ID: {agent.Id})");
}

// Get a specific agent by name
Agent? supportAgent = await client.Agents.GetByNameAsync("production", "customer-support");
if (supportAgent != null)
{
    var latestVersion = supportAgent.Versions
        .Where(v => !v.IsDisabled)
        .OrderByDescending(v => v.Version)
        .FirstOrDefault();

    Console.WriteLine($"Latest version: {latestVersion?.Version}");
    Console.WriteLine($"System prompt: {latestVersion?.SystemPrompt}");
}

// Create an agent with external operations
var externalOps = new AgentExternalOperationReference[]
{
    new AgentExternalOperationReference(
        Guid.Parse("123e4567-e89b-12d3-a456-426614174001"),
        "Use this operation to look up customer data."
    )
};

Agent newAgent = await client.Agents.CreateAsync(
    namespaceName: "production",
    name: "Data Lookup Agent",
    aiModelId: Guid.Parse("550e8400-e29b-41d4-a716-446655440001"),
    systemPrompt: "You are a data lookup agent that retrieves customer information.",
    summaryForOtherAgents: "Retrieves customer data from the database.",
    externalOperationReferences: externalOps
);

Creating and Running Interactions

using Maitento.Sdk;
using Maitento.Entities.Interactions;

await using IMaitentoClient client = MaitentoClient.Create("your-api-key");

// Create a OneShot interaction
var agent = new InteractionAgentBinding(
    agent: new VersionReference(agentId, version: 1),
    name: "Summarizer",
    externalOperationsMcp: Array.Empty<McpExternalOperationBinding>(),
    externalOperationsOpenApi: Array.Empty<OpenApiExternalOperationBinding>()
);

var promptInputs = new[]
{
    new PromptInput("document", "The document to summarize", InteractionInputType.String, isRequired: true)
};

OneShotInteraction interaction = await client.Interactions.CreateOneShotAsync(
    namespaceName: "production",
    name: "document-summarizer",
    prompt: "Summarize the following document:\n\n{{document}}",
    solutionSchema: null,
    systemPromptMode: InteractionSystemPromptMode.AppendToDefault,
    systemPrompts: new[] { "Produce clear, concise summaries." },
    durationWarningToAi: null,
    durationAutoTermination: TimeSpan.FromMinutes(5),
    externalOperationsMcp: Array.Empty<McpExternalOperationBinding>(),
    externalOperationsOpenApi: Array.Empty<OpenApiExternalOperationBinding>(),
    promptInputs: promptInputs,
    connectorBindingInputs: Array.Empty<ConnectorBindingInput>(),
    connectorAuthenticationSecretInputs: Array.Empty<ConnectorAuthenticationSecretInput>(),
    agent: agent
);

Console.WriteLine($"Created interaction: {interaction.Id}");

// Start the interaction
var inputs = new[]
{
    new NameValuePair("document", "This is a long document that needs to be summarized...")
};

InteractionProcess process = await client.InteractionProcesses.StartAsync(
    interactionId: interaction.Id,
    inputs: inputs
);

Console.WriteLine($"Started process: {process.Id}");

// Poll for completion
while (process.Status == InteractionProcessStatus.Running ||
       process.Status == InteractionProcessStatus.New)
{
    await Task.Delay(TimeSpan.FromSeconds(5));
    process = await client.InteractionProcesses.GetInstanceAsync(process.Id);
}

if (process.Status == InteractionProcessStatus.Finished)
{
    Console.WriteLine($"Output: {process.Output}");
}
else if (process.Status == InteractionProcessStatus.Error)
{
    Console.WriteLine($"Error: {process.FailureDetails}");
}

RoundRobin with Human Participation

// Create a RoundRobin interaction with human-in-the-loop
var agents = new[]
{
    new InteractionAgentBinding(
        agent: new VersionReference(analyst1Id, version: 1),
        name: "Security Analyst",
        externalOperationsMcp: Array.Empty<McpExternalOperationBinding>(),
        externalOperationsOpenApi: Array.Empty<OpenApiExternalOperationBinding>()
    ),
    new InteractionAgentBinding(
        agent: new VersionReference(analyst2Id, version: 1),
        name: "Performance Analyst",
        externalOperationsMcp: Array.Empty<McpExternalOperationBinding>(),
        externalOperationsOpenApi: Array.Empty<OpenApiExternalOperationBinding>()
    )
};

var humanSettings = new RoundRobinInteractionHumanSettings(
    chatMode: HumanChatMode.GoesLast,
    includeInVotes: true,
    includeInSolutions: true
);

RoundRobinInteraction roundRobin = await client.Interactions.CreateRoundRobinAsync(
    namespaceName: "production",
    name: "code-review",
    prompt: "Review the following code and discuss improvements: {{code}}",
    solutionSchema: null,
    systemPromptMode: InteractionSystemPromptMode.AppendToDefault,
    systemPrompts: new[] { "Be thorough and collaborative." },
    durationWarningToAi: TimeSpan.FromMinutes(5),
    durationAutoTermination: TimeSpan.FromMinutes(30),
    externalOperationsMcp: Array.Empty<McpExternalOperationBinding>(),
    externalOperationsOpenApi: Array.Empty<OpenApiExternalOperationBinding>(),
    promptInputs: new[] { new PromptInput("code", "Code to review", InteractionInputType.String, true) },
    connectorBindingInputs: Array.Empty<ConnectorBindingInput>(),
    connectorAuthenticationSecretInputs: Array.Empty<ConnectorAuthenticationSecretInput>(),
    agents: agents,
    isNoActionAllowed: false,
    isVotingAllowed: true,
    isDirectQuestioningAllowed: true,
    isSolutionProposalAllowed: true,
    humanSettings: humanSettings,
    maximumNoActionLoops: 3
);

// Start the interaction
var process = await client.InteractionProcesses.StartAsync(
    namespaceName: "production",
    name: "code-review",
    inputs: new[] { new NameValuePair("code", "function example() { /* ... */ }") }
);

// When process requires human interaction
if (process.Status == InteractionProcessStatus.HumanInteractionRequired)
{
    // Add a human message
    await client.InteractionProcesses.AddMessageAsync(
        id: process.Id,
        messageAuthorName: "John Smith",
        messageAuthorId: Guid.Parse("123e4567-e89b-12d3-a456-426614174000"),
        message: "I agree with the security concerns. We should also consider rate limiting."
    );

    // Or vote on a proposal
    await client.InteractionProcesses.VoteYesAsync(
        id: process.Id,
        messageAuthorName: "John Smith",
        messageAuthorId: Guid.Parse("123e4567-e89b-12d3-a456-426614174000")
    );
}

Shell Commands

Agent Commands

CommandDescription
agent-listList all agents, optionally filtered by namespace
agent-get <name>Get details of a specific agent
agent-create <name>Create a new agent
agent-update <name>Update an existing agent

Examples:

# List agents
> agent-list --namespace production

# Get agent details
> agent-get customer-support --namespace production

# Create an agent
> agent-create my-agent \
    --ai-model-id 12345678-1234-1234-1234-123456789012 \
    --system-prompt "You are a helpful assistant." \
    --summary "General purpose assistant"

# Update an agent
> agent-update my-agent \
    --system-prompt "Enhanced system prompt..."

Interaction Commands

CommandDescription
interaction-listList all interactions
interaction-get <name>Get interaction details
interaction-start <name>Start an interaction (non-blocking)
interaction-run <name>Run an interaction and wait for completion
interaction-attach <id>Attach to a running interaction
interaction-psList active interaction processes
interaction-add-messageAdd a message to an interaction
interaction-vote-yesVote yes on a proposal
interaction-vote-noVote no on a proposal

Examples:

# List interactions
> interaction-list --namespace production

# Start an interaction with inputs
> interaction-start document-summarizer \
    --namespace production \
    --input-document "Document content..."

# Run and wait for completion (with streaming)
> interaction-run my-interaction --stream --input-query "What is the status?"

# Attach to monitor a running process
> interaction-attach 550e8400-e29b-41d4-a716-446655440000 --stream

# List active processes
> interaction-ps --namespace production

# Add a human message
> interaction-add-message 550e8400-e29b-41d4-a716-446655440000 "John Doe" a1b2c3d4-... "My response"

# Vote on a proposal
> interaction-vote-yes 550e8400-e29b-41d4-a716-446655440000 "John Doe" a1b2c3d4-...
> interaction-vote-no 550e8400-e29b-41d4-a716-446655440000 "Jane Doe" b2c3d4e5-... "Not suitable"

Author Defaults

Configure default author credentials for interaction commands:

# Set defaults
> interaction-author-defaults-set "John Doe" a1b2c3d4-e5f6-7890-abcd-ef1234567890

# Get current defaults
> interaction-author-defaults-get

# With defaults set, simplified commands work:
> interaction-add-message 550e8400-... "My message"
> interaction-vote-yes 550e8400-...

Best Practices

Agent Design

  1. Clear System Prompts: Write detailed, specific system prompts that clearly define the agent’s role and boundaries
  2. Meaningful Summaries: Provide accurate summaries so other agents can understand capabilities in multi-agent scenarios
  3. External Operation Guidance: Include clear promptGuidance for each external operation to help the agent understand when and how to use them
  4. Version Management: Test new versions thoroughly before disabling old ones

Interaction Design

  1. Choose the Right Type:

    • Use OneShot for simple, single-task operations
    • Use RoundRobin when multiple perspectives or consensus is needed
    • Use Managed for complex workflows requiring coordination
    • Use Routed for dynamic task delegation
  2. Set Appropriate Timeouts: Configure durationWarningToAi and durationAutoTermination to prevent runaway processes

  3. Solution Schemas: Use JSON schemas to validate and structure agent outputs when a specific format is required

  4. Human-in-the-Loop: Enable human participation in RoundRobin interactions when human judgment or approval is important


Error Handling

Common API Errors

Status CodeDescriptionResolution
400 Bad RequestValidation errorsCheck request body for missing/invalid fields
401 UnauthorizedInvalid credentialsVerify API key or token
403 ForbiddenInsufficient permissionsCheck user roles (Tenant.Admin or Tenant.User)
404 Not FoundResource not foundVerify ID/name and namespace

SDK Exception Handling

try
{
    var agent = await client.Agents.CreateAsync(...);
}
catch (MaitentoValidationException ex)
{
    foreach (var error in ex.ValidationErrors)
    {
        Console.WriteLine($"{error.Key}: {string.Join(", ", error.Value)}");
    }
}
catch (MaitentoApiException ex)
{
    Console.WriteLine($"API error ({ex.StatusCode}): {ex.ResponseBody}");
}
catch (MaitentoApiAuthenticationException ex)
{
    Console.WriteLine("Authentication failed - check your API key");
}

See Also