[experimental] @cline/agents
@cline/agents is the runtime-agnostic agent loop package in the Cline SDK.
It gives you the core primitives for building tool-using LLM agents without
bringing in session storage, hub transport, or host-specific default tools.
What You Get
Agent/AgentRuntime— the same class under two names — for running and continuing tool-using agent conversationscreateAgent/createAgentRuntime— factory-function equivalentsAgentRuntimeHooksfor lifecycle interception (beforeRun,afterRun,beforeModel,afterModel,beforeTool,afterTool,onEvent)- Event streaming via
agent.subscribe(listener)and thehooks.onEventcallback - Plugin setup callbacks for contributing tools and hooks at boot
What This Package Does Not Include
@cline/agents does not ship a full application runtime by itself.
- Default host tools like filesystem access, shell execution, or web fetching live in
@cline/core - Session persistence and stateful orchestration live in
@cline/core - Shared hub runtime/session transport lives in
@cline/core(see@cline/core/hub) - Sub-agent and team coordination primitives live in
@cline/core
That split keeps this package usable in Node, browser, and custom host environments where you want to supply your own tools and runtime policy.
Installation
npm install @cline/agents @cline/shared @cline/llms
Quick Start
import { Agent } from "@cline/agents";
import type { AgentTool } from "@cline/shared";
const getWeather: AgentTool<{ city: string }, { forecast: string }> = {
name: "get_weather",
description: "Return the current weather for a city.",
inputSchema: {
type: "object",
properties: { city: { type: "string" } },
required: ["city"],
},
async execute({ city }) {
return { forecast: `sunny in ${city}` };
},
};
const agent = new Agent({
providerId: "anthropic",
modelId: "claude-sonnet-4-6",
apiKey: process.env.ANTHROPIC_API_KEY,
systemPrompt: "You are a concise assistant.",
tools: [getWeather],
});
const result = await agent.run("What's the weather in San Francisco?");
console.log(result.outputText);
Two Ways to Configure
Agent / AgentRuntime accepts two config shapes:
Provider form — friendly entrypoint. The runtime builds an AgentModel for
you via @cline/llms:
new Agent({
providerId: "openai",
modelId: "gpt-5",
apiKey: process.env.OPENAI_API_KEY,
// baseUrl, headers also supported
tools: [/* ... */],
});
Model form — advanced. Supply a pre-built AgentModel directly. Useful
when the host already owns gateway construction (this is what @cline/core
uses internally):
import { createGateway } from "@cline/llms";
const gateway = createGateway({ providerConfigs: [/* ... */] });
const model = gateway.createAgentModel({ providerId, modelId });
new Agent({
model,
tools: [/* ... */],
});
Core Concepts
Tools
Tools conform to the AgentTool<TInput, TOutput> interface from
@cline/shared. Each tool has a JSON Schema inputSchema and an
execute(input, context) function that returns the tool output directly:
import type { AgentTool } from "@cline/shared";
const summarize: AgentTool<{ text: string }, { summary: string }> = {
name: "summarize_text",
description: "Summarize text into a short preview.",
inputSchema: {
type: "object",
properties: { text: { type: "string" } },
required: ["text"],
},
async execute({ text }, context) {
// context.signal — aborts when the run is cancelled
// context.emitUpdate(...) — stream progress as `tool-updated` events
return { summary: text.slice(0, 120) };
},
};
The runtime wraps successful tool outputs in an internal tool-result message.
Throw from execute(...) to report a tool failure, or use an afterTool hook
to transform the internal AgentToolResult envelope.
Events
Subscribe to the AgentRuntimeEvent stream in one of two ways:
// 1. Attach a listener after construction. Returns an unsubscribe function.
const unsubscribe = agent.subscribe((event) => {
if (event.type === "assistant-text-delta") {
process.stdout.write(event.text);
}
});
// 2. Register an `onEvent` hook at construction time.
new Agent({
providerId,
modelId,
apiKey,
hooks: {
onEvent(event) {
// fires for every runtime event
},
},
});
AgentRuntimeEvent covers run/turn boundaries, assistant text and reasoning
deltas, tool lifecycle, usage updates, and run completion/failure. See
AgentRuntimeEvent in @cline/shared for the full union.
Conversation Control
agent.run(input)— start a run.inputmay be a string, anAgentMessage, or an array of messages. Also acceptsundefinedto continue without adding a new user turn.agent.continue(input?)— convenience alias forrun(input?).agent.abort(reason?)— cancel the active run..run()resolves withstatus: "aborted".agent.snapshot()— immutable view of the currentAgentRuntimeStateSnapshot(messages, usage, iteration, status, etc.).agent.restore(messages)— replace the conversation with a persisted message array. Resets run/turn state but preserves subscribers, tools, hooks, plugins, and the model.initialMessagesin the constructor seeds the conversation on boot.
Hooks
Pass a hooks bag (AgentRuntimeHooks) to observe or influence the loop.
All hooks may be async; any that return { stop: true, reason } will halt the
run with an aborted status.
new Agent({
providerId,
modelId,
apiKey,
tools: [/* ... */],
hooks: {
beforeModel({ request }) {
// mutate messages/tools/options before the model call
return { options: { temperature: 0.2 } };
},
beforeTool({ tool, input }) {
// block a tool call based on policy
if (tool.name === "get_weather" && !(input as { city?: string }).city) {
return { skip: true, reason: "city required" };
}
return undefined;
},
afterRun({ result }) {
console.log("done", result.usage);
},
},
});
For richer, host-side hook orchestration (15-stage HookEngine,
subprocess-backed hooks, MCP extensions), use @cline/core.
Preparing Requests with prepareTurn
prepareTurn runs before messages are sent to the provider. It can rewrite the
messages or system prompt for the next request:
saved transcript
|
| turn preparation
v
prepareTurn
|
v
prepared provider request
Returned messages affect only the provider request for the current model call.
They do not replace saved history and are not returned from
AgentRunResult.messages.
prepareTurn returns prepared messages
|
+--> provider request: yes
+--> saved transcript: no
+--> AgentRunResult.messages: no
This is intentionally different from changing saved history. Hosts that need durable redaction, normalization, or policy filtering must apply that change before a message enters the transcript.
Plugins
Plugins can contribute tools and hooks at setup time:
import type { AgentRuntimePlugin } from "@cline/shared";
const loggingPlugin: AgentRuntimePlugin = {
name: "logging",
setup({ agentId }) {
return {
hooks: {
afterTool({ tool, result }) {
console.log(agentId, tool.name, result.isError);
return undefined; // hook may return an AgentAfterToolResult
},
},
};
},
};
new Agent({
providerId,
modelId,
apiKey,
plugins: [loggingPlugin],
});
Teams and Spawn
For multi-agent workflows, use @cline/core:
import {
createSpawnAgentTool,
AgentTeamsRuntime,
createAgentTeamsTools,
bootstrapAgentTeams,
} from "@cline/core";
These helpers provide coordination primitives for delegated runs, mailboxes, task management, and outcome convergence.
Entry Point
@cline/agents— the single package entrypoint. Thepackage.jsonexportsmap automatically serves a browser-safe bundle when bundlers resolve thebrowsercondition.
Related Packages
@cline/shared: shared types (AgentTool,AgentMessage,AgentRuntimeEvent,AgentRuntimeHooks, etc.)@cline/llms: provider settings, model catalogs, and gateway/handler creation@cline/core: stateful runtime assembly, storage, default tools, subprocess hooks, hub transport, and MCP integration
More Examples
- Repo examples: examples/plugins, examples/hooks, examples/cron
- Workspace overview: README.md
- API and architecture references: DOC.md, ARCHITECTURE.md