npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

deepthink-js

v2.0.1

Published

SOTA NPM module for agentic processes using local or cloud LLMs.

Readme

Deepthink

An AI reasoning engine with multi-step thinking, sandboxed code execution, deep web research, autonomous browser control, self-verifying answer loops, persona debate, self-consistency voting, plan-and-execute, tool use, reflexion, mixture-of-agents, and confidence calibration. Works with Ollama, OpenAI, Claude, Gemini, Perplexity, Grok, and LM Studio.


Table of Contents


Overview

Deepthink wraps any LLM provider with a stack of reasoning infrastructure:

  • Multi-provider support — Ollama, OpenAI, Claude (Anthropic), Gemini (Google), Perplexity, Grok (xAI), LM Studio, or any OpenAI-compatible endpoint
  • Multi-depth thinking — up to 3 staged internal reasoning passes (analysis → planning → sanity check) before the final response
  • Typed output parsing — returns string, integer, double, or boolean directly from free-form model output
  • Self-verification loops — adversarial and numerical checker agents review responses and drive iterative repair
  • Sandboxed code execution — generates and runs JavaScript in an isolated-vm isolate (32 MB cap, 5 s timeout) and Python in a guarded subprocess to verify numeric answers
  • MCTS consensus — runs multiple algorithmic approaches in parallel and votes on the most consistent result
  • 9-step deep research pipeline — query planning → crawling → credibility scoring → MMR diversity → fact verification → report writing → critique loops
  • Universal URL-to-HTML extractor — fetches and converts HTML, PDF, DOCX, XLSX, PPTX, EPUB, CSV, RTF, ODT, JSON, XML, Markdown, images, and SVG
  • Chrome TLS fingerprint spoofingimpit-backed axios adapter that bypasses bot-detection
  • Autonomous Electron browser — a free-roaming AI agent that browses the web with human-like mouse events, multi-tab management, and reflective session summaries
  • AI code project generator — cognitive planning → code generation → AST validation → sandbox execution → test oracle → iterative repair
  • Self-consistency voting — sample N candidates in parallel, return the majority
  • Persona debate — two opposing agents argue, an impartial judge picks the stronger side
  • Plan-and-execute — explicitly plan atomic steps, run each, reflect, then synthesize
  • Reflexion — after a failure, write a one-sentence lesson; recall similar lessons before the next attempt
  • Mixture-of-agents — fan out to N providers, judge merges the strongest elements
  • Tool use — model emits JSON tool calls; the engine runs js_eval / py_eval / custom tools in a sandbox, loops until finish
  • Smart context compression — when token budget overflows, summarize the middle, keep the head and tail
  • Persistent memory — JSON-file-backed store at ~/.deepthink-js/memory.json for cross-session state
  • Confidence calibration — track per-type wins/losses; blend with a 0.5 prior at low N

What's new in v1.4.0

  • TypeScript source.ts everywhere, build output in dist/. Build with npx tsc, typecheck with npx tsc --noEmit. index.d.ts exposes the full public surface.
  • EventEmitter on Deepthinkdt.on('log', e => …) and dt.on('step', e => …) instead of the old console.log with ANSI colors. Default is silent. The constructor bridges globalEmitter (research pipeline + code generator) onto the instance, so one subscriber catches every pipeline event.
  • isolated-vm JS sandboxrunJSSandbox runs in a 32 MB memory-limit, 5 s hard-timeout, 1 s heap-watch isolate. require is blocked outright — host modules never cross the isolation wall. Python stays on the subprocess fallback.
  • Zod for LLM JSONparseJsonSafe(text, schema) returns { ok: true, data } | { ok: false, error, raw }. Errors are real Error / ZodError instances, no null cast. tryParseJsonSafe is the T | null shortcut. Schemas in parse/llmSchemas.ts.
  • codeGenerator split — was 1,974 lines, now codeGenerator/{index,sandbox,fileBlocks,python,run,project}.ts. Public API unchanged.

Installation

Install deepthink-js from npm — all dependencies are bundled automatically:

npm install deepthink-js

