@agents-eco/reasoning
v0.1.0
Published
Reasoning module for AI agents — ReAct, Chain-of-Thought, Tree-of-Thought with HuggingFace SmolAgents and OpenAI-compatible backends. Built for agents.eco.
Maintainers
Readme
npm install @agents-eco/reasoningWhy This Exists
Most agent frameworks treat reasoning as a black box. You send a prompt, you get an answer. There is no visibility into how the agent thinks, no way to swap strategies, and no structured output to inspect.
This module makes reasoning explicit. Every thought, action, observation, and reflection is a structured step you can log, inspect, and hook into.
Three reasoning strategies, each suited to different problem types:
- ReAct — Multi-step reason-act loop with tool calling. Inspired by SmolAgents and Yao et al. 2022. Best for tasks requiring external information or computation.
- Chain-of-Thought (CoT) — Sequential step-by-step reasoning with optional self-reflection. Best for logic, math, and analytical problems.
- Tree-of-Thought (ToT) — Explores multiple reasoning paths using beam search. Best for complex problems with multiple valid approaches.
Two backend categories:
- OpenAI-compatible — OpenAI, Venice, Groq, Ollama, agents.eco. Any API that speaks the OpenAI chat format.
- HuggingFace — Inference API (serverless), Inference Endpoints (dedicated), or self-hosted TGI. Run SmolAgents-recommended models like Qwen, Llama, DeepSeek.
Quick Start
ReAct with Tool Calling
import { ReasoningEngine, veniceBackend } from "@agents-eco/reasoning";
const engine = new ReasoningEngine(
veniceBackend(process.env.VENICE_API_KEY!, "qwen3-4b"),
{ strategy: "react", maxSteps: 10 }
);
// Register tools
engine.tool("search", {
name: "search",
description: "Search the web for information",
parameters: {
type: "object",
properties: { query: { type: "string" } },
required: ["query"],
},
}, async ({ query }) => {
const res = await fetch(`https://api.duckduckgo.com/?q=${query}&format=json`);
const data = await res.json();
return data.AbstractText || "No results found.";
});
const result = await engine.reason("What is the population of Tokyo?");
console.log(result.answer);
console.log(`Steps: ${result.steps.length}, LLM calls: ${result.llmCalls}`);Chain-of-Thought
import { ReasoningEngine, openaiBackend } from "@agents-eco/reasoning";
const engine = new ReasoningEngine(
openaiBackend(process.env.OPENAI_API_KEY!, "gpt-4o"),
{ strategy: "cot", reflection: true }
);
const result = await engine.chainOfThought(
"A bat and a ball cost $1.10 in total. The bat costs $1.00 more than the ball. How much does the ball cost?"
);
for (const step of result.steps) {
console.log(`[${step.type}] ${step.content}`);
}
// Thought: Let x = ball price...
// Thought: x + (x + 1.00) = 1.10...
// Answer: The ball costs $0.05Tree-of-Thought
import { ReasoningEngine, groqBackend } from "@agents-eco/reasoning";
const engine = new ReasoningEngine(
groqBackend(process.env.GROQ_API_KEY!, "llama-3.3-70b-versatile"),
{ strategy: "tot" }
);
const result = await engine.treeOfThought(
"Design a sorting algorithm that is optimal for nearly-sorted arrays.",
{ branchFactor: 3, maxDepth: 4, beamWidth: 2, scoringMethod: "llm" }
);
console.log(result.answer);
console.log(`Explored ${result.steps.filter(s => s.type === "thought").length} branches`);HuggingFace / SmolAgents Models
import { ReasoningEngine, hfInferenceBackend, SMOLAGENTS_MODELS } from "@agents-eco/reasoning";
// Serverless Inference API
const engine = new ReasoningEngine(
hfInferenceBackend(process.env.HF_TOKEN!, SMOLAGENTS_MODELS.qwen72b),
{ strategy: "react", maxSteps: 8 }
);
const result = await engine.reason("Explain the Riemann hypothesis.");import { hfEndpointBackend, tgiBackend } from "@agents-eco/reasoning";
// Dedicated Inference Endpoint
const endpoint = hfEndpointBackend(
process.env.HF_TOKEN!,
"https://xyz.endpoints.huggingface.cloud"
);
// Self-hosted TGI
const local = tgiBackend("http://localhost:8080");Local with Ollama
import { ReasoningEngine, ollamaBackend } from "@agents-eco/reasoning";
const engine = new ReasoningEngine(
ollamaBackend("llama3.2"),
{ strategy: "cot", reflection: true }
);
const result = await engine.reason("What are the trade-offs between B-trees and LSM-trees?");Architecture
┌──────────────────────────────────────────────────────────┐
│ ReasoningEngine │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Strategies │ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────────┐ ┌───────────────┐ │ │
│ │ │ ReAct │ │ Chain-of- │ │ Tree-of- │ │ │
│ │ │ │ │ Thought │ │ Thought │ │ │
│ │ │ Thought │ │ │ │ │ │ │
│ │ │ Action │ │ Step 1 │ │ [root] │ │ │
│ │ │ Observe │ │ Step 2 │ │ / | \ │ │ │
│ │ │ Reflect │ │ Step N │ │ A B C │ │ │
│ │ │ Plan │ │ Reflect │ │ / \ | │ │ │
│ │ │ Answer │ │ Answer │ │ D E F │ │ │
│ │ └──────────┘ └──────────────┘ └───────────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────▼────────────────────────────┐ │
│ │ Tools │ │
│ │ search, calculate, fetch, execute, ... │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────▼────────────────────────────┐ │
│ │ LLM Backends │ │
│ │ │ │
│ │ OpenAI Venice Groq Ollama agents.eco │ │
│ │ HuggingFace (Inference API / Endpoints / TGI) │ │
│ └─────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘Strategies
ReAct (Reason + Act)
The default strategy. Implements the multi-step reasoning loop from SmolAgents and the ReAct paper (Yao et al., 2022).
Each step follows: Thought -> Action -> Observation, with optional Reflection and Planning.
| Feature | Description | |---------|-------------| | Tool calling | Register handlers, agent decides when to use them | | Reflection | Self-evaluation every N steps (configurable) | | Planning | Initial plan + periodic revision | | Self-correction | Agent retries on tool errors with different approach | | Max steps | Hard limit to prevent infinite loops |
Chain-of-Thought (CoT)
Single-pass sequential reasoning. The LLM breaks the problem into numbered steps and arrives at an answer.
| Feature | Description | |---------|-------------| | Step parsing | Extracts individual reasoning steps from output | | Self-reflection | Optional second pass to verify the chain | | Revision | If reflection finds errors, produces a corrected answer |
Tree-of-Thought (ToT)
Explores multiple reasoning paths in parallel using beam search.
| Feature | Description | |---------|-------------| | Branch generation | LLM generates N distinct next steps at each node | | Branch scoring | LLM-based or heuristic scoring (0-1) | | Beam search | Keeps top-k branches at each depth | | Path extraction | Best path is used to generate the final answer |
Hooks
Intercept every step of the reasoning process:
const engine = new ReasoningEngine(backend, {
strategy: "react",
maxSteps: 10,
hooks: {
onStep: (step) => console.log(`[${step.type}] ${step.content.slice(0, 80)}`),
onThought: (thought) => console.log(`Thinking: ${thought}`),
onAction: (tool, args) => console.log(`Calling: ${tool}(${JSON.stringify(args)})`),
onObservation: (result) => console.log(`Got: ${result.slice(0, 80)}`),
onReflection: (reflection) => console.log(`Reflecting: ${reflection}`),
onPlan: (plan) => console.log(`Plan: ${plan}`),
onAnswer: (answer) => console.log(`Answer: ${answer}`),
onError: (error) => console.error(`Error: ${error.message}`),
},
});SmolAgents-Recommended Models
Pre-configured model constants for HuggingFace:
| Key | Model | Notes |
|-----|-------|-------|
| qwen72b | Qwen/Qwen2.5-72B-Instruct | Best open reasoning model |
| qwen32b | Qwen/Qwen2.5-32B-Instruct | Good balance of speed and quality |
| qwen7b | Qwen/Qwen2.5-7B-Instruct | Fast, good for simple tasks |
| llama70b | meta-llama/Llama-3.3-70B-Instruct | Strong reasoning, open weights |
| llama8b | meta-llama/Llama-3.1-8B-Instruct | Fast Llama variant |
| deepseek | deepseek-ai/DeepSeek-R1-Distill-Qwen-32B | Code-focused reasoning |
| mistral | mistralai/Mistral-Small-24B-Instruct-2501 | Compact but capable |
import { SMOLAGENTS_MODELS } from "@agents-eco/reasoning";
console.log(SMOLAGENTS_MODELS.qwen72b); // "Qwen/Qwen2.5-72B-Instruct"Integration with Open Agentic Framework
Use as the reasoning backend for @agents-eco/open-agentic-framework:
import { Agent } from "@agents-eco/open-agentic-framework";
import { ReasoningEngine, veniceBackend } from "@agents-eco/reasoning";
const reasoning = new ReasoningEngine(
veniceBackend(process.env.VENICE_API_KEY!, "qwen3-4b"),
{ strategy: "react", maxSteps: 8, reflection: true }
);
const agent = new Agent({
name: "reasoning-agent",
systemPrompt: "You are a thoughtful assistant that reasons step by step.",
provider: {
name: "venice",
apiKey: process.env.VENICE_API_KEY!,
baseUrl: "https://api.venice.ai/api/v1",
defaultModel: "qwen3-4b",
},
hooks: {
beforeRequest: async (messages) => {
// Use reasoning engine for complex queries
const lastMsg = messages[messages.length - 1];
if (lastMsg.role === "user" && lastMsg.content.length > 100) {
const result = await reasoning.reason(lastMsg.content);
messages.push({
role: "system",
content: `Reasoning trace:\n${result.steps.map(s => `[${s.type}] ${s.content}`).join("\n")}`,
});
}
return messages;
},
},
});API Reference
ReasoningEngine
| Method | Description |
|--------|-------------|
| reason(task, overrides?) | Run reasoning with configured strategy |
| react(task, overrides?) | Run ReAct reasoning |
| chainOfThought(task, overrides?) | Run CoT reasoning |
| treeOfThought(task, overrides?) | Run ToT reasoning |
| tool(name, def, handler) | Register a tool |
| addTools(toolMap) | Register multiple tools |
| setBackend(backend) | Swap the LLM backend |
| setSystemPrompt(prompt) | Set the system prompt |
| configure(config) | Update configuration |
| hooks(hooks) | Set event hooks |
| registerStrategy(strategy) | Add a custom strategy |
ReasoningResult
| Field | Type | Description |
|-------|------|-------------|
| answer | string | Final answer |
| steps | ReasoningStep[] | All reasoning steps |
| strategy | StrategyType | Strategy used |
| durationMs | number | Total time |
| tokens | {prompt, completion, total} | Token usage |
| llmCalls | number | Number of LLM calls |
| toolCalls | number | Number of tool calls |
| success | boolean | Whether reasoning succeeded |
ReasoningStep
| Field | Type | Description |
|-------|------|-------------|
| type | StepType | thought, action, observation, reflection, plan, revision, answer, error |
| content | string | Step content |
| confidence | number | Confidence score (0-1) |
| toolCalls | ToolCall[] | Tool calls made |
| toolResults | ToolResult[] | Tool results received |
| durationMs | number | Step duration |
Contributing
We welcome contributions. This project is early and there is room to shape its direction.
- Add a strategy — Implement the
ReasoningStrategyinterface for new approaches (Reflexion, MCTS, etc.) - Add a backend — Anthropic, Cohere, local transformers
- Improve prompts — Better ReAct/CoT/ToT prompts for specific model families
- Add benchmarks — Test against GSM8K, MATH, HotpotQA, etc.
- Report issues — Bug reports and feature requests help us prioritize
License
MIT — agents.eco
