# How to Create, Configure, and Assign Tasks to Agents in Multica: A Complete Guide

> Learn to create, configure, and assign tasks to agents in Multica. This guide covers task creation, agent runtime settings, and effective work assignment for efficient task execution by the daemon. Get started today.

- Repository: [multica-ai/multica](https://github.com/multica-ai/multica)
- Tags: how-to-guide
- Published: 2026-04-11

---

**You create tasks in Multica using `TaskService` methods like `EnqueueTaskForIssue`, configure agents with runtime settings and `max_concurrent_tasks` limits, and assign work either by setting an agent as an issue assignee or mentioning them in comments, after which the daemon claims and executes tasks via the CLI.**

Multica treats every unit of AI agent work as a task stored in the `agent_task_queue` table. Understanding how to create, configure, and assign tasks to agents in Multica is essential for orchestrating automated workflows reliably. This guide examines the `TaskService` implementation in [`server/internal/service/task.go`](https://github.com/multica-ai/multica/blob/main/server/internal/service/task.go) and the agent schema in [`server/pkg/db/generated/agent.sql.go`](https://github.com/multica-ai/multica/blob/main/server/pkg/db/generated/agent.sql.go) to show you exactly how the task lifecycle operates from enqueue to completion.

## Creating Tasks in Multica

The `TaskService` in [`server/internal/service/task.go`](https://github.com/multica-ai/multica/blob/main/server/internal/service/task.go) provides three primary entry points for creating tasks, depending on the trigger source.

### Enqueue Tasks from Issue Assignments

When an issue’s `assignee_id` points to an agent, the backend calls `EnqueueTaskForIssue` (lines 33‑75 in [`server/internal/service/task.go`](https://github.com/multica-ai/multica/blob/main/server/internal/service/task.go)). This method validates the assignee, loads the agent record via `GetAgent`, and inserts a row into `agent_task_queue` using `CreateAgentTask`.

```go
func (s *TaskService) EnqueueTaskForIssue(
    ctx context.Context,
    issue db.Issue,
    triggerCommentID ...pgtype.UUID,
) (db.AgentTaskQueue, error)

```

The function maps the issue’s priority to an integer via `priorityToInt`, sets the agent’s `runtime_id` on the task, and optionally links a triggering comment ID. If the agent is archived or lacks a runtime, the enqueue fails immediately.

### Trigger Tasks via Agent Mentions

For explicit mentions (e.g., `@code-reviewer`), use `EnqueueTaskForMention` (lines 77‑108). This bypasses the issue assignee requirement and accepts an `agentID` directly, allowing any agent to be triggered regardless of the issue’s current assignee.

```go
func (s *TaskService) EnqueueTaskForMention(
    ctx context.Context,
    issue db.Issue,
    agentID pgtype.UUID,
    triggerCommentID pgtype.UUID,
) (db.AgentTaskQueue, error)

```

This method follows the same validation and insertion logic as `EnqueueTaskForIssue`, ensuring consistency in task creation while supporting flexible invocation patterns.

### Create Chat Session Tasks

For ad-hoc assistant interactions, `EnqueueChatTask` (lines 11‑38) creates a task linked to a `chat_session_id` with medium priority (value 2). This is useful for real-time help requests that do not originate from repository issues.

```go
func (s *TaskService) EnqueueChatTask(
    ctx context.Context,
    chatSession db.ChatSession,
) (db.AgentTaskQueue, error)

```

The method loads the agent associated with the chat session and inserts the task using `CreateChatTask`, returning the queued record for WebSocket broadcast.

## Configuring Agents for Task Execution

### Agent Configuration Fields

Before an agent can claim work, it must be properly configured in the `agent` table (defined in [`server/pkg/db/generated/agent.sql.go`](https://github.com/multica-ai/multica/blob/main/server/pkg/db/generated/agent.sql.go)). Key fields include:

- **`runtime_id`** – Links the agent to a runtime record that defines the daemon’s host and port.
- **`max_concurrent_tasks`** – Hard limit on parallel task execution; enforced by `ClaimTask` in [`server/internal/service/task.go`](https://github.com/multica-ai/multica/blob/main/server/internal/service/task.go).
- **`runtime_mode`** / **`runtime_config`** – JSON configuration passed to the daemon (e.g., Docker image, environment variables).
- **`status`** – Automatically updated by `TaskService.ReconcileAgentStatus` to `idle` or `working` based on active task count.

### Runtime Setup

The daemon binary (`cmd/multica daemon`) registers itself using environment variables `MULTICA_DAEMON_PORT` and `MULTICA_RUNTIME_ID`. Create the runtime and agent via CLI:

```bash

# Create a runtime endpoint

multica runtime create my-runtime --url http://localhost:8081

# Create an agent with concurrency limit of 4

multica agent create my-agent \
  --runtime-id $(multica runtime list | jq -r '.[] | select(.name=="my-runtime") | .id') \
  --max-concurrent-tasks 4 \
  --description "Code-review bot"

```

The CLI invokes REST endpoints that persist these values to the database, making the agent eligible for task assignment immediately.

## Assigning Tasks to Agents

### Issue-Based Assignment

When you create or update an issue with an `assignee_id` referencing an agent, the server automatically calls `EnqueueTaskForIssue`. Use the CLI to assign work:

```bash
multica issue create "Add linting" \
  --description "Run golint on the repo" \
  --assignee-id $(multica agent list | jq -r '.[] | select(.name=="my-agent") | .id')

```

### Mention-Based Assignment

If a comment contains `@agent-name`, the comment handler resolves the agent ID and invokes `EnqueueTaskForMention`. This allows a single comment to trigger a task without modifying the issue’s primary assignee, supporting multi-agent workflows on a single issue.

### Daemon Task Claiming and Execution

The daemon polls `GET /api/daemon/tasks` (handled by [`server/internal/daemon/client.go`](https://github.com/multica-ai/multica/blob/main/server/internal/daemon/client.go)) and claims work via `TaskService.ClaimTask` (lines 65‑100):

1. **Claim** – The daemon requests the next eligible task for its `agent_id`.
2. **Concurrency Check** – If the agent’s running task count meets or exceeds `max_concurrent_tasks`, `ClaimTask` returns `nil` (no capacity).
3. **Dispatch** – Upon successful claim, the server broadcasts a `task:dispatch` event (defined in [`server/pkg/protocol/events.go`](https://github.com/multica-ai/multica/blob/main/server/pkg/protocol/events.go)) containing the task ID and payload.
4. **Execution** – The daemon runs the agent CLI with `--task-id=$TASK_ID`, then calls back to `/api/daemon/tasks/$TASK_ID/complete` or `/fail`, triggering `TaskService.CompleteTask` (lines 42‑84) or `FailTask`.

## Practical Implementation Examples

### Programmatic Task Enqueueing in Go

```go
// Initialize queries and services
qs := db.New(dbConn)
taskSrv := service.NewTaskService(qs, hub, eventBus)

// Load the assigned issue
issue, err := qs.GetIssue(ctx, issueID)
if err != nil {
    log.Fatal(err)
}

// Enqueue the task
task, err := taskSrv.EnqueueTaskForIssue(ctx, issue)
if err != nil {
    log.Fatalf("failed to enqueue: %v", err)
}

fmt.Printf("Task %s queued for agent %s with runtime %s\n",
    task.ID, task.AgentID, task.RuntimeID)

```

This mirrors the production flow in [`server/internal/service/task.go`](https://github.com/multica-ai/multica/blob/main/server/internal/service/task.go), where `hub` and `eventBus` handle WebSocket notifications to the frontend.

### CLI-Based Task Management

```bash

# Poll for tasks (runs continuously in production)

multica daemon poll

# Manually claim a specific task (debugging)

multica daemon claim --agent-id $(multica agent get my-agent --format=json | jq -r .id)

# Report completion after agent CLI finishes

multica daemon complete \
  --task-id $TASK_ID \
  --output "$(cat result.json)" \
  --session-id $SESSION_ID \
  --work-dir $PWD

```

## Summary

- **Create** tasks using `EnqueueTaskForIssue`, `EnqueueTaskForMention`, or `EnqueueChatTask` in [`server/internal/service/task.go`](https://github.com/multica-ai/multica/blob/main/server/internal/service/task.go) depending on the trigger source.
- **Configure** agents with a valid `runtime_id` and set `max_concurrent_tasks` to control parallelism; the daemon uses these values to constrain workload.
- **Assign** tasks automatically by setting an agent as an issue assignee, or dynamically via `@agent` mentions in comments.
- The **daemon** claims tasks respecting concurrency limits defined in [`server/pkg/db/generated/agent.sql.go`](https://github.com/multica-ai/multica/blob/main/server/pkg/db/generated/agent.sql.go), executes the agent CLI, and reports status via `TaskService.CompleteTask` or `FailTask`.
- The server broadcasts `task:dispatch`, `task:progress`, and `task:completed` events (defined in [`server/pkg/protocol/events.go`](https://github.com/multica-ai/multica/blob/main/server/pkg/protocol/events.go)) to keep the frontend synchronized.

## Frequently Asked Questions

### How does Multica prevent an agent from being overloaded with tasks?

Multica enforces the `max_concurrent_tasks` field defined in the `agent` table. When the daemon calls `TaskService.ClaimTask` (lines 65‑100 in [`server/internal/service/task.go`](https://github.com/multica-ai/multica/blob/main/server/internal/service/task.go)), the service checks the current running task count for that agent. If the count equals or exceeds the configured limit, `ClaimTask` returns `nil`, forcing the daemon to skip that cycle and poll again later.

### What is the difference between `EnqueueTaskForIssue` and `EnqueueTaskForMention`?

`EnqueueTaskForIssue` requires the issue’s `assignee_id` to reference an agent and is typically triggered when an issue is created or updated. `EnqueueTaskForMention` accepts an explicit `agentID` parameter, allowing any agent to be triggered via a comment mention without changing the issue’s primary assignee, enabling multi-agent collaboration on a single issue.

### How do I check if an agent has available capacity before assigning work?

While you cannot query capacity directly via the public CLI, the `TaskService` automatically validates capacity during the claim phase. For programmatic checks, inspect the `agent_task_queue` table for rows matching the agent ID with status `running` or `claimed`, and compare the count against the agent’s `max_concurrent_tasks` value stored in the `agent` table.

### What happens when a task fails during execution?

When the agent CLI exits with an error, the daemon calls the `/api/daemon/tasks/$TASK_ID/fail` endpoint, which invokes `TaskService.FailTask`. This updates the task status to `failed`, records the exit code and stderr output in the database, triggers a WebSocket `task:failed` event to the frontend, and allows `TaskService.ReconcileAgentStatus` to update the agent’s status if no other tasks are running.