Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

agentool

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

agentool - npm Package Compare versions

Comparing version
1.4.2
to
1.5.0
+11
dist/agent/index.cjs
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
var _chunk6THYNTJFcjs = require('../chunk-6THYNTJF.cjs');
require('../chunk-KONXT2SF.cjs');
exports.agent = _chunk6THYNTJFcjs.agent; exports.agentPrompt = _chunk6THYNTJFcjs.getPrompt; exports.createAgent = _chunk6THYNTJFcjs.createAgent;
import * as ai from 'ai';
import { LanguageModel, ToolSet, StopCondition, CallSettings } from 'ai';
type AgentTaskStatus = 'running' | 'completed' | 'failed' | 'stopped' | 'timed_out';
interface ManagedAgentDefinition {
/** Description shown in the tool prompt for this agent. */
description?: string;
/** System prompt controlled by application code. */
systemPrompt: string;
/** Optional model override for this agent. */
model?: LanguageModel;
/** Optional tool override for this agent. */
tools?: ToolSet;
/** Optional AI SDK stop condition override. */
stopWhen?: StopCondition<ToolSet> | Array<StopCondition<ToolSet>>;
/** Agent-specific turn limit used when stopWhen is omitted. */
maxTurns?: number;
/** Agent-specific call settings. */
settings?: Omit<CallSettings, 'abortSignal'>;
}
interface AgentConfig {
/** Default language model used by subagents. Required for start unless an agent overrides it. */
model?: LanguageModel;
/** Default tools available to subagents. */
tools?: ToolSet;
/** Named subagent registry. */
agents?: Record<string, ManagedAgentDefinition>;
/** Default agent name. Defaults to the first registry entry, or "default". */
defaultAgent?: string;
/** Maximum number of running tasks. Defaults to 4. */
maxConcurrent?: number;
/** Default subagent run timeout in milliseconds. Defaults to 300000. */
defaultTimeoutMs?: number;
/** Default wait action timeout in milliseconds. Defaults to 30000. */
defaultWaitTimeoutMs?: number;
/** Default wait polling interval in milliseconds. Defaults to 500. */
defaultPollIntervalMs?: number;
/** Maximum result characters returned to the orchestrator. Defaults to 30000. */
maxResultChars?: number;
/** Default AI SDK stop condition override. */
stopWhen?: StopCondition<ToolSet> | Array<StopCondition<ToolSet>>;
/** Default turn limit used when stopWhen is omitted. Defaults to 20. */
maxTurns?: number;
/** Default call settings for child generateText calls. */
settings?: Omit<CallSettings, 'abortSignal'>;
/** Override the default tool description. */
description?: string;
}
declare function getPrompt(config?: AgentConfig): string;
/**
* Creates a managed subagent tool.
*
* The tool keeps task state in memory for the lifetime of the returned tool
* instance. Child runs use configured model/tools and registry-controlled
* system prompts; parent messages are intentionally not forwarded.
*/
declare function createAgent(config?: AgentConfig): ai.Tool<{
action: "start";
prompt: string;
description?: string | undefined;
agent?: string | undefined;
timeoutMs?: number | undefined;
} | {
action: "wait";
mode: "all" | "any";
timeoutMs?: number | undefined;
taskIds?: string[] | undefined;
pollIntervalMs?: number | undefined;
} | {
action: "status";
taskId: string;
} | {
action: "result";
taskId: string;
} | {
action: "list";
} | {
action: "stop";
taskId: string;
}, string>;
/**
* Default agent tool instance. Configure a model with createAgent({ model }).
*/
declare const agent: ai.Tool<{
action: "start";
prompt: string;
description?: string | undefined;
agent?: string | undefined;
timeoutMs?: number | undefined;
} | {
action: "wait";
mode: "all" | "any";
timeoutMs?: number | undefined;
taskIds?: string[] | undefined;
pollIntervalMs?: number | undefined;
} | {
action: "status";
taskId: string;
} | {
action: "result";
taskId: string;
} | {
action: "list";
} | {
action: "stop";
taskId: string;
}, string>;
export { type AgentConfig, type AgentTaskStatus, type ManagedAgentDefinition, agent, getPrompt as agentPrompt, createAgent };
import * as ai from 'ai';
import { LanguageModel, ToolSet, StopCondition, CallSettings } from 'ai';
type AgentTaskStatus = 'running' | 'completed' | 'failed' | 'stopped' | 'timed_out';
interface ManagedAgentDefinition {
/** Description shown in the tool prompt for this agent. */
description?: string;
/** System prompt controlled by application code. */
systemPrompt: string;
/** Optional model override for this agent. */
model?: LanguageModel;
/** Optional tool override for this agent. */
tools?: ToolSet;
/** Optional AI SDK stop condition override. */
stopWhen?: StopCondition<ToolSet> | Array<StopCondition<ToolSet>>;
/** Agent-specific turn limit used when stopWhen is omitted. */
maxTurns?: number;
/** Agent-specific call settings. */
settings?: Omit<CallSettings, 'abortSignal'>;
}
interface AgentConfig {
/** Default language model used by subagents. Required for start unless an agent overrides it. */
model?: LanguageModel;
/** Default tools available to subagents. */
tools?: ToolSet;
/** Named subagent registry. */
agents?: Record<string, ManagedAgentDefinition>;
/** Default agent name. Defaults to the first registry entry, or "default". */
defaultAgent?: string;
/** Maximum number of running tasks. Defaults to 4. */
maxConcurrent?: number;
/** Default subagent run timeout in milliseconds. Defaults to 300000. */
defaultTimeoutMs?: number;
/** Default wait action timeout in milliseconds. Defaults to 30000. */
defaultWaitTimeoutMs?: number;
/** Default wait polling interval in milliseconds. Defaults to 500. */
defaultPollIntervalMs?: number;
/** Maximum result characters returned to the orchestrator. Defaults to 30000. */
maxResultChars?: number;
/** Default AI SDK stop condition override. */
stopWhen?: StopCondition<ToolSet> | Array<StopCondition<ToolSet>>;
/** Default turn limit used when stopWhen is omitted. Defaults to 20. */
maxTurns?: number;
/** Default call settings for child generateText calls. */
settings?: Omit<CallSettings, 'abortSignal'>;
/** Override the default tool description. */
description?: string;
}
declare function getPrompt(config?: AgentConfig): string;
/**
* Creates a managed subagent tool.
*
* The tool keeps task state in memory for the lifetime of the returned tool
* instance. Child runs use configured model/tools and registry-controlled
* system prompts; parent messages are intentionally not forwarded.
*/
declare function createAgent(config?: AgentConfig): ai.Tool<{
action: "start";
prompt: string;
description?: string | undefined;
agent?: string | undefined;
timeoutMs?: number | undefined;
} | {
action: "wait";
mode: "all" | "any";
timeoutMs?: number | undefined;
taskIds?: string[] | undefined;
pollIntervalMs?: number | undefined;
} | {
action: "status";
taskId: string;
} | {
action: "result";
taskId: string;
} | {
action: "list";
} | {
action: "stop";
taskId: string;
}, string>;
/**
* Default agent tool instance. Configure a model with createAgent({ model }).
*/
declare const agent: ai.Tool<{
action: "start";
prompt: string;
description?: string | undefined;
agent?: string | undefined;
timeoutMs?: number | undefined;
} | {
action: "wait";
mode: "all" | "any";
timeoutMs?: number | undefined;
taskIds?: string[] | undefined;
pollIntervalMs?: number | undefined;
} | {
action: "status";
taskId: string;
} | {
action: "result";
taskId: string;
} | {
action: "list";
} | {
action: "stop";
taskId: string;
}, string>;
export { type AgentConfig, type AgentTaskStatus, type ManagedAgentDefinition, agent, getPrompt as agentPrompt, createAgent };
import {
agent,
createAgent,
getPrompt
} from "../chunk-34XNLXFI.js";
import "../chunk-X6ZY2KFU.js";
export {
agent,
getPrompt as agentPrompt,
createAgent
};
import {
extractErrorMessage
} from "./chunk-X6ZY2KFU.js";
// src/agent/index.ts
import { generateText, stepCountIs, tool } from "ai";
import { randomUUID } from "crypto";
import { setTimeout as sleep } from "timers/promises";
// src/agent/constants.ts
var DEFAULT_AGENT_NAME = "default";
var DEFAULT_MAX_CONCURRENT = 4;
var DEFAULT_RUN_TIMEOUT_MS = 3e5;
var DEFAULT_WAIT_TIMEOUT_MS = 3e4;
var DEFAULT_POLL_INTERVAL_MS = 500;
var DEFAULT_RESULT_CHARS = 3e4;
var DEFAULT_MAX_TURNS = 20;
var terminalStatuses = /* @__PURE__ */ new Set([
"completed",
"failed",
"stopped",
"timed_out"
]);
var fallbackAgent = {
description: "General purpose subagent",
systemPrompt: "You are a focused subagent. Complete the delegated task and report concise findings back to the orchestrator."
};
// src/agent/format.ts
function isTerminal(task) {
return terminalStatuses.has(task.status);
}
function truncateResult(value, maxChars) {
if (value.length <= maxChars) return value;
const omitted = value.length - maxChars;
return `${value.slice(0, maxChars)}
... [agent result truncated - ${omitted} chars removed]`;
}
function formatUsage(usage) {
if (!usage) return "";
const parts = [
usage.inputTokens === void 0 ? void 0 : `input=${usage.inputTokens}`,
usage.outputTokens === void 0 ? void 0 : `output=${usage.outputTokens}`,
usage.totalTokens === void 0 ? void 0 : `total=${usage.totalTokens}`
].filter((part) => part !== void 0);
return parts.length > 0 ? `
Usage: ${parts.join(", ")}` : "";
}
function formatTaskSummary(task) {
const elapsedMs = (task.endTime ?? Date.now()) - task.startTime;
const label = task.description ? ` (${task.description})` : "";
const error = task.error ? `
Error: ${task.error}` : "";
return `Task ${task.id}${label}
Agent: ${task.agentName}
Status: ${task.status}
Elapsed: ${elapsedMs}ms${formatUsage(task.usage)}${error}`;
}
function formatTaskResult(task, maxResultChars) {
const summary = formatTaskSummary(task);
if (task.status === "completed") {
return `${summary}
Result:
${truncateResult(task.result ?? "", maxResultChars)}`;
}
if (task.status === "running") {
return `${summary}
Result is not ready yet. Use wait or status later.`;
}
return summary;
}
function formatWaitResult(tasks, mode, timedOut, maxResultChars) {
const completed = tasks.filter(isTerminal);
const running = tasks.filter((task) => task.status === "running");
const header = timedOut ? `Wait timed out. ${completed.length}/${tasks.length} selected task(s) finished.` : `Wait complete (${mode}). ${completed.length}/${tasks.length} selected task(s) finished.`;
const sections = completed.map((task) => formatTaskResult(task, maxResultChars));
const runningLines = running.map(
(task) => `Task ${task.id}: running${task.description ? ` (${task.description})` : ""}`
);
return [header, ...sections, ...runningLines].join("\n\n");
}
// src/agent/prompt.ts
function getPrompt(config = {}) {
const names = Object.keys(config.agents ?? {});
const registryLine = names.length > 0 ? `Configured agents: ${names.join(", ")}.` : "No named agents are configured; the built-in default agent is used.";
return `Spawn and manage parallel subagents.
Use this tool when work can be split into focused independent investigations or checks.
${registryLine}
Actions:
- start: launch a subagent in the background and return a task id immediately.
- wait: wait internally for any or all selected tasks to finish.
- status: inspect one task.
- result: read one completed task result.
- list: show known tasks.
- stop: abort a running task.
Guidelines:
- Start multiple independent subagents before waiting when parallel work helps.
- Use wait instead of repeatedly polling status.
- Subagents do not receive this agent tool recursively.
- If a result is incomplete, start a narrower follow-up subagent or investigate directly.
- Stop tasks that are no longer useful.`;
}
// src/agent/schema.ts
import { z } from "zod";
var inputSchema = z.discriminatedUnion("action", [
z.object({
action: z.literal("start"),
agent: z.string().optional().describe("Configured agent name to run"),
prompt: z.string().describe("User prompt for the subagent"),
description: z.string().optional().describe("Short task label"),
timeoutMs: z.number().int().positive().optional().describe("Run timeout in milliseconds")
}),
z.object({
action: z.literal("wait"),
taskIds: z.array(z.string()).optional().describe("Task ids to wait for. Defaults to all running tasks."),
mode: z.enum(["all", "any"]).optional().default("all").describe("Wait for all selected tasks or the first selected task"),
timeoutMs: z.number().int().nonnegative().optional().describe("Wait timeout in milliseconds"),
pollIntervalMs: z.number().int().positive().optional().describe("Internal polling interval in milliseconds")
}),
z.object({
action: z.literal("status"),
taskId: z.string().describe("Task id to inspect")
}),
z.object({
action: z.literal("result"),
taskId: z.string().describe("Task id to read")
}),
z.object({
action: z.literal("list")
}),
z.object({
action: z.literal("stop"),
taskId: z.string().describe("Task id to stop")
})
]);
// src/agent/tasks.ts
function activeTaskCount(tasks) {
let count = 0;
for (const task of tasks.values()) {
if (task.status === "running") count++;
}
return count;
}
function selectAgent(config, requestedName) {
const registry = config.agents ?? {};
const registryNames = Object.keys(registry);
const name = requestedName ?? config.defaultAgent ?? registryNames[0] ?? DEFAULT_AGENT_NAME;
const definition = registry[name] ?? (name === DEFAULT_AGENT_NAME && registryNames.length === 0 ? fallbackAgent : void 0);
if (!definition) {
const available = registryNames.length > 0 ? registryNames.join(", ") : DEFAULT_AGENT_NAME;
return `Unknown agent "${name}". Available agents: ${available}.`;
}
return { name, definition };
}
function getWaitTargets(tasks, taskIds) {
if (taskIds && taskIds.length > 0) {
const selected = [];
const missing = [];
for (const taskId of taskIds) {
const task = tasks.get(taskId);
if (task) selected.push(task);
else missing.push(taskId);
}
if (missing.length > 0) {
return `Unknown task id(s): ${missing.join(", ")}.`;
}
return selected;
}
return Array.from(tasks.values()).filter((task) => task.status === "running");
}
function stopTask(task, status, error) {
if (task.status !== "running") return;
task.status = status;
task.error = error;
task.endTime = Date.now();
if (task.timeoutId) {
clearTimeout(task.timeoutId);
task.timeoutId = void 0;
}
task.abortController.abort();
}
// src/agent/tools.ts
var AGENT_TOOL_NAME = "agent";
var agentTools = /* @__PURE__ */ new WeakSet();
function markAgentTool(agentTool) {
agentTools.add(agentTool);
return agentTool;
}
function isMarkedAgentTool(value) {
return typeof value === "object" && value !== null && agentTools.has(value);
}
function removeAgentTools(tools) {
if (!tools) return tools;
const toolEntries = Object.entries(tools);
const entries = toolEntries.filter(
([name, value]) => name !== AGENT_TOOL_NAME && !isMarkedAgentTool(value)
);
if (entries.length === toolEntries.length) return tools;
if (entries.length === 0) return void 0;
return Object.fromEntries(entries);
}
// src/agent/index.ts
function createAgent(config = {}) {
const tasks = /* @__PURE__ */ new Map();
const maxConcurrent = config.maxConcurrent ?? DEFAULT_MAX_CONCURRENT;
const defaultRunTimeoutMs = config.defaultTimeoutMs ?? DEFAULT_RUN_TIMEOUT_MS;
const defaultWaitTimeoutMs = config.defaultWaitTimeoutMs ?? DEFAULT_WAIT_TIMEOUT_MS;
const defaultPollIntervalMs = config.defaultPollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
const maxResultChars = config.maxResultChars ?? DEFAULT_RESULT_CHARS;
function startTask(input) {
if (activeTaskCount(tasks) >= maxConcurrent) {
return `Error [agent]: Max concurrent subagents reached (${maxConcurrent}). Use wait, result, or stop before starting more.`;
}
const selected = selectAgent(config, input.agent);
if (typeof selected === "string") {
return `Error [agent]: ${selected}`;
}
const model = selected.definition.model ?? config.model;
if (!model) {
return "Error [agent]: No model configured. Provide createAgent({ model }) or an agent-specific model.";
}
const taskId = `agent_${randomUUID()}`;
const abortController = new AbortController();
const timeoutMs = input.timeoutMs ?? defaultRunTimeoutMs;
const task = {
id: taskId,
agentName: selected.name,
description: input.description,
prompt: input.prompt,
status: "running",
startTime: Date.now(),
abortController,
promise: Promise.resolve()
};
tasks.set(taskId, task);
task.timeoutId = setTimeout(() => {
stopTask(
task,
"timed_out",
`Subagent timed out after ${timeoutMs}ms.`
);
}, timeoutMs);
task.promise = (async () => {
try {
const maxTurns = selected.definition.maxTurns ?? config.maxTurns ?? DEFAULT_MAX_TURNS;
const stopWhen = selected.definition.stopWhen ?? config.stopWhen ?? stepCountIs(maxTurns);
const result = await generateText({
...config.settings ?? {},
...selected.definition.settings ?? {},
model,
tools: removeAgentTools(selected.definition.tools ?? config.tools),
system: selected.definition.systemPrompt,
prompt: input.prompt,
stopWhen,
abortSignal: abortController.signal
});
if (task.status === "running") {
task.status = "completed";
task.result = result.text;
task.usage = result.usage;
task.endTime = Date.now();
}
} catch (error) {
if (task.status === "running") {
task.status = "failed";
task.error = extractErrorMessage(error);
task.endTime = Date.now();
}
} finally {
if (task.timeoutId) {
clearTimeout(task.timeoutId);
task.timeoutId = void 0;
}
}
})();
return `Started subagent task ${taskId}.
Agent: ${selected.name}
Status: running
Use wait with taskIds ["${taskId}"] or wait for all running tasks.`;
}
async function waitForTasks(input, abortSignal) {
const targets = getWaitTargets(tasks, input.taskIds);
if (typeof targets === "string") return `Error [agent]: ${targets}`;
if (targets.length === 0) {
return "No running or selected subagent tasks to wait for.";
}
const mode = input.mode;
const timeoutMs = input.timeoutMs ?? defaultWaitTimeoutMs;
const pollIntervalMs = input.pollIntervalMs ?? defaultPollIntervalMs;
const deadline = Date.now() + timeoutMs;
while (true) {
const completed = targets.filter(isTerminal);
const done = mode === "any" ? completed.length > 0 : completed.length === targets.length;
if (done) {
return formatWaitResult(targets, mode, false, maxResultChars);
}
const remainingMs = deadline - Date.now();
if (remainingMs <= 0) {
return formatWaitResult(targets, mode, true, maxResultChars);
}
await sleep(Math.min(pollIntervalMs, remainingMs), void 0, {
signal: abortSignal
});
}
}
return markAgentTool(tool({
description: config.description ?? getPrompt(config),
inputSchema,
execute: async (input, options) => {
try {
switch (input.action) {
case "start":
return startTask(input);
case "wait":
return await waitForTasks(input, options.abortSignal);
case "status": {
const task = tasks.get(input.taskId);
return task ? formatTaskSummary(task) : `Error [agent]: Unknown task id "${input.taskId}".`;
}
case "result": {
const task = tasks.get(input.taskId);
return task ? formatTaskResult(task, maxResultChars) : `Error [agent]: Unknown task id "${input.taskId}".`;
}
case "list": {
if (tasks.size === 0) return "No subagent tasks have been started.";
return Array.from(tasks.values()).sort((a, b) => a.startTime - b.startTime).map(formatTaskSummary).join("\n\n");
}
case "stop": {
const task = tasks.get(input.taskId);
if (!task) return `Error [agent]: Unknown task id "${input.taskId}".`;
if (task.status !== "running") {
return `Task ${task.id} is already ${task.status}.`;
}
stopTask(task, "stopped", "Subagent stopped by orchestrator.");
return `Stopped subagent task ${task.id}.`;
}
}
} catch (error) {
return `Error [agent]: ${extractErrorMessage(error)}`;
}
}
}));
}
var agent = createAgent();
export {
getPrompt,
createAgent,
agent
};
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }
var _chunkKONXT2SFcjs = require('./chunk-KONXT2SF.cjs');
// src/agent/index.ts
var _ai = require('ai');
var _crypto = require('crypto');
var _promises = require('timers/promises');
// src/agent/constants.ts
var DEFAULT_AGENT_NAME = "default";
var DEFAULT_MAX_CONCURRENT = 4;
var DEFAULT_RUN_TIMEOUT_MS = 3e5;
var DEFAULT_WAIT_TIMEOUT_MS = 3e4;
var DEFAULT_POLL_INTERVAL_MS = 500;
var DEFAULT_RESULT_CHARS = 3e4;
var DEFAULT_MAX_TURNS = 20;
var terminalStatuses = /* @__PURE__ */ new Set([
"completed",
"failed",
"stopped",
"timed_out"
]);
var fallbackAgent = {
description: "General purpose subagent",
systemPrompt: "You are a focused subagent. Complete the delegated task and report concise findings back to the orchestrator."
};
// src/agent/format.ts
function isTerminal(task) {
return terminalStatuses.has(task.status);
}
function truncateResult(value, maxChars) {
if (value.length <= maxChars) return value;
const omitted = value.length - maxChars;
return `${value.slice(0, maxChars)}
... [agent result truncated - ${omitted} chars removed]`;
}
function formatUsage(usage) {
if (!usage) return "";
const parts = [
usage.inputTokens === void 0 ? void 0 : `input=${usage.inputTokens}`,
usage.outputTokens === void 0 ? void 0 : `output=${usage.outputTokens}`,
usage.totalTokens === void 0 ? void 0 : `total=${usage.totalTokens}`
].filter((part) => part !== void 0);
return parts.length > 0 ? `
Usage: ${parts.join(", ")}` : "";
}
function formatTaskSummary(task) {
const elapsedMs = (_nullishCoalesce(task.endTime, () => ( Date.now()))) - task.startTime;
const label = task.description ? ` (${task.description})` : "";
const error = task.error ? `
Error: ${task.error}` : "";
return `Task ${task.id}${label}
Agent: ${task.agentName}
Status: ${task.status}
Elapsed: ${elapsedMs}ms${formatUsage(task.usage)}${error}`;
}
function formatTaskResult(task, maxResultChars) {
const summary = formatTaskSummary(task);
if (task.status === "completed") {
return `${summary}
Result:
${truncateResult(_nullishCoalesce(task.result, () => ( "")), maxResultChars)}`;
}
if (task.status === "running") {
return `${summary}
Result is not ready yet. Use wait or status later.`;
}
return summary;
}
function formatWaitResult(tasks, mode, timedOut, maxResultChars) {
const completed = tasks.filter(isTerminal);
const running = tasks.filter((task) => task.status === "running");
const header = timedOut ? `Wait timed out. ${completed.length}/${tasks.length} selected task(s) finished.` : `Wait complete (${mode}). ${completed.length}/${tasks.length} selected task(s) finished.`;
const sections = completed.map((task) => formatTaskResult(task, maxResultChars));
const runningLines = running.map(
(task) => `Task ${task.id}: running${task.description ? ` (${task.description})` : ""}`
);
return [header, ...sections, ...runningLines].join("\n\n");
}
// src/agent/prompt.ts
function getPrompt(config = {}) {
const names = Object.keys(_nullishCoalesce(config.agents, () => ( {})));
const registryLine = names.length > 0 ? `Configured agents: ${names.join(", ")}.` : "No named agents are configured; the built-in default agent is used.";
return `Spawn and manage parallel subagents.
Use this tool when work can be split into focused independent investigations or checks.
${registryLine}
Actions:
- start: launch a subagent in the background and return a task id immediately.
- wait: wait internally for any or all selected tasks to finish.
- status: inspect one task.
- result: read one completed task result.
- list: show known tasks.
- stop: abort a running task.
Guidelines:
- Start multiple independent subagents before waiting when parallel work helps.
- Use wait instead of repeatedly polling status.
- Subagents do not receive this agent tool recursively.
- If a result is incomplete, start a narrower follow-up subagent or investigate directly.
- Stop tasks that are no longer useful.`;
}
// src/agent/schema.ts
var _zod = require('zod');
var inputSchema = _zod.z.discriminatedUnion("action", [
_zod.z.object({
action: _zod.z.literal("start"),
agent: _zod.z.string().optional().describe("Configured agent name to run"),
prompt: _zod.z.string().describe("User prompt for the subagent"),
description: _zod.z.string().optional().describe("Short task label"),
timeoutMs: _zod.z.number().int().positive().optional().describe("Run timeout in milliseconds")
}),
_zod.z.object({
action: _zod.z.literal("wait"),
taskIds: _zod.z.array(_zod.z.string()).optional().describe("Task ids to wait for. Defaults to all running tasks."),
mode: _zod.z.enum(["all", "any"]).optional().default("all").describe("Wait for all selected tasks or the first selected task"),
timeoutMs: _zod.z.number().int().nonnegative().optional().describe("Wait timeout in milliseconds"),
pollIntervalMs: _zod.z.number().int().positive().optional().describe("Internal polling interval in milliseconds")
}),
_zod.z.object({
action: _zod.z.literal("status"),
taskId: _zod.z.string().describe("Task id to inspect")
}),
_zod.z.object({
action: _zod.z.literal("result"),
taskId: _zod.z.string().describe("Task id to read")
}),
_zod.z.object({
action: _zod.z.literal("list")
}),
_zod.z.object({
action: _zod.z.literal("stop"),
taskId: _zod.z.string().describe("Task id to stop")
})
]);
// src/agent/tasks.ts
function activeTaskCount(tasks) {
let count = 0;
for (const task of tasks.values()) {
if (task.status === "running") count++;
}
return count;
}
function selectAgent(config, requestedName) {
const registry = _nullishCoalesce(config.agents, () => ( {}));
const registryNames = Object.keys(registry);
const name = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(requestedName, () => ( config.defaultAgent)), () => ( registryNames[0])), () => ( DEFAULT_AGENT_NAME));
const definition = _nullishCoalesce(registry[name], () => ( (name === DEFAULT_AGENT_NAME && registryNames.length === 0 ? fallbackAgent : void 0)));
if (!definition) {
const available = registryNames.length > 0 ? registryNames.join(", ") : DEFAULT_AGENT_NAME;
return `Unknown agent "${name}". Available agents: ${available}.`;
}
return { name, definition };
}
function getWaitTargets(tasks, taskIds) {
if (taskIds && taskIds.length > 0) {
const selected = [];
const missing = [];
for (const taskId of taskIds) {
const task = tasks.get(taskId);
if (task) selected.push(task);
else missing.push(taskId);
}
if (missing.length > 0) {
return `Unknown task id(s): ${missing.join(", ")}.`;
}
return selected;
}
return Array.from(tasks.values()).filter((task) => task.status === "running");
}
function stopTask(task, status, error) {
if (task.status !== "running") return;
task.status = status;
task.error = error;
task.endTime = Date.now();
if (task.timeoutId) {
clearTimeout(task.timeoutId);
task.timeoutId = void 0;
}
task.abortController.abort();
}
// src/agent/tools.ts
var AGENT_TOOL_NAME = "agent";
var agentTools = /* @__PURE__ */ new WeakSet();
function markAgentTool(agentTool) {
agentTools.add(agentTool);
return agentTool;
}
function isMarkedAgentTool(value) {
return typeof value === "object" && value !== null && agentTools.has(value);
}
function removeAgentTools(tools) {
if (!tools) return tools;
const toolEntries = Object.entries(tools);
const entries = toolEntries.filter(
([name, value]) => name !== AGENT_TOOL_NAME && !isMarkedAgentTool(value)
);
if (entries.length === toolEntries.length) return tools;
if (entries.length === 0) return void 0;
return Object.fromEntries(entries);
}
// src/agent/index.ts
function createAgent(config = {}) {
const tasks = /* @__PURE__ */ new Map();
const maxConcurrent = _nullishCoalesce(config.maxConcurrent, () => ( DEFAULT_MAX_CONCURRENT));
const defaultRunTimeoutMs = _nullishCoalesce(config.defaultTimeoutMs, () => ( DEFAULT_RUN_TIMEOUT_MS));
const defaultWaitTimeoutMs = _nullishCoalesce(config.defaultWaitTimeoutMs, () => ( DEFAULT_WAIT_TIMEOUT_MS));
const defaultPollIntervalMs = _nullishCoalesce(config.defaultPollIntervalMs, () => ( DEFAULT_POLL_INTERVAL_MS));
const maxResultChars = _nullishCoalesce(config.maxResultChars, () => ( DEFAULT_RESULT_CHARS));
function startTask(input) {
if (activeTaskCount(tasks) >= maxConcurrent) {
return `Error [agent]: Max concurrent subagents reached (${maxConcurrent}). Use wait, result, or stop before starting more.`;
}
const selected = selectAgent(config, input.agent);
if (typeof selected === "string") {
return `Error [agent]: ${selected}`;
}
const model = _nullishCoalesce(selected.definition.model, () => ( config.model));
if (!model) {
return "Error [agent]: No model configured. Provide createAgent({ model }) or an agent-specific model.";
}
const taskId = `agent_${_crypto.randomUUID.call(void 0, )}`;
const abortController = new AbortController();
const timeoutMs = _nullishCoalesce(input.timeoutMs, () => ( defaultRunTimeoutMs));
const task = {
id: taskId,
agentName: selected.name,
description: input.description,
prompt: input.prompt,
status: "running",
startTime: Date.now(),
abortController,
promise: Promise.resolve()
};
tasks.set(taskId, task);
task.timeoutId = setTimeout(() => {
stopTask(
task,
"timed_out",
`Subagent timed out after ${timeoutMs}ms.`
);
}, timeoutMs);
task.promise = (async () => {
try {
const maxTurns = _nullishCoalesce(_nullishCoalesce(selected.definition.maxTurns, () => ( config.maxTurns)), () => ( DEFAULT_MAX_TURNS));
const stopWhen = _nullishCoalesce(_nullishCoalesce(selected.definition.stopWhen, () => ( config.stopWhen)), () => ( _ai.stepCountIs.call(void 0, maxTurns)));
const result = await _ai.generateText.call(void 0, {
..._nullishCoalesce(config.settings, () => ( {})),
..._nullishCoalesce(selected.definition.settings, () => ( {})),
model,
tools: removeAgentTools(_nullishCoalesce(selected.definition.tools, () => ( config.tools))),
system: selected.definition.systemPrompt,
prompt: input.prompt,
stopWhen,
abortSignal: abortController.signal
});
if (task.status === "running") {
task.status = "completed";
task.result = result.text;
task.usage = result.usage;
task.endTime = Date.now();
}
} catch (error) {
if (task.status === "running") {
task.status = "failed";
task.error = _chunkKONXT2SFcjs.extractErrorMessage.call(void 0, error);
task.endTime = Date.now();
}
} finally {
if (task.timeoutId) {
clearTimeout(task.timeoutId);
task.timeoutId = void 0;
}
}
})();
return `Started subagent task ${taskId}.
Agent: ${selected.name}
Status: running
Use wait with taskIds ["${taskId}"] or wait for all running tasks.`;
}
async function waitForTasks(input, abortSignal) {
const targets = getWaitTargets(tasks, input.taskIds);
if (typeof targets === "string") return `Error [agent]: ${targets}`;
if (targets.length === 0) {
return "No running or selected subagent tasks to wait for.";
}
const mode = input.mode;
const timeoutMs = _nullishCoalesce(input.timeoutMs, () => ( defaultWaitTimeoutMs));
const pollIntervalMs = _nullishCoalesce(input.pollIntervalMs, () => ( defaultPollIntervalMs));
const deadline = Date.now() + timeoutMs;
while (true) {
const completed = targets.filter(isTerminal);
const done = mode === "any" ? completed.length > 0 : completed.length === targets.length;
if (done) {
return formatWaitResult(targets, mode, false, maxResultChars);
}
const remainingMs = deadline - Date.now();
if (remainingMs <= 0) {
return formatWaitResult(targets, mode, true, maxResultChars);
}
await _promises.setTimeout.call(void 0, Math.min(pollIntervalMs, remainingMs), void 0, {
signal: abortSignal
});
}
}
return markAgentTool(_ai.tool.call(void 0, {
description: _nullishCoalesce(config.description, () => ( getPrompt(config))),
inputSchema,
execute: async (input, options) => {
try {
switch (input.action) {
case "start":
return startTask(input);
case "wait":
return await waitForTasks(input, options.abortSignal);
case "status": {
const task = tasks.get(input.taskId);
return task ? formatTaskSummary(task) : `Error [agent]: Unknown task id "${input.taskId}".`;
}
case "result": {
const task = tasks.get(input.taskId);
return task ? formatTaskResult(task, maxResultChars) : `Error [agent]: Unknown task id "${input.taskId}".`;
}
case "list": {
if (tasks.size === 0) return "No subagent tasks have been started.";
return Array.from(tasks.values()).sort((a, b) => a.startTime - b.startTime).map(formatTaskSummary).join("\n\n");
}
case "stop": {
const task = tasks.get(input.taskId);
if (!task) return `Error [agent]: Unknown task id "${input.taskId}".`;
if (task.status !== "running") {
return `Task ${task.id} is already ${task.status}.`;
}
stopTask(task, "stopped", "Subagent stopped by orchestrator.");
return `Stopped subagent task ${task.id}.`;
}
}
} catch (error) {
return `Error [agent]: ${_chunkKONXT2SFcjs.extractErrorMessage.call(void 0, error)}`;
}
}
}));
}
var agent = createAgent();
exports.getPrompt = getPrompt; exports.createAgent = createAgent; exports.agent = agent;
+9
-1

