braiin
v0.4.3
Published
Behavioral Reasoning AI for Intelligent Navigation
Maintainers
Readme
🧠 BRAIIN - Behavioral Reasoning AI for Intelligent Navigation
BRAIIN is an AI-powered tool orchestrator that intelligently selects and combines API calls, database queries, and external tools to achieve complex tasks. Inspired by systems like J.A.R.V.I.S., BRAIIN enables autonomous reasoning to determine the best execution path for a given request.
🚀 Features
- 🏗 Tool Orchestration – Dynamically chooses the best tools (APIs, databases, system commands) for a task.
- 🔄 Multi-Step Reasoning – Can combine multiple tools to solve complex problems.
- 🧠 LLM-Powered Decision Making – Uses large language models (LLMs) to analyze and optimize tool usage.
- 🔌 Flexible & Extendable – Easily add custom tools for specific use cases.
- ⚡ Real-Time Execution – Executes tasks efficiently with minimal latency.
- 📡 Answer Streaming – Stream the final answer token by token to your UI via
onToken, with no extra LLM call. - 🧩 Structured Tool Input – Tools accept simple strings or structured objects for complex parameters.
- 🔁 Context Persistence – Tool results are tracked across tasks to avoid redundant calls.
📦 Installation
npm install braiin openaiConcept
BRAIIN is based on the concept of an Orchestrator and one or multiple Agents that have each one or multiple Tools.
- A tool is an object that has a tag, a description, an input and an output fields. Its purpose is to achieve a given specific goal like writing a file. The input can be a simple string description or an array of structured parameters.
- An agent is an object that has a name, a description and a list of tools. Each agent is specialised in a specific topic (math, management, handling files, ...) and has a set of tools (write file, read file, ...) that can be used to achieve a specific goal.
- An orchestrator is an object that has a set of agents that are each specialised in a specific topic. The orchestrator is the one that orchestrates the execution of the tools based on the user's request. It is the one that chooses which agent to use and which tool to use, it is capable of combining the tools to achieve the best result.

Example
// user.retriever.tool.ts
import { Tool } from 'braiin'
const users = [
{ name: 'User 1', age: 25, email: '[email protected]' },
{ name: 'User 2', age: 30, email: '[email protected]' },
{ name: 'User 3', age: 35, email: '[email protected]' }
]
export const userRetrieverTool: Tool = {
tag: 'user-retriever',
description: 'Retrieve a user informations from its name',
input: 'The user\'s name',
output: 'A json object containing the user\'s informations if the user was found, an empty string otherwise',
call: async (userName) => {
const user = users.find(u => u.name === userName)
return user ? JSON.stringify(user) : ''
}
}// user.birth.tool.ts
import { Tool } from 'braiin'
export const userBirthYearTool: Tool = {
tag: 'user-birth-year',
description: 'Compute the birth year of a user from its age',
input: 'The user\'s age',
output: 'A number representing the user\'s birth year',
call: async (age) => {
const year = new Date().getFullYear()
const ageAsNumber = age ? parseInt(age as string) : year
return `${year - ageAsNumber}`
}
}// index.ts
import { userRetrieverTool } from './user.retriever.tool'
import { userBirthYearTool } from './user.birth.tool'
import { createAgent, createOrchestrator } from 'braiin'
const userAgent = createAgent(
'user-agent',
'You are a useful assistant that answers questions about users.',
[userRetrieverTool, userBirthYearTool]
)
const orchestrator = createOrchestrator(
[userAgent],
{
apiKey: 'your api key',
model: 'gpt-4o',
serverUrl: 'https://api.openai.com/v1',
temperature: 0
}
)
const result = await orchestrator.executeTask(
'When was User 1 born?'
)
console.log(result.answer) // User 1 was born in 2001
console.log(result.status) // 'success'
console.log(result.toolTraces) // [{ tool: 'user-retriever', input: 'User 1', result: '...' }, ...]Streaming the final answer
Pass an onToken callback as the 5th argument of executeTask to stream the final answer token by token, exactly as the model writes it — with no extra LLM call:
const result = await orchestrator.executeTask(
'When was User 1 born?',
[], // history (optional)
[], // toolTraces (optional)
undefined, // logCallback (optional — raw protocol of every step, for debugging)
(token) => process.stdout.write(token) // onToken — streamed final answer
)
console.log(result.answer) // still holds the full answer once the chain completesOnly the final answer is streamed — the intermediate agent/tool steps are not. onToken is purely additive: the same answer is also returned in result.answer. On the OpenAI-compatible backend the answer streams token by token; on a non-streaming backend it is delivered in a single chunk at the end.
Context Persistence
Tool results are tracked as toolTraces and can be passed between calls to avoid redundant tool executions:
const first = await orchestrator.executeTask('Tell me about User 1\'s wife')
// first.toolTraces holds only the traces produced by THIS call
const second = await orchestrator.executeTask(
'Has User 1 been married before?',
[],
first.toolTraces // injected as context, so tools aren't re-run
)
// second.toolTraces holds only the second call's traces.
// Accumulate across turns yourself if you need the full history:
const allTraces = [...first.toolTraces, ...second.toolTraces]TaskResult.toolTraces contains only the traces produced during that call. Passing prior traces injects them as context (the model reuses their results) but does not echo them back into the next result — you accumulate them yourself if you need a running history.
Structured Tool Input
Tools can define structured parameters instead of a simple string description:
import { Tool } from 'braiin'
const writeFileTool: Tool = {
tag: 'write-file',
description: 'Write content to a file',
input: [
{ name: 'path', description: 'The file path', required: true },
{ name: 'content', description: 'The file content', required: true }
],
output: 'Confirmation that the file was written',
call: async (input) => {
const { path, content } = input as Record<string, string>
// write file logic here
return `File written to ${path}`
}
}Configuration
| Option | Default | Description |
| --- | --- | --- |
| apiKey | required | Your LLM API key |
| model | 'gpt-4o' | The model to use |
| serverUrl | 'https://api.openai.com/v1' | Base URL for any OpenAI-compatible API |
| temperature | 0 | LLM temperature |
| maxSteps | 50 | Maximum chain iterations (prevents infinite loops) |
| stepsInterval | undefined | Delay in ms between chain steps (rate limiting) |
| optionalPrompt | undefined | Additional instructions appended to the system prompt |
Claude Code skill
braiin ships with a Claude Code skill that teaches the agent how to use the library — the primitives, the LLM protocol, every config option, streaming, and best practices. Install it once after adding the dependency:
npx braiin init-skill # installs into ./.claude/skills/braiin (this project)
npx braiin init-skill --global # installs into ~/.claude/skills/braiin (all projects)Claude Code does not auto-discover skills inside node_modules, so this one-time command copies the bundled skill to where Claude Code looks for it. The skill is versioned with the library — re-run the command after upgrading braiin to refresh the guidance. The project-level .claude/skills/braiin can be committed so your whole team gets it automatically.
