Skip to main content

Agent Commands

Agents are autonomous workers that execute tasks independently in the background without requiring constant supervision. Unlike interactive sessions where you guide each step, agents receive a goal and figure out how to accomplish it—analyzing codebases, generating documentation, running tests, or monitoring systems—while you focus on other work. They store results for review when ready.

Understanding Agent Lifecycle

Every agent moves through distinct lifecycle states: "starting" during initialization, "running" while executing tasks, and finally "completed", "failed", or "stopped" based on outcome. A stuck agent showing "running" for hours signals a potential problem, while quick transitions to "failed" indicate execution errors requiring investigation.

Listing Your Agents

When you want to see what agents exist and what they're currently doing, the lattice-ctl agents list command provides a comprehensive overview:

bash
lattice-ctl agents list

This shows every agent the daemon knows about—running, completed, failed, or stopped. For each agent, you see its unique identifier, the name you assigned when creating it, its current status, and timestamps indicating when it was created and potentially when it completed. This bird's-eye view helps you understand your agent landscape: what's actively running, what's finished, and what might need attention.

The list output is particularly useful for monitoring concurrent agent execution. If you've launched multiple agents to work in parallel, the list shows them all simultaneously, letting you track overall progress and identify any agents that might be stuck or failing while others succeed.

For programmatic use or integration with other tools, JSON output provides structured data you can parse and process:

bash
lattice-ctl agents list --format json

The JSON structure includes all agent metadata in machine-readable form. You can pipe this through jq to filter by status, extract agent IDs, or generate reports about agent execution patterns. This becomes especially valuable in automation scenarios where you're launching agents programmatically and need to monitor their status through code.

Starting an Agent

Creating an agent and giving it work to do requires the lattice-ctl agents start command. Every agent needs a name that identifies it uniquely:

bash
lattice-ctl agents start --name my-agent

The name you provide serves as a human-readable identifier that makes it easier to track which agent is which when you have multiple running concurrently. Agent names must be unique—you can't start two agents with the same name simultaneously. Choose names that describe what the agent is doing: "code-reviewer", "documentation-generator", or "test-runner" are more useful than generic names like "agent1" or "my-agent".

When you start an agent, the daemon creates it, assigns it a unique ID, and begins initialization. The command returns immediately with the agent ID and initial status, typically "starting". The agent then transitions to "running" status as it begins executing its work. You don't need to wait for the agent to complete—it runs in the background independently.

For automation scenarios where you need to capture the agent ID to monitor or interact with it later, use JSON output and parse the ID:

bash
AGENT_ID=$(lattice-ctl agents start --name task-runner --format json | jq -r '.data.id')
echo "Started agent: $AGENT_ID"

This pattern is essential for scripts that launch agents and then need to monitor their progress or wait for completion. The captured agent ID becomes your handle for all future operations on this specific agent.

Stopping an Agent

Sometimes you need to terminate an agent before it completes naturally—perhaps you realized the task was wrong, or circumstances changed making the work unnecessary. The lattice-ctl agents stop command gracefully shuts down a running agent:

bash
lattice-ctl agents stop agent_123abc

The stop operation is graceful, not abrupt. When the daemon receives a stop request, it signals the agent to shut down. The agent finishes whatever immediate operation it's performing—completing the current step rather than cutting off mid-action. It then saves any state or results it has accumulated so far, updates its status to "stopped", and terminates cleanly.

This graceful shutdown ensures you don't lose work the agent has already completed. If an agent has been running for an hour analyzing code when you stop it, any analysis completed before the stop signal arrives remains saved and accessible. Only work that hadn't started or was still in progress gets abandoned.

Understanding the difference between stopping and waiting for completion helps you use agents effectively. If an agent is doing what you want but it's taking too long, consider letting it complete rather than stopping it—you'll get the full results. Stop is for scenarios where you actively want to terminate the work because it's wrong, unnecessary, or needs to be restarted with different parameters.

Common Agent Workflows

Agents shine in scenarios where you want to launch work and monitor it periodically rather than sitting and watching it execute. Let's look at typical patterns.

The basic pattern for working with agents involves starting them, monitoring their progress, and retrieving results when they complete:

bash
# Start agent and capture its ID
AGENT_ID=$(lattice-ctl agents start --name task-runner --format json | jq -r '.data.id')

# Monitor status periodically with watch
watch -n 1 "lattice-ctl agents list | grep $AGENT_ID"

# When it completes or you're ready to stop it
lattice-ctl agents stop $AGENT_ID

This workflow gives you visibility into agent progress without requiring constant attention. The watch command refreshes the agent list every second, showing you current status. You can let this run in a terminal window while working on other things, glancing over occasionally to see progress.