@@ -38,2 +38,7 @@ "use strict";Object.defineProperty(exports, "__esModule", {value: true});

var _chunk6THYNTJFcjs = require('./chunk-6THYNTJF.cjs');
var _chunkLNAR3NJQcjs = require('./chunk-LNAR3NJQ.cjs');

@@ -181,2 +186,5 @@

exports.askUser = _chunkKUFZFNPTcjs.askUser; exports.askUserPrompt = _chunkKUFZFNPTcjs.getPrompt; exports.bash = _chunkDKN6WTRYcjs.bash; exports.bashPrompt = _chunkDKN6WTRYcjs.getPrompt; exports.compactMessages = _chunkB76NYX22cjs.compactMessages; exports.createAskUser = _chunkKUFZFNPTcjs.createAskUser; exports.createBash = _chunkDKN6WTRYcjs.createBash; exports.createDiff = _chunkOYLTQJXTcjs.createDiff; exports.createEdit = _chunk6ULQG2W2cjs.createEdit; exports.createGlob = _chunkBNICFVN5cjs.createGlob; exports.createGrep = _chunkNRU2KZIMcjs.createGrep; exports.createHttpRequest = _chunk5T3SQYI4cjs.createHttpRequest; exports.createLsp = _chunkNQIV6LBHcjs.createLsp; exports.createMemory = _chunkLNAR3NJQcjs.createMemory; exports.createMultiEdit = _chunkVPV6WG5Vcjs.createMultiEdit; exports.createOutputValidator = _chunk7HFEO5BWcjs.createOutputValidator; exports.createRead = _chunkHG5T47NAcjs.createRead; exports.createSleep = _chunkJYTOARJVcjs.createSleep; exports.createTaskCreate = _chunkSFDZRLSXcjs.createTaskCreate; exports.createTaskGet = _chunkXGDE7S2Dcjs.createTaskGet; exports.createTaskList = _chunk3FT4ZPB2cjs.createTaskList; exports.createTaskUpdate = _chunkT6STO7PScjs.createTaskUpdate; exports.createToolSearch = _chunk2JBLVFB7cjs.createToolSearch; exports.createWebFetch = _chunkG6ZVJA4Vcjs.createWebFetch; exports.createWebSearch = _chunkCM3VRCNXcjs.createWebSearch; exports.createWrite = _chunkABXTBB2Ncjs.createWrite; exports.diff = _chunkOYLTQJXTcjs.diff; exports.diffPrompt = _chunkOYLTQJXTcjs.getPrompt; exports.edit = _chunk6ULQG2W2cjs.edit; exports.editPrompt = _chunk6ULQG2W2cjs.getPrompt; exports.glob = _chunkBNICFVN5cjs.glob; exports.globPrompt = _chunkBNICFVN5cjs.getPrompt; exports.grep = _chunkNRU2KZIMcjs.grep; exports.grepPrompt = _chunkNRU2KZIMcjs.getPrompt; exports.httpRequest = _chunk5T3SQYI4cjs.httpRequest; exports.httpRequestPrompt = _chunk5T3SQYI4cjs.getPrompt; exports.lsp = _chunkNQIV6LBHcjs.lsp; exports.lspPrompt = _chunkNQIV6LBHcjs.getPrompt; exports.memory = _chunkLNAR3NJQcjs.memory; exports.memoryPrompt = _chunkLNAR3NJQcjs.getPrompt; exports.multiEdit = _chunkVPV6WG5Vcjs.multiEdit; exports.multiEditPrompt = _chunkVPV6WG5Vcjs.getPrompt; exports.outputValidator = _chunk7HFEO5BWcjs.outputValidator; exports.outputValidatorPrompt = _chunk7HFEO5BWcjs.getPrompt; exports.read = _chunkHG5T47NAcjs.read; exports.readPrompt = _chunkHG5T47NAcjs.getPrompt; exports.sleep = _chunkJYTOARJVcjs.sleep; exports.sleepPrompt = _chunkJYTOARJVcjs.getPrompt; exports.taskCreate = _chunkSFDZRLSXcjs.taskCreate; exports.taskCreatePrompt = _chunkSFDZRLSXcjs.getPrompt; exports.taskGet = _chunkXGDE7S2Dcjs.taskGet; exports.taskGetPrompt = _chunkXGDE7S2Dcjs.getPrompt; exports.taskList = _chunk3FT4ZPB2cjs.taskList; exports.taskListPrompt = _chunk3FT4ZPB2cjs.getPrompt; exports.taskUpdate = _chunkT6STO7PScjs.taskUpdate; exports.taskUpdatePrompt = _chunkT6STO7PScjs.getPrompt; exports.toolSearch = _chunk2JBLVFB7cjs.toolSearch; exports.toolSearchPrompt = _chunk2JBLVFB7cjs.getPrompt; exports.webFetch = _chunkG6ZVJA4Vcjs.webFetch; exports.webFetchPrompt = _chunkG6ZVJA4Vcjs.getPrompt; exports.webSearch = _chunkCM3VRCNXcjs.webSearch; exports.webSearchPrompt = _chunkCM3VRCNXcjs.getPrompt; exports.write = _chunkABXTBB2Ncjs.write; exports.writePrompt = _chunkABXTBB2Ncjs.getPrompt;
exports.agent = _chunk6THYNTJFcjs.agent; exports.agentPrompt = _chunk6THYNTJFcjs.getPrompt; exports.askUser = _chunkKUFZFNPTcjs.askUser; exports.askUserPrompt = _chunkKUFZFNPTcjs.getPrompt; exports.bash = _chunkDKN6WTRYcjs.bash; exports.bashPrompt = _chunkDKN6WTRYcjs.getPrompt; exports.compactMessages = _chunkB76NYX22cjs.compactMessages; exports.createAgent = _chunk6THYNTJFcjs.createAgent; exports.createAskUser = _chunkKUFZFNPTcjs.createAskUser; exports.createBash = _chunkDKN6WTRYcjs.createBash; exports.createDiff = _chunkOYLTQJXTcjs.createDiff; exports.createEdit = _chunk6ULQG2W2cjs.createEdit; exports.createGlob = _chunkBNICFVN5cjs.createGlob; exports.createGrep = _chunkNRU2KZIMcjs.createGrep; exports.createHttpRequest = _chunk5T3SQYI4cjs.createHttpRequest; exports.createLsp = _chunkNQIV6LBHcjs.createLsp; exports.createMemory = _chunkLNAR3NJQcjs.createMemory; exports.createMultiEdit = _chunkVPV6WG5Vcjs.createMultiEdit; exports.createOutputValidator = _chunk7HFEO5BWcjs.createOutputValidator; exports.createRead = _chunkHG5T47NAcjs.createRead; exports.createSleep = _chunkJYTOARJVcjs.createSleep; exports.createTaskCreate = _chunkSFDZRLSXcjs.createTaskCreate; exports.createTaskGet = _chunkXGDE7S2Dcjs.createTaskGet; exports.createTaskList = _chunk3FT4ZPB2cjs.createTaskList; exports.createTaskUpdate = _chunkT6STO7PScjs.createTaskUpdate; exports.createToolSearch = _chunk2JBLVFB7cjs.createToolSearch; exports.createWebFetch = _chunkG6ZVJA4Vcjs.createWebFetch; exports.createWebSearch = _chunkCM3VRCNXcjs.createWebSearch; exports.createWrite = _chunkABXTBB2Ncjs.createWrite; exports.diff = _chunkOYLTQJXTcjs.diff; exports.diffPrompt = _chunkOYLTQJXTcjs.getPrompt; exports.edit = _chunk6ULQG2W2cjs.edit; exports.editPrompt = _chunk6ULQG2W2cjs.getPrompt; exports.glob = _chunkBNICFVN5cjs.glob; exports.globPrompt = _chunkBNICFVN5cjs.getPrompt; exports.grep = _chunkNRU2KZIMcjs.grep; exports.grepPrompt = _chunkNRU2KZIMcjs.getPrompt; exports.httpRequest = _chunk5T3SQYI4cjs.httpRequest; exports.httpRequestPrompt = _chunk5T3SQYI4cjs.getPrompt; exports.lsp = _chunkNQIV6LBHcjs.lsp; exports.lspPrompt = _chunkNQIV6LBHcjs.getPrompt; exports.memory = _chunkLNAR3NJQcjs.memory; exports.memoryPrompt = _chunkLNAR3NJQcjs.getPrompt; exports.multiEdit = _chunkVPV6WG5Vcjs.multiEdit; exports.multiEditPrompt = _chunkVPV6WG5Vcjs.getPrompt; exports.outputValidator = _chunk7HFEO5BWcjs.outputValidator; exports.outputValidatorPrompt = _chunk7HFEO5BWcjs.getPrompt; exports.read = _chunkHG5T47NAcjs.read; exports.readPrompt = _chunkHG5T47NAcjs.getPrompt; exports.sleep = _chunkJYTOARJVcjs.sleep; exports.sleepPrompt = _chunkJYTOARJVcjs.getPrompt; exports.taskCreate = _chunkSFDZRLSXcjs.taskCreate; exports.taskCreatePrompt = _chunkSFDZRLSXcjs.getPrompt; exports.taskGet = _chunkXGDE7S2Dcjs.taskGet; exports.taskGetPrompt = _chunkXGDE7S2Dcjs.getPrompt; exports.taskList = _chunk3FT4ZPB2cjs.taskList; exports.taskListPrompt = _chunk3FT4ZPB2cjs.getPrompt; exports.taskUpdate = _chunkT6STO7PScjs.taskUpdate; exports.taskUpdatePrompt = _chunkT6STO7PScjs.getPrompt; exports.toolSearch = _chunk2JBLVFB7cjs.toolSearch; exports.toolSearchPrompt = _chunk2JBLVFB7cjs.getPrompt; exports.webFetch = _chunkG6ZVJA4Vcjs.webFetch; exports.webFetchPrompt = _chunkG6ZVJA4Vcjs.getPrompt; exports.webSearch = _chunkCM3VRCNXcjs.webSearch; exports.webSearchPrompt = _chunkCM3VRCNXcjs.getPrompt; exports.write = _chunkABXTBB2Ncjs.write; exports.writePrompt = _chunkABXTBB2Ncjs.getPrompt;

