Files
deepagentsjs/examples/repl/data-analysis-agent.ts
T
Hunter Lovell 454fa26804 feat: add quickjs middleware (#261)
* feat(quickjs): add @langchain/quickjs — sandboxed JS/TS REPL with PTC, env isolation, and RLM support

* chore: split changesets into quickjs minor + deepagents patch

* refactor(quickjs): remove env/secrets, lazy runtime, buffered writes, fix thread_id propagation

- Remove entire env/secrets system (EnvVarConfig, EnvConfig, secretRef, injectEnv, blockEnvLeaks, checkEnvAccess, generateEnvPrompt)
- Lazy-load QuickJS WASM runtime on first eval via ensureStarted()
- Buffer file writes in pendingWrites[], flush after eval via flushWrites(backend)
- Make ReplSession.getOrCreate() synchronous (runtime init deferred)
- Add toJSON()/fromJSON() for session serialization
- Fix thread_id propagation: move session creation from wrapModelCall (which lacks configurable) to tool handler (which has config.configurable.thread_id)
- Remove dead starting map from ReplSession
- Add integration test verifying REPL state persists across js_eval calls
- Add thread_id propagation unit tests
- Remove secret-env-agent example
- 68 unit tests + 1 integration test passing, types clean

* cr

* cr

* docs(quickjs): add README and LICENSE, fix lint errors

* cr

* cr
2026-03-06 08:49:17 +00:00

51 lines
1.6 KiB
TypeScript

/**
* Data Analysis Agent Example
*
* Demonstrates the QuickJS REPL as a computational scratch pad.
* The agent reads data from the VFS, processes it in sandboxed JavaScript,
* and writes results back — all without network access or Node.js APIs.
*
* This is useful for tasks where LLMs typically hallucinate:
* - Arithmetic and statistical calculations
* - Sorting, filtering, grouping data
* - JSON transformation and restructuring
* - Multi-step logic with intermediate state
*/
import "dotenv/config";
import dedent from "dedent";
import { HumanMessage } from "@langchain/core/messages";
import { ChatAnthropic } from "@langchain/anthropic";
import { createDeepAgent } from "deepagents";
import { createQuickJSMiddleware } from "@langchain/quickjs";
const model = new ChatAnthropic({
model: "claude-sonnet-4-5",
temperature: 0,
});
const agent = createDeepAgent({
model,
systemPrompt: dedent`
You are a data analyst. Use the js_eval REPL to perform calculations
and data transformations. Always show your work in code — never guess
at arithmetic or statistics.
`,
middleware: [createQuickJSMiddleware()],
});
const result = await agent.invoke({
messages: [
new HumanMessage(dedent`
I have sales data in /data/sales.json. Parse it, calculate the total
revenue per region, find the top-performing region, and write a
summary report to /reports/sales-summary.md.
`),
],
});
const last = result.messages[result.messages.length - 1];
// eslint-disable-next-line no-console
console.log(
typeof last.content === "string" ? last.content.slice(0, 500) : last.content,
);