Building from source (only if you're working on the lib itself):

git clone https://github.com/crazystuffxyz/deepthink-js
cd deepthink-js
npm install
npx tsc              # emit .js + .d.ts into dist/
npx tsc --noEmit     # typecheck only
npm test             # runs tests/test_*.js against dist/

For the Electron explorer example only:

npm install electron pdf-parse

For Python sandbox support (optional but recommended for numeric verification):

pip install sympy

Node.js ≥ 18 is required. The package uses ES Modules — set "type": "module" in your package.json.


Quick Start

import Deepthink from 'deepthink-js';

// Ollama (default — no API key needed)
const dt = new Deepthink('cogito-2.1:671b-cloud');

// 1. Simple string generation
const answer = await dt.generate('What is the capital of France?');
console.log(answer); // "Paris"

// 2. Typed integer output with 2-stage thinking and 2 verification checks
const count = await dt.generate(
  'How many prime numbers are less than 50?',
  { type: 'integer', depth: 2, checks: 2 }
);
console.log(count); // 15

// 3. Streaming response for long-form content
await dt.generate(
  'Explain the Riemann Hypothesis in plain language.',
  {
    depth: 1,
    onChunk: (chunk, meta) => process.stdout.write(chunk)
  }
);

// 4. Full Project Generation (AI App Builder)
import { generateAndRunProject } from 'deepthink-js/thinking/codeGenerator.js';
const callChat = dt.callChat.bind(dt);
const project = await generateAndRunProject(callChat, 'Build a personal finance dashboard with chart.js');
console.log('Project created with', Object.keys(project.files).length, 'files');

Multi-Provider Setup

Pass clientOptions.provider to the constructor to route calls to any supported backend.

OpenAI

const dt = new Deepthink('gpt-4o', [process.env.OPENAI_API_KEY], { provider: 'openai' });

Anthropic Claude

const dt = new Deepthink('claude-opus-4-6', [process.env.ANTHROPIC_API_KEY], { provider: 'claude' });

Google Gemini

const dt = new Deepthink('gemini-2.5-flash', [process.env.GEMINI_API_KEY], { provider: 'gemini' });

Perplexity

const dt = new Deepthink('sonar-pro', [process.env.PERPLEXITY_API_KEY], { provider: 'perplexity' });

Grok (xAI)

const dt = new Deepthink('grok-3', [process.env.XAI_API_KEY], { provider: 'grok' });

LM Studio (local)

const dt = new Deepthink('my-local-model', [], { provider: 'lmstudio' });

Any OpenAI-Compatible Endpoint

const dt = new Deepthink('my-model', ['my-api-key'], {
  provider: 'openai-compat',
  baseUrl: 'https://my-custom-server.example.com/v1',
});

Core API — Deepthink Class

Constructor

new Deepthink(model, apiKeys, clientOptions, concurrency, auditModel)

| Parameter | Type | Default | Description | |-----------------|------------|-------------------------|-------------| | model | string | process.env.OLLAMA_MODEL \|\| 'llama3.1' | Primary model identifier | | apiKeys | string[] | [] | API keys for the selected provider, rotated automatically on failure and quarantined for 60 s after 2 consecutive errors | | clientOptions | object | {} | Provider configuration — see clientOptions table below | | concurrency | number | Infinity | Maximum simultaneous in-flight requests | | auditModel | string | same as model | Model used for verification checker agents |

clientOptions fields:

| Field | Description | |--------------|-------------| | provider | One of: ollama (default), openai, claude, gemini, perplexity, grok, lmstudio, openai-compat | | baseUrl | Override the base URL for the selected provider | | host | Alias for baseUrl | | apiKey | Inline API key (alternative to passing via constructor apiKeys array) | | headers | Extra HTTP headers merged into every request | | anthropicVersion | Anthropic API version header (default: 2023-06-01) |

Environment variables (fallback when no key is passed):

| Variable | Used by provider | |-----------------------|-----------------| | OLLAMA_HOST | Ollama | | OLLAMA_API_KEY | Ollama | | OLLAMA_MODEL | Ollama | | OPENAI_API_KEY | OpenAI | | ANTHROPIC_API_KEY | Claude | | GEMINI_API_KEY | Gemini | | PERPLEXITY_API_KEY | Perplexity | | XAI_API_KEY | Grok |


callChat()

Low-level chat method with automatic retry, streaming fallback, and API key rotation.

const result = await dt.callChat(messages, stream, onChunk, opts);
// result: { content: string, thinking: string }

| Parameter | Type | Description | |------------|------------|-------------| | messages | Message[]| OpenAI-style [{ role, content }] array | | stream | boolean | Enable streaming | | onChunk | function | (chunk, { kind: 'content' \| 'thinking' }) => void | | opts | object | See options reference |

Retries up to 3 times with exponential backoff (500 ms → 1 s → 2 s).


generate()

High-level generation with named parameters, multi-stage thinking, code sandboxing, and self-verification.

const result = await dt.generate(input, opts);

| Parameter | Type | Description | |------------|----------------------------------------------------------|-------------| | input | string \| Message[] \| object | The prompt — plain string, messages array, or any object | | opts | object | Named options — see full table below |

All options are passed as a single named object. This makes call sites self-documenting:

// Simple call — all defaults
await dt.generate('What is pi?');

// Fully configured call
await dt.generate('Count the prime numbers below 1000', {
  type:    'integer',
  depth:   2,
  checks:  2,
  model:   'gpt-4o',          // override for this call only
  onChunk: chunk => process.stdout.write(chunk),
});

// Streaming creative writing
await dt.generate('Write a short story about a robot.', {
  depth:   1,
  onChunk: (chunk, meta) => process.stdout.write(chunk),
  options: { temperature: 0.9 },
});

// Research-style deep thinking with analytical decomposition
const answer = await dt.generate('What are all distinct ways to tile a 2×8 board with 1×2 dominoes?', {
  type:       'integer',
  depth:      3,
  checks:     3,
  analytical: true,
});

generate() options object:

| Option | Type | Default | Description | |--------------------------|------------|-------------|-------------| | type | string | 'string' | Return type: 'string', 'integer', 'double', 'boolean' | | depth | 0–3 | 1 | Internal thinking stages before final answer | | checks | number | 0 | Verification checker passes (max 3) | | checkStyle | string | 'full' | 'full' = checkers audit the whole draft; 'blind' = checkers see only the claimed answer and must re-derive it | | answerFormat | string | none | 'bracket' — demand the final answer as [value] on the last line so extractors find it unambiguously | | onChunk | function | null | Streaming callback (chunk, meta) => void | | model | string | constructor model | Override model for this call | | systemPrompt | string | auto | Custom system prompt | | autoSystemPrompt | boolean | true | Inject a default system prompt | | think | boolean | false | Enable model's native <think> token | | enableCode | boolean | true | Auto-detect and run sandboxed code | | mcts | boolean | true | Enable MCTS multi-approach consensus | | mctsNumApproaches | number | 4 | Algorithmic approaches for MCTS | | mctsConsensusThreshold | number | 3 | Minimum agreement count for HIGH confidence | | analytical | boolean | false | Multi-agent analytical decomposition mode | | humanBrain | boolean | false | Attach a BrainMemory (working + semantic) | | maxCheckIterations | number | 10 | Max self-verification repair iterations | | finalConsistency | boolean | true | After checks pass, one independent blind re-derivation; reconciles on mismatch (skipped when the sandbox machine-verified the answer) | | monitorWindowSize | number | 5 | MetacognitiveMonitor response history window | | images | string[] | [] | Base64 image strings for multimodal input | | options | object | {} | Raw provider sampling params (temperature, top_p, etc.) | | _globalBudget | object | none | { maxLLMCalls: number } — hard cap on total LLM calls | | ollamaOutput | boolean | false | Return raw <think> blocks in output (Ollama only) |

Depth levels:

| Depth | Stages | |-------|--------| | 0 | Direct answer — no pre-thinking | | 1 | Analysis pass | | 2 | Analysis → Planning | | 3 | Analysis → Planning → Sanity Check |


Self-Verification Checks

With checks > 0 the pipeline audits the draft with up to 3 persona checkers (Standard QA, Red-Team Adversarial, Numerical Forensic) and revises until they pass:

  • checkStyle: 'full' (default) — checkers audit the whole draft.
  • checkStyle: 'blind' — checkers see ONLY the claimed answer and must re-derive it from the problem (verifier-blind; tests whether seeing the reasoning biases the audit). Claimed answer is the final [bracket] line.
  • Sandbox cross-validation — when code runs, a result is stamped verified only if independent implementations agree (MCTS consensus ≥3 votes across ≥2 domains, or JS ≡ Python). Checkers then treat it as ground truth and must not contradict it. Otherwise it is a candidate the checkers may overturn.
  • Escapes — the revision loop stops early instead of burning tokens when (a) the same Y/N verdict pattern repeats (no convergence), (b) the passed count stalls across 3 revisions, or (c) the metacognitive monitor detects feedback/response churn.

New Reasoning Modes

Additive — pass any of these as options to dt.generate(input, opts). They do not change the existing options; they just route to a different reasoning module before the main flow.

// Self-consistency: sample N candidates, return the majority
const r = await dt.generate('What is 6 * 7?', {
  type: 'integer',
  selfConsistency: true,
  selfConsistencySamples: 5,
});

// Persona debate: two agents argue, judge picks the stronger side
const r = await dt.generate('Is intermittent fasting healthier than 3 meals a day?', {
  debate: true,
  debateRounds: 2,
});

// Plan-and-execute: explicit plan, run each step, reflect, synthesize
const r = await dt.generate('List the first 5 prime numbers.', {
  planExecute: true,
});

// Tool use: model emits JSON tool calls, engine runs them, loops until 'finish'
const r = await dt.generate('Compute 11 * 11, then call finish with the answer.', {
  tools: true,           // or pass an array of custom tools
  maxSteps: 4,
});

// Reflexion: recall past lessons, then write a new lesson on failure
const r = await dt.generate('What is 17 * 19?', {
  type: 'integer',
  reflexion: true,
  // _lastResultFailed: 'wrong answer'  // pass this to trigger a lesson write
});

// Mixture-of-agents: fan out to N providers, judge merges
const r = await dt.generate('Summarize the causes of WWI in 50 words.', {
  mixtureModels: ['gemma4:31b-cloud', 'gemma4:31b-cloud'],
  // each entry can also be { name, callChat } for cross-provider routing
});

// Confidence calibration: track wins/losses per task type
const r = await dt.generate('2 + 2 = ?', { type: 'integer', calibrate: true });
// dt._calibrator (private) holds the running stats; expose via your own getter

// Evolved thinking: synthetic-RL prompt evolution. generates N candidate prompt templates,
// scores each on a 10-item benchmark, mutates the best, repeats. applies the winner to your input.
const r = await dt.generate('Explain the Banach-Tarski paradox in plain English.', {
  evolve: true,
  evolvePop: 10,            // candidates per generation
  evolveGenerations: 6,     // how many rounds of mutation
  // evolveOnly: true,     // just run evolution, skip the apply step
});

Evolved Thinking (prompt evolution)

The evolve mode is built on three ideas pulled from real reasoning research:

  1. Patterns from geniuses — the thinkingPatterns.js library contains 25+ citable thinking moves, each tied to a named thinker (Feynman, Erdős, Ramanujan, Poincaré, Tao, Knuth, Sagan, Curie, Turing, McClintock, Lamarr, Kahneman, von Neumann, Dijkstra, Lovelace, Fuller, ...). Every move is one concrete instruction the LLM can follow.
  2. Synthetic-RL evolution — a population of 10 prompt-template candidates is generated by composing these patterns, scored against a fixed 10-item benchmark (math, logic, code, science, paradox, planning, hypothesis, ethics, deduction), mutated via 12 operators (add-reconsider, add-feynman-elaborate, add-counter-example, add-verification, add-devils-advocate, add-numerical-sanity, add-analogy, add-parallel-drafts, add-lemma-decompose, add-incubation, change-tone-socratic, compress-to-half), and selected by tournament. The loop runs for N generations. The full per-generation log is written to data/evolved/<runId>/population-gen-NNN.json so you can see what each generation found.
  3. Generalization — the winning template is a composition of moves from different thinkers, which means it generalizes across task types (no overfit to one benchmark item).
import { evolvePrompts, applyEvolvedPrompt, loadBest, PATTERNS, BENCH, OOD_BENCH } from 'deepthink-js';

// run evolution with the OOD probe — the loop trains on BENCH, then scores
// the winner on the held-out OOD_BENCH and reports the gap.
const result = await evolvePrompts(callChat, {
  popSize: 10,
  generations: 8,
  bench: BENCH,
  oodBench: OOD_BENCH,
});
console.log('best:', result.best.id, 'fitness:', result.best.fitness);
if (result.oodScore != null) {
  const gap = (result.best.fitness || 0) - result.oodScore;
  console.log(`OOD: ${result.oodScore.toFixed(3)}  gap: ${gap.toFixed(3)}${gap > 0.20 ? '  ⚠ overfit' : '  ✓ generalizes'}`);
}
console.log('log at:', result.runDir);

// apply the winning template to a new hard problem
const answer = await applyEvolvedPrompt(callChat, result.best.systemPrompt,
  'Design a fair consensus protocol for 3 mutually distrustful parties with no trusted dealer.');

// or re-use a previous run
const best = loadBest('./data/evolved/2026-07-08-...');
const answer2 = await applyEvolvedPrompt(callChat, best.systemPrompt, '...');

CLI:

node scripts/evolve.js 10 6        # 10 candidates, 6 generations
node scripts/applyBest.js <runId> "your hard problem"

The seed population includes a fableMetaPrompt variant that forces a visible <thinking> block, a 4-stage classify → restate → attack → verify workflow, and explicit "actually…" / "wait…" self-correction markers — modeled on the thinking format used by the strongest public reasoning models. Scoring rewards candidates that actually produce visible reasoning, so the loop converges on prompts that elicit thinking, not just on prompts that produce lucky answers. Operators include fableThinkFormat, fableClassify, fableInternalCritic, fableCalibrate, and fableHighIntensity to push the population toward the Fable-style format.

All new modes respect the existing type, depth, checks, onChunk, and model options. They short-circuit before the main flow and never call the legacy paths unless you set the option to false.

OOD Probe (generalization check)

Once an evolution run finishes, run two probes to make sure the winning template actually generalizes instead of having overfit the in-distribution benchmark:

# 1. score the winner on a held-out OOD benchmark (5 fresh problems, never seen by the loop)
node scripts/probeOOD.js <runId>
# writes data/evolved/<runId>/ood-score.json with {idFitness, oodFitness, gap}
# gap > 0.20 means the winner overfit — re-evolve with a wider benchmark

# 2. apply the winner to 3 hand-picked "hard hard problems" (consensus protocol, dedupe, hypothesis)
node scripts/probeGeneralize.js <runId>
# prints the winner's full <thinking>...</thinking> + answer trace

The OOD probe uses 5 held-out items (ood-01-fair-share, ood-02-subset-sum, ood-03-monty-extended, ood-04-anagram-check, ood-05-orbit) that the evolution loop never sees. If the in-distribution score is high but the OOD score is much lower, the prompt is gaming the bench — discard it and re-run with a wider BENCH distribution or fewer generations.

Interpreting the gap: in practice on gemma4:31b-cloud, the in-distribution BENCH runs at ~0.7 while the OOD bench runs at ~0.3. That gap is mostly bench hardness (the OOD items include multi-number and algorithmic problems that even strong models get wrong) rather than prompt overfit. The real signal is probeGeneralize — if the winner still produces a coherent, structured answer on the 3 hand-picked hard problems, the prompt has generalized even if its numeric OOD score is low.


generateAndRunProject() (via codeGenerator)

Generates a complete, runnable multi-file project from a task description.

import Deepthink from 'deepthink-js';
import { generateAndRunProject } from 'deepthink-js/thinking/codeGenerator.js';

const dt = new Deepthink('cogito-2.1:671b-cloud');
const callChat = dt.callChat.bind(dt);

const result = await generateAndRunProject(callChat, 'Build a CLI tool that converts CSV to JSON', {
  thinkingDepth:   2,
  maxProjectLoops: 6,
  maxOracleLoops:  3,
});

if (result.success) {
  console.log(result.files);        // { 'index.js': '...', ... }
  console.log(result.buildCommands);
  console.log(result.runCommands);
}

Research Agent

The researchAgent implements a high-fidelity, 9-step verification pipeline that transforms a simple query into a peer-reviewed academic report.

import Deepthink from 'deepthink-js';
import runDeepResearch from 'deepthink-js/thinking/researchAgent.js';

const dt = new Deepthink('cogito-2.1:671b-cloud', []);
const callChat = dt.callChat.bind(dt);

const result = await runDeepResearch(
  callChat,
  'What are the causes of the 2008 financial crisis?',
  {
    maxQueries:           12,
    maxConcurrency:       10,
    credibilityThreshold: 45,
    maxSummaries:         20,
    useOllamaSearch:      true,
    academicFilter:       false,
    outputFormat:         'markdown', // markdown | plain | json | html
    humanize:             false,      // true = rewrite until the AI-detector says 0%
    mode:                 'general',  // 'stock' = real quant engine + quant-finance answer spec
    files:                [],         // local PDFs/docx/xlsx/pptx/csv/epub/rtf/odt/md → converted to markdown and injected as max-credibility evidence
  }
);

console.log(result.report);      // Full research report (formatted per outputFormat)
console.log(result.references);  // Array of APA-formatted citations
console.log(result.claimCount);  // Number of verified facts
console.log(result.success);     // boolean

Citation integrity is enforced structurally — after writing and after every critique repair, enforceCitations re-checks that every [Source N] tag in the body resolves, every source is cited, and the References section lists every source; missing tags are restored, orphan tags removed. Every source gets a full citation set in 9 styles (APA, MLA, Chicago, Harvard, Vancouver, IEEE, Bluebook, ACS, AMA, Turabian) via extractCitation. The humanize loop (humanize: true) runs humanize → integrity check → fix → detector until the detector scores 0%, with a local regex backstop that every number, name, date, and [Source N] tag survives each rewrite.

Stock mode computes real math. When mode: 'stock', a pure-code quant engine (quantEngine) harvests inputs from the verified claims — price, EPS, beta, volatility, risk-free rate, equity risk premium — and derives growth the way an analyst would (forward P/E ÷ PEG when no explicit growth % is cited). It then computes, with zero LLM involvement:

  • CAPM cost of equity: Re = Rf + β × ERP
  • A genuine 10-year DCF with Gordon terminal value → intrinsic value per share
  • GBM expected return with Ito's lemma: expected log-return (μ − σ²/2), the volatility drag σ²/2, and E[S_T] = S₀e^{μT}
  • Sharpe ratio and 1-day 95%/99% + 1-year 95% VaR (z·σ·P·√T)

The report writer is told to use these exact numbers, and the full derivations are appended as a ## Quantitative Model (computed by pipeline) section after the critique loop — so no critic or repair pass can rewrite code-computed math. The quant finance verifier cross-checks every number the writer states against the formulas (VaR = 1.645·σ/√252, Sharpe = (μ − Rf)/σ, etc.).

Pipeline steps:

| Step | Name | Description | |------|------|-------------| | 0 | Answer Format Detection | Classifies what a correct answer looks like | | 1 | Query Planning | Generates layered search queries at up to 3 recursion depths | | 2 | Parallel Web Crawling | Fetches all URLs concurrently via extractArticleText | | 3 | Credibility Scoring | Scores each source (0–100) | | 4 | MMR Diversity Filter | Maximal Marginal Relevance selects a diverse, high-credibility subset | | 5 | Fact Verification Loop | Each extracted claim is verified against its source | | 6 | Report Writing | Synthesises verified claims into a structured markdown report | | 7–9 | Critique & Repair Loop | Domain expert, adversarial, source fidelity, and math/logic critic agents (+ quant finance verifier in stock mode) | | — | Quant Engine | mode: 'stock' — pure-code CAPM, 10-year DCF, GBM/Ito, Sharpe, VaR computed from verified claims; injected after critique | | — | Citation Integrity | enforceCitations restores dropped [Source N] tags after every repair pass | | — | Humanize Loop | humanize: true — rewrite → integrity check → fix → detect, until 0% AI-ness | | — | Format Conversion | outputFormat — mechanical markdown → plain/json/html (never touches citations) | | — | Local Files | files: [...] — PDFs and other document types converted to markdown and injected as max-credibility evidence sources |


Internet Utilities

Universal Content Extractor

import { extractArticleText } from 'deepthink-js/internet/extractFromUrl.js';

const html = await extractArticleText('https://example.com/paper.pdf');

Supports HTML, PDF, DOCX, XLSX, PPTX, EPUB, CSV, TSV, JSON, XML, Markdown, plain text, RTF, ODT, SVG, and images.


Chrome-Fingerprinted Axios Adapter

import axios from 'deepthink-js/internet/axios.js';

const response = await axios.get('https://example.com', {
  responseType: 'arraybuffer',
  timeout: 15000,
});

Uses impit to mimic Chrome's TLS fingerprint, bypassing most bot-detection middleware.


Ollama Web Search

import { getOllamaSearchResults } from 'deepthink-js/internet/ollamaSearch.js';

const results = await getOllamaSearchResults('Riemann hypothesis latest research', 5);
// results: [{ title, link, snippet, cite }, ...]

Electron Free Explorer

An autonomous AI browsing agent that explores the web with human-like behaviour.

npm install electron pdf-parse && npx electron examples/electron_explorer.js

Press Ctrl+C to stop — a reflective journal-style session summary is generated and saved to disk.

Features:

  • Up to 3 concurrent browser tabs; least-productive tabs pruned automatically
  • Human-like mouse movement, clicking, triple-click-and-type, scroll, and key press simulation
  • PDF detection — automatically fetches and injects text as readable HTML
  • Goal compression every 20 loops — the AI builds and evolves a first-person "current focus" narrative
  • Topic drift detection — nudges the AI toward new territory after 8+ loops on the same hostname
  • Full action log written to log.txt; session summaries saved as summary_<timestamp>.txt

Testing

npm test           # full suite (pure + integration against your configured model)
npm run test:fast  # pure tests only (no LLM)

Tests default to gemma4:31b-cloud. Override with DEEPTHINK_TEST_MODEL=... npm test. Each test file exits 0 on pass, 1 on fail. The runner prints a summary at the end.

| Test file | Coverage | LLM? | |---|---|---| | test_dataTypes.js | stripThinkBlocks, stripCodeFences, parseDataType, messages, normalization | no | | test_memory.js | persistent + ephemeral memory stores | no | | test_compression.js | token counting, middle-truncation, compress passthrough | no | | test_consistency.js | vote, keyFor, findRelevant, makeCalibrator | no | | test_toolUse.js | parseToolCall, describeTools | no | | test_providers.js | client construction across all 8 providers | no | | test_sandbox.js | JS sandbox, Python sandbox, compareResults | no (Python needs python3 in PATH) | | test_integration.js | every new public option against the configured model | yes |


Benchmarks

Head-to-head against gemma4:31b-cloud on Ollama: a single direct chat call ("plain") vs the same model wrapped in Deepthink.generate(prompt, { depth: 2, checks: 2 }). Problems come from official public sources (AIME 2024/2023, USAMO 2024, IMO 2024, MIT Integration Bee, MBPP) — never given to the model with answers. Answers are verified exactly (sympy-backed, prose-number fallback) or by running hidden tests in the sandbox (MBPP). The verifier model is deepseek-v4-flash:0731-cloud, used only for critique/checks — it never sees the gold answer.

node scripts/benchmarks/run.js --bench aime2024   # official AIME 2024 (30 problems, plain vs dt)
node scripts/benchmarks/freshRun.js --set freshMulti  # untrained multi-step set (choice format)
node scripts/benchmarks/verifyMulti.js           # independent gold verification for freshMulti
node scripts/iqTrain.js --pop 8 --gens 6         # IQ training loop (80% train / 20% OOD holdout)

Raw per-row output (CSV, resume-safe) is in benchmarks/results/.

Fresh untrained sets (benchmarks/data/): freshSet (35 IQ-style), freshHard / freshHard2 (novel computation), freshMulti (20 novel multi-step problems with compounding-error traps — the set that separates single-shot from pipeline reasoning). Every gold in freshMulti is verified by verifyMulti.js from first principles — no gold is taken on the author's word. iqTrain.jsonl (25 items) is the 80% training bank; freshSet is the 20% held-out OOD probe for the evolution loop.

| Benchmark | n | Plain | Deepthink (d=2, c=2) | Δ | self-corrected | |---|---:|---:|---:|---:|---:| | AIME 2024 I | 5 | 4/5 | 5/5 | +1 | 2 | | AIME 2024 II | 5 | 5/5 | 5/5 | 0 | 1 | | AIME 2023 I | 5 | 4/5 | 4/5 | 0 | 0 | | USAMO 2024 | 6 | 3/6 | 3/6 | 0 | 3 | | IMO 2024 | 6 | 6/6 | 6/6 | 0 | 6 | | Integration Bee | 2 | 1/2 | 1/2 | 0 | 0 | | MBPP (code-gen) | 5 | 4/5 | 4/5 | 0 | 0 | | Coding (HTML critique) | 1 | 37/50 | 41/50 | +4 | — | | Total (math) | 29 | 23/29 (79%) | 24/29 (83%) | +1 | 12 |

Deepthink's win condition is the revert rule: any pipeline change must improve ≥2 of the 4 measured dimensions (correctness, reasoning-trace quality, self-correction, token efficiency) and worsen none. The current pipeline lands +1 on AIME 2024-I (5/5 vs 4/5), matches everywhere else, and self-corrects 11 problems — while the check-loop escapes cut IMO token burn from 173–253k/problem (v1.4, escape bug) to ~22k with ≤2 revisions. Full per-run logs land in benchmarks/results/.


Advanced Options Reference

generate() Options

See the full options table in the generate() section above.


researchAgent Options

| Option | Type | Default | Description | |--------------------------|------------|---------|-------------| | maxQueries | number | 12 | Total search queries to plan | | maxConcurrency | number | 10 | Parallel URL fetch workers | | credibilityThreshold | number | 45 | Minimum score (0–100) to include a source | | maxSummaries | number | 20 | Max sources after MMR diversity filter | | diversityLambda | number | 0.6 | MMR trade-off: 1.0 = pure relevance, 0.0 = pure diversity | | chunkSize | number | 20 | Claims per report-writing chunk | | useOllamaSearch | boolean | false | Use Ollama web search. Falls back to SearXNG when false | | academicFilter | boolean | false | Restrict sources to trusted academic/news domains | | academicWhitelist | string[] | built-in| Additional trusted domains | | academicBlacklist | string[] | built-in| Additional domains to block | | academicWhitelistMode | 'extend' \| 'replace' | 'extend' | Whitelist merge mode | | academicBlacklistMode | 'extend' \| 'replace' | 'extend' | Blacklist merge mode | | credNegativePatterns | RegExp[] | built-in| URL patterns that reduce credibility | | enableCritique | boolean | true | Run critique-and-repair loop (steps 7–9) | | recursionDepth | number | 2 | Query tree depth |


Internal Architecture

Deepthink.generate()
│
├── runThink()                    ← Multi-stage pre-thinking (think.js)
│   ├── depth ≥ 1 → Analysis pass
│   ├── depth ≥ 2 → Planning pass
│   └── depth ≥ 3 → Sanity-check pass
│
├── detectComputeNeeds()          ← Decide: none / single / parallel
│
├── generateAndRunCode()          ← codeGenerator.js
│   ├── runMCTSApproaches()       ← 4 parallel Python sandboxes, consensus vote
│   ├── mathematicianAgent()      ← Formal spec (no code)
│   ├── engineerAgent() × 2      ← JS + Python implementations
│   ├── runJSSandbox()
│   ├── runPythonSandbox()
│   └── reconcileResults()
│
├── callChat()                    ← Final answer with ground truth injected
│   └── buildProviderClient()     ← Routes to correct provider adapter
│
└── runChecks() × N              ← Self-verification loop
    ├── Standard checker
    ├── Adversarial checker
    └── Numerical checker
        └── MetacognitiveMonitor
runDeepResearch()
│
├── Step 0  detectAnswerFormat()
├── Step 1  plannerAgent()
├── Step 2  crawlerAgent()
├── Step 3  verificationAgent()
├── Step 4  extractWithFallback() + applyMMR()
├── Step 5  factVerificationLoop()
├── Step 6  reportWriterAgent()
└── Steps 7–9  critiqueAndRepairLoop()

Proxy & MCP Integration

Deepthink ships as a local server too: an OpenAI/Anthropic-compatible HTTP proxy and a Model Context Protocol (MCP) server. Any tool that speaks OpenAI or Anthropic wire formats — Cursor, Aider, Claude Code, ChatGPT UI, custom scripts — can use deepthink-js as a drop-in backend, and any MCP client (Claude Desktop, Cursor, Claude Code) can call deepthink_reason as a tool.

HTTP proxy

npm run proxy          # or: node src/proxy.js

Listens on http://127.0.0.1:8000 (override with PORT / HOST env vars) and serves:

| Endpoint | Format | Purpose | |---|---|---| | POST /v1/chat/completions | OpenAI | chat completions, streaming + non-streaming | | GET /v1/models | OpenAI | model list | | POST /v1/messages | Anthropic | messages API, streaming + non-streaming | | GET/POST/DELETE /mcp | MCP streamable HTTP | MCP server over HTTP | | GET /health | — | liveness + in-flight count |

Requests are routed through the full deepthink pipeline: parallel probes, MCTS-style search, sandboxed code verification, and the self-correction check loop. The model field in the request body is ignored — the engine model comes from DEEPTHINK_MODEL (or OLLAMA_MODEL), overridable per request via the x-deepthink-model header.

Pointing tools at it:

  • Cursor — Settings → Models → OpenAI API Key: any value, Base URL: http://localhost:8000/v1
  • Aideraider --openai-api-base http://localhost:8000/v1 --openai-api-key dummy
  • Claude CodeANTHROPIC_BASE_URL=http://localhost:8000 ANTHROPIC_API_KEY=dummy claude
  • Any OpenAI SDK — set baseURL to http://localhost:8000/v1

Streaming"stream": true returns real SSE: the final synthesis call streams token-by-token through the pipeline's onChunk hook, framed as standard OpenAI chunks (data: {...} + data: [DONE]) or Anthropic events (message_startcontent_block_deltamessage_stop). A keep-alive comment is written every 15s while the engine thinks, so long MCTS searches survive proxy idle timeouts.

Thinking traces — send x-deepthink-trace: true to get the internal reasoning back:

  • OpenAI: message.reasoning_content (non-streaming) or a reasoning_content delta chunk (streaming), plus the full call trace under _deepthink.trace
  • Anthropic: a thinking content block
  • Every response carries x-deepthink-trace-id, x-deepthink-calls, and x-deepthink-ms headers

Deepthink knobs — per-request via a deepthink object in the body or x-deepthink-* headers:

{
  "model": "gpt-4o",
  "messages": [{ "role": "user", "content": "Solve this IMO problem..." }],
  "deepthink": { "depth": 2, "checks": 2, "type": "string", "enableCode": true }
}

| Knob | Body field | Header | Default | |---|---|---|---| | reasoning depth (0–3) | deepthink.depth | x-deepthink-depth | 1 | | check-loop passes (0–5) | deepthink.checks | x-deepthink-checks | 1 | | output type | deepthink.type | — | string | | sandboxed code execution | deepthink.enableCode | — | true | | engine model | deepthink.model | x-deepthink-model | DEEPTHINK_MODEL |

Env vars: PORT (8000), HOST (127.0.0.1), DEEPTHINK_MODEL, DEEPTHINK_MAX_INFLIGHT (8 — beyond this, requests get 429), DEEPTHINK_API_KEY (optional bearer auth; when set, every request needs Authorization: Bearer <key>).

MCP server

Two transports, 69 tools. The MCP surface is a full agent toolkit, all wired onto deepthink's own engine through one shared context — so every tool reuses the same pooled model instances, memory store, worker pool, event log, and rollback log.

The tool families:

| Family | Tools | |---|---| | LLM + research | deepthink_reason, deepthink_generate, deepthink_json, deep_research, deepthink_humanize_text, deepthink_check_score, deepthink_ai_analyze, deepthink_analyze_image, ollama_chat, list_models, ollama_health | | Auto-agents | deepthink_process, deepthink_plan, deepthink_agent, deepthink_mcts_search, deepthink_beam_search | | Skills | deepthink_list_skills, deepthink_run_skill (csv, markdown, json-spec, html-report, excel) | | Vision | deepthink_design_svg | | Documents | deepthink_parse_document (pdf/docx/xlsx/csv/html/md/json) | | Code intelligence | deepthink_search_code, deepthink_find_files, deepthink_project_overview, deepthink_import_map, deepthink_list_functions, deepthink_audit_deps | | Memory | deepthink_memory_set/get/search/list/delete/gc | | Sandbox | deepthink_js_execute (fresh Node subprocess, state in scope) | | Runner | fs (read/write/list/mkdir/delete/copy/rollback), shell/powershell, web search/fetch/http, desktop (screenshot/mouse/keyboard/clipboard), git, node/python run, process/env control | | Utilities | get_current_time, roll_dice, coin_flip, echo_message, random_number, get_event_log |

The flagship reasoning tool, deepthink_reason"Executes deep test-time compute reasoning, sandboxed code verification, MCTS tree search, and adversarial critique to solve hard mathematical, algorithmic, or multi-file coding problems."

| Input | Type | Default | Meaning | |---|---|---|---| | prompt | string | — | the problem or question (required) | | type | string | string | string | integer | double | boolean | json | | depth | number | 1 | reasoning depth 0–3 | | enableCode | boolean | true | allow sandboxed code execution |

Stdio (Claude Desktop, Cursor CLI, Claude Code):

npm run mcp          # or: node src/mcp.js

Claude Desktop — Settings → Developer → Edit Config, add to claude_desktop_config.json (Windows: %APPDATA%\Claude\claude_desktop_config.json; use absolute paths — Claude Desktop doesn't inherit your shell PATH):

{
  "mcpServers": {
    "deepthink": {
      "command": "C:\\Program Files\\nodejs\\node.exe",
      "args": ["C:\\path\\to\\deepthink-js\\src\\mcp.js"]
    }
  }
}

Fully restart Claude Desktop after editing. Logs land in %APPDATA%\Claude\logs\.

Cursor.cursor/mcp.json (project) or ~/.cursor/mcp.json (global):

{
  "mcpServers": {
    "deepthink": {
      "command": "node",
      "args": ["C:\\path\\to\\deepthink-js\\src\\mcp.js"]
    }
  }
}

Over HTTP — the proxy exposes the same server at http://localhost:8000/mcp (MCP streamable HTTP transport, session-based). Point any MCP client that supports remote servers at that URL. The stdio server exits cleanly when stdin closes; stdout carries only MCP frames, so logs go to stderr.


Project Structure

thinking/
├── deepthink.ts          Deepthink class (EventEmitter, generate, callChat, verification)
├── researchAgent.ts      9-step deep research pipeline (Zod-validated JSON)
├── analytical.ts         Multi-agent analytical decomposition mode
├── think.ts              Multi-stage pre-thinking passes
├── dataTypes.ts          Type parsing, message normalisation
├── cognitive.ts          7-phase cognitive flow
├── consistency.ts        Self-consistency: sample N, vote
├── personaDebate.ts      Two-agent debate + judge
├── planAndExecute.ts     Explicit plan, run steps, reflect, synthesize
├── reflexion.ts          Lesson store + writeLesson + recall
├── smartCompression.ts   Compress when token budget overflows
├── toolUse.ts            Tool-call loop (js_eval, py_eval, finish, custom)
├── mixtureOfAgents.ts    Fan out to N providers, judge merges
├── confidence.ts         Per-type win/loss calibration
├── memory.ts             JSON-file-backed persistent store
├── thinkingPatterns.ts   33 cognitive patterns + fable profiles
├── benchmarkSet.ts       BENCH (10) + OOD_BENCH (5) for prompt scoring
├── evolvedThinking.ts    Prompt-evolution loop
├── evolvedMutate.ts      17 mutation operators
├── evolvedScoring.ts     Multi-number scoring
├── events.ts             module-level emitter, makeConsoleLogger
└── types.ts              shared TS types (LogEvent, StepEvent)

codeGenerator/
├── index.ts              public surface
├── sandbox.ts            isolated-vm JS sandbox + python subprocess fallback
├── fileBlocks.ts         ### FILE: and ### PATCH: parse/apply + automation script gen
├── python.ts             MCTS-of-approaches + JS+Python double-check
├── run.ts                12-step project pipeline
└── project.ts            re-exports for direct consumers

parse/
├── json.ts               parseJsonSafe + tryParseJsonSafe
└── llmSchemas.ts         Zod schemas for every LLM-emitted shape

providers/
├── index.ts              Multi-provider adapter
└── gemini.ts             Direct Gemini Web API via cookies

internet/
├── extractFromUrl.ts     Universal URL → HTML extractor (13 formats)
├── axios.ts              Chrome TLS-spoofing axios adapter (impit)
├── ollamaSearch.ts       Ollama web search
├── interactWithInternet.ts Search + fetch orchestration
├── mullvadLetaClient.ts   SearXNG meta-search
└── extractCitation.ts    9 citation styles

examples/
├── electron_explorer.js  Autonomous AI browser agent (Electron)
└── research.js           Standalone deep research usage

All .ts files emit to dist/ at build time. dist/ is what gets published to npm.


Requirements & Dependencies

Install via npm install deepthink-js — everything below is included automatically.

| Dependency | Purpose | |---|---| | ollama | Ollama JS client | | axios | HTTP client (wrapped by the impit adapter) | | impit | Chrome TLS fingerprint for bot bypass | | cheerio | HTML parsing and cleaning | | jsdom | DOM for Readability | | @mozilla/readability | Article extraction from HTML | | mammoth | DOCX → HTML conversion | | xlsx | Spreadsheet (XLSX/XLS/ODS) parsing | | jszip | PPTX, ODT, EPUB unpacking | | fast-xml-parser | XML/PPTX slide text extraction | | @iarna/rtf-to-html | RTF → HTML | | papaparse | CSV/TSV parsing | | marked | Markdown → HTML | | pdf-parse | PDF text extraction | | electron | (examples/electron_explorer.js only — install separately) | | python3 + sympy | Python sandbox and symbolic math (optional — install separately) |

Node.js ≥ 18 is required for native fetch, ReadableStream, and top-level await.


Troubleshooting

❌ Python Sandbox Errors

If you see "Python not installed", ensure python3 is in your system PATH. For complex math, pip install sympy is highly recommended.

❌ API Key Rotation Failures

Deepthink rotates keys automatically. If all keys in an array fail, the engine will throw a terminal error. Check your .env or constructor apiKeys array.

❌ Gemini Cookie Authentication

Gemini Web requires specific cookies (__Secure-1PSID, __Secure-1PSIDTS). If authentication fails, ensure you are logged in via a Chromium-based browser and that your cookies haven't expired.

❌ Memory/OOM in Code Generation

For extremely large projects, the LLM may time out or hit context limits. Try breaking the task into smaller, more specific requests or increasing the thinkingDepth.


Contributing

We welcome contributions to make Deepthink more powerful.

Adding a New Provider

  1. Create a new file in providers/ (e.g., providers/mistral.js).
  2. Implement the callChat adapter to map Deepthink's message format to the provider's API.
  3. Register the provider in providers/index.js.

Improving Agents

Modify files in the thinking/ directory. Most agents follow a pattern of Analysis → Execution → Verification. When updating prompts, always test with both a "small" (Flash) and "large" (Opus/Pro) model to ensure robust parsing.


Roadmap

  • [x] Multi-Agent Swarms: Multiple agents per call (mixture-of-agents, persona debate)
  • [x] Long-term Memory: Persistent JSON store at ~/.deepthink-js/memory.json
  • [x] Tool Use: Model emits JSON tool calls, engine runs them in a sandbox
  • [x] Self-Consistency / Plan-and-Execute / Reflexion / Calibration: New reasoning modes
  • [ ] Visual Verification: Ability for agents to "see" the generated UI via screenshots and fix layout bugs
  • [ ] Dynamic Tool Synthesis: Ability for the agent to write and install its own npm packages to solve a specific task
  • [ ] Cross-Session Replay: Replay an entire reasoning session from a saved log

License

MIT