@@ -23,4 +23,5 @@ export { BashConfig, bash, bashPrompt, createBash } from './bash/index.cjs';

export { SleepConfig, createSleep, sleep, sleepPrompt } from './sleep/index.cjs';
export { AgentConfig, AgentTaskStatus, ManagedAgentDefinition, agent, agentPrompt, createAgent } from './agent/index.cjs';
export { B as BaseToolConfig, T as TimeoutConfig, a as ToolResult } from './types-3QPDuCXN.cjs';
import 'ai';
import '@ai-sdk/provider';

@@ -23,4 +23,5 @@ export { BashConfig, bash, bashPrompt, createBash } from './bash/index.js';

export { SleepConfig, createSleep, sleep, sleepPrompt } from './sleep/index.js';
export { AgentConfig, AgentTaskStatus, ManagedAgentDefinition, agent, agentPrompt, createAgent } from './agent/index.js';
export { B as BaseToolConfig, T as TimeoutConfig, a as ToolResult } from './types-3QPDuCXN.js';
import 'ai';
import '@ai-sdk/provider';

@@ -35,2 +35,7 @@ import {

import {
agent,
createAgent,
getPrompt as getPrompt22
} from "./chunk-34XNLXFI.js";
import {
createMemory,

@@ -117,2 +122,4 @@ getPrompt as getPrompt8,

export {
agent,
getPrompt22 as agentPrompt,
askUser,

@@ -123,2 +130,3 @@ getPrompt20 as askUserPrompt,

compactMessages,
createAgent,
createAskUser,

@@ -125,0 +133,0 @@ createBash,

+7
-2
{
"name": "agentool",
"version": "1.4.2",
"version": "1.5.0",
"type": "module",
"description": "22 AI agent tools + context-compaction helper as standalone Vercel AI SDK modules",
"description": "23 AI agent tools + context-compaction helper as standalone Vercel AI SDK modules",
"author": "Z-M-Huang",

@@ -151,2 +151,7 @@ "license": "Apache-2.0",

"require": "./dist/sleep/index.cjs"
},
"./agent": {
"types": "./dist/agent/index.d.ts",
"import": "./dist/agent/index.js",
"require": "./dist/agent/index.cjs"
}

@@ -153,0 +158,0 @@ },

@@ -5,3 +5,3 @@ <div align="center">

**22 AI agent tools + context-compaction helper for the [Vercel AI SDK](https://sdk.vercel.ai/).**
**23 AI agent tools + context-compaction helper for the [Vercel AI SDK](https://sdk.vercel.ai/).**

@@ -31,3 +31,3 @@ <p>

- **22 production-ready tools** -- bash, grep, glob, read, edit, write, web-fetch, web-search, tool-search, output-validator, memory, multi-edit, diff, task-create, task-get, task-update, task-list, lsp, http-request, ask-user, sleep
- **23 production-ready tools** -- bash, grep, glob, read, edit, write, web-fetch, web-search, tool-search, output-validator, memory, multi-edit, diff, task-create, task-get, task-update, task-list, lsp, http-request, ask-user, sleep, agent
- **Context-compaction middleware** -- transparent prompt compaction via `wrapLanguageModel()`, preserves system messages and recent turns

@@ -739,2 +739,44 @@ - **Vercel AI SDK compatible** -- works with `generateText()`, `streamText()`, and any AI SDK provider (OpenAI, Anthropic, Google, etc.)

---
### agent
Spawn and manage parallel subagents from an orchestrator session.
```typescript
import { openai } from '@ai-sdk/openai';
import { bash, grep, read } from 'agentool';
import { createAgent } from 'agentool/agent';
const agentTool = createAgent({
model: openai('gpt-4o'),
tools: { bash, grep, read },
agents: {
explorer: {
description: 'Explore one focused area of the codebase',
systemPrompt: 'You are a focused exploration subagent. Report findings with file references.',
},
},
});
const started = await agentTool.execute(
{
action: 'start',
agent: 'explorer',
prompt: 'Inspect src/auth and summarize the login flow',
description: 'auth flow',
},
{ toolCallId: 'id', messages: [] },
);
const finished = await agentTool.execute(
{ action: 'wait', mode: 'all', timeoutMs: 60000 },
{ toolCallId: 'id', messages: [] },
);
```
**Parameters:** `action` (`start`, `wait`, `status`, `result`, `list`, `stop`), plus action-specific fields.
Subagents do not receive the `agent` tool recursively, even if it is present in the configured toolset.
## Configuration

@@ -790,2 +832,3 @@

| `sleep` | `maxDuration?: number` -- cap in ms (default: 300000) |
| `agent` | `model?: LanguageModel`, `tools?: ToolSet`, `agents?: Record<string, ManagedAgentDefinition>`, `maxConcurrent?: number` |

@@ -834,2 +877,3 @@ ## Error Handling

sleep, createSleep,
agent, createAgent,
} from 'agentool';

@@ -863,2 +907,3 @@ ```

import { sleep } from 'agentool/sleep';
import { agent } from 'agentool/agent';
```

@@ -865,0 +910,0 @@