For scenarios where you're launching multiple agents to work in parallel, monitoring them all at once helps you understand overall progress:

bash
# Start several agents
lattice-ctl agents start --name code-analyzer
lattice-ctl agents start --name test-runner
lattice-ctl agents start --name doc-generator

# Monitor all at once
watch -n 2 "lattice-ctl agents list"

The agent list shows all agents and their current states, letting you see at a glance which have completed, which are still running, and whether any have failed. This holistic view is crucial when coordinating multiple concurrent agents whose work might be interdependent.

As agents complete, they accumulate in your agent list. While the daemon handles cleanup automatically over time, you might want to identify completed agents manually:

bash
# Find all completed agents
lattice-ctl agents list --format json | \
  jq -r '.data.agents[] | select(.status == "completed") | .id'

This query extracts just the IDs of agents that have finished their work. You can use this to verify expected agents have completed or to identify which agents' results are available for review.

Working with Agents Programmatically

Just as with sessions, agents can be managed through code using Lattice's client libraries. This enables sophisticated automation and integration scenarios.

The TypeScript client provides async methods for agent management:

typescript
import { LatticeClient } from "@lovelace-ai/lattice-client";

const client = new LatticeClient();
await client.connect();

// Start agent
const agent = await client.startAgent({ name: "my-agent" });

// List agents to check status
const agents = await client.listAgents();
const myAgent = agents.find((a) => a.id === agent.id);
console.log(`Agent status: ${myAgent.status}`);

// Stop agent if needed
if (myAgent.status === "running") {
  await client.stopAgent(agent.id);
}

This programmatic approach lets you build applications that spawn agents dynamically, monitor their execution, and react to completion or failure states. You might create a CI/CD system that launches agents to analyze code changes, a development tool that uses agents for background code generation, or a monitoring system that deploys agents to check system health.

Rust code follows similar patterns with Rust-specific idioms:

rust
use lattice_client::{LatticeDaemonClient, ClientConfig};

let client = LatticeDaemonClient::connect(ClientConfig::default()).await?;

// Start agent
let agent = client.start_agent("my-agent").await?;

// Poll for completion
loop {
    let agents = client.list_agents().await?;
    let my_agent = agents.iter().find(|a| a.id == agent.id).unwrap();

    if my_agent.status != "running" {
        println!("Agent finished with status: {}", my_agent.status);
        break;
    }

    tokio::time::sleep(Duration::from_secs(1)).await;
}

The Rust version demonstrates a polling pattern where you periodically check agent status until it exits the "running" state. This pattern is useful for orchestration scenarios where subsequent steps depend on agent completion.

Understanding Agent Concurrency

The daemon limits how many agents can run simultaneously through the max_agents configuration setting. This limit exists to prevent resource exhaustion—each agent consumes memory and CPU, and too many concurrent agents will overwhelm your system.

When you try to start an agent but have already reached the maximum concurrent agents limit, the daemon queues the new agent rather than rejecting it outright. As running agents complete and free up slots, queued agents automatically transition to running status. This queueing behavior lets you launch many agents without worrying about the exact limit—they'll execute in waves as resources become available.

You can monitor how many agent slots are in use through the daemon status command, which shows active agent count. If you're consistently hitting the limit and experiencing queuing delays, consider increasing max_agents in your configuration or spacing out agent launches to reduce concurrent load.

Troubleshooting Agent Issues

When agents don't behave as expected, a few common issues are worth investigating.

If an agent starts but immediately transitions to "failed" status, check the daemon's logs for error messages explaining what went wrong. Common causes include incorrect configuration, missing dependencies, or problems reaching LLM providers. The logs usually contain enough detail to identify the root cause.

Agents that remain in "starting" status for extended periods indicate initialization problems. The agent can't complete its startup sequence for some reason. Again, daemon logs will reveal what's blocking initialization—often provider connectivity issues or resource constraints.

If agents complete but you can't find their results, verify you're looking in the right place for output. Agent results are typically stored in the daemon's state database and should be accessible through agent inspection commands, but the exact mechanism depends on what your specific agents are designed to produce.

Resource exhaustion manifests as agents that start but then hang or crash. If the system runs out of memory or CPU capacity, agents may fail unpredictably. Monitor system resources while agents run, and consider reducing max_agents or running fewer concurrent agents if you're pushing resource limits.

Next Steps

Agents are powerful tools for autonomous work, but they're just one part of the Lattice ecosystem. The session commands guide covers interactive conversations that complement agent autonomy. The provider commands guide explains how to configure the LLM providers that power agents. For complete agent lifecycle management and advanced patterns, see the agent management guide. Finally, the programmatic usage guide dives deeper into building applications that orchestrate agent execution through code.