Skip to Content

@loopstack/code-agent

Agent workflow module for the Loopstack  automation framework.

AI-powered code exploration for Loopstack workflows. Provides a tool that launches a sub-agent workflow to search, read, and synthesize findings from a remote workspace using glob, grep, and read tools from @loopstack/remote-client.

When to Use

  • You need a workflow to answer questions about a codebase before acting — locating functions, summarizing features, understanding architecture
  • You want to delegate exploration as a single tool call from a parent workflow or agent
  • You need a self-contained agent that iteratively searches and reads files on a remote workspace and returns a synthesized answer
  • Use @loopstack/remote-client directly if you only need individual file operations without the agent loop

Installation

npm install @loopstack/code-agent

Register the module in your application:

import { Module } from '@nestjs/common'; import { CodeAgentModule } from '@loopstack/code-agent'; @Module({ imports: [CodeAgentModule], }) export class AppModule {}

CodeAgentModule imports AgentModule from @loopstack/agent, which in turn requires LlmProviderModule and RemoteClientModule to be configured in your app.

To override the LLM provider or model for this module specifically:

@Module({ imports: [CodeAgentModule.forFeature({ llm: { provider: 'claude', model: 'claude-sonnet-4-20250514' } })], }) export class AppModule {}

Quick Start

The most common pattern is launching the code agent from a parent workflow using AgentWorkflow directly:

import { Module } from '@nestjs/common'; import { z } from 'zod'; import { AgentWorkflow } from '@loopstack/agent'; import { CodeAgentModule } from '@loopstack/code-agent'; import { BaseWorkflow, CallbackSchema, MessageDocument, Transition, Workflow } from '@loopstack/common'; const ExploreCallbackSchema = CallbackSchema.extend({ data: z.object({ response: z.string() }), }); type ExploreCallback = z.infer<typeof ExploreCallbackSchema>; @Workflow({ title: 'Code Agent Example' }) export class MyWorkflow extends BaseWorkflow { constructor(private readonly agentWorkflow: AgentWorkflow) { super(); } @Transition({ to: 'exploring' }) async start(state: Record<string, unknown>): Promise<Record<string, unknown>> { await this.agentWorkflow.run( { system: 'You are a codebase exploration agent. Search and read source code to answer the question thoroughly.', tools: ['glob', 'grep', 'read'], userMessage: 'Find the entry-point module and list its top-level providers.', }, { callback: { transition: 'onExploreComplete' }, show: 'inline', label: 'Exploring codebase...' }, ); return state; } @Transition({ from: 'exploring', to: 'end', wait: true, schema: ExploreCallbackSchema }) async onExploreComplete(state: Record<string, unknown>, payload: ExploreCallback): Promise<unknown> { await this.documentStore.save(MessageDocument, { role: 'assistant', text: payload.data.response, }); return {}; } } @Module({ imports: [CodeAgentModule], providers: [MyWorkflow], exports: [MyWorkflow, CodeAgentModule], }) export class MyModule {}

How It Works

State Machine

start ──► exploring (wait) ──► end │ ▲ └── callback ───────┘
  1. The parent workflow calls agentWorkflow.run() with a system prompt, tool list, and user message
  2. The AgentWorkflow sub-workflow starts its own agent loop: LLM generates text, calls tools (glob, grep, read), loops until it produces a final answer
  3. The orchestrator renders the sub-workflow inline in the parent’s UI based on the show option ('inline' by default)
  4. When the agent finishes, it calls back to the parent workflow’s wait transition with { data: { response } }
  5. The parent receives the synthesized answer and can display it or act on it

ExploreTask Tool

The module also provides ExploreTask, a tool wrapper around AgentWorkflow that can be used by other agents:

Parent Agent ──► explore_task tool call ──► AgentWorkflow sub-agent glob/grep/read loop synthesized answer ◄── complete() callback

ExploreTask launches the sub-agent and returns { workflowId } with pending status. The orchestrator renders the sub-agent inline in the parent’s view. When the sub-agent completes, ExploreTask.complete() returns the response text.

Args Reference

AgentWorkflow.run()

ArgTypeRequiredDescription
systemstringYesSystem prompt for the agent
toolsstring[]YesTool names to make available (e.g. ['glob', 'grep', 'read'])
userMessagestringYesThe question or instruction for the agent
contextstringNoAdditional context to include in the conversation

Second argument (options):

ArgTypeRequiredDescription
callback.transitionstringNoTransition name to call when the agent finishes

Returns: QueueResult with { workflowId: string }

Callback Payload

Extend CallbackSchema to type the completion payload:

const ExploreCallbackSchema = CallbackSchema.extend({ data: z.object({ response: z.string() }), });
FieldTypeDescription
workflowIdstringID of the completed sub-workflow
data.responsestringThe agent’s synthesized text answer

Tools Reference

explore_task

FieldValue
Nameexplore_task
DescriptionLaunch a sub-agent to explore and analyze the codebase. The agent uses glob, grep, and read tools to search for files and code patterns, then returns a synthesized summary.

Args (Zod schema):

ArgTypeRequiredDescription
instructionsstringYesDetailed instructions for what to explore in the codebase

Returns: ToolResult<ExploreTaskResult>

  • On launch: { data: { workflowId }, pending: { workflowId } }
  • On complete: { data: string } — the agent’s synthesized response text

Configuration

CodeAgentModule.forFeature()

Override the LLM provider or model for the code agent specifically:

CodeAgentModule.forFeature({ llm: { provider: 'claude', // LLM provider name model: 'claude-sonnet-4-20250514', // Model identifier }, });
OptionTypeRequiredDescription
llm.providerstringNoLLM provider name
llm.modelstringNoModel identifier

Public API

  • Module: CodeAgentModule
  • Tool: ExploreTask
  • Type: ExploreTaskResult

Dependencies

PackageRole
@loopstack/agentAgentWorkflow — generic LLM agent loop with tool calling
@loopstack/commonBaseTool, BaseWorkflow, decorators, document types
@loopstack/coreWorkflow engine, scheduling, state management
@loopstack/remote-clientglob, grep, read tools executed on the remote workspace
@nestjs/commonNestJS dependency injection
zodSchema validation

About

Author: Jakob Klippel 

License: MIT

Last updated on