This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated. ⚠️⚠️⚠️⚠️⚠️⚠️ `main` is currently in **pre mode** so this branch has prereleases rather than normal releases. If you want to exit prereleases, run `changeset pre exit` on `main`. ⚠️⚠️⚠️⚠️⚠️⚠️ # Releases ## deepagents@1.12.0-rc.0 ### Minor Changes - [#703](https://github.com/langchain-ai/deepagentsjs/pull/703) [`d25097f`](https://github.com/langchain-ai/deepagentsjs/commit/d25097f78d0e66741da34e1d74551f3c19991126) Thanks [@hntrl](https://github.com/hntrl)! - feat(deepagents): adopt more minimal prompting We've observed that current models don't need as verbose of prompting guidance, so we're reducing the amount of perscriptive guidance that deepagents has. This is reflected in the generic system prompt (which is now blank), and in the tool descriptions (which have been simplified). - [#674](https://github.com/langchain-ai/deepagentsjs/pull/674) [`dd142fe`](https://github.com/langchain-ai/deepagentsjs/commit/dd142fe4fc54c986d5bcf51211d9a839a427e931) Thanks [@hntrl](https://github.com/hntrl)! - feat(filesystem): allow `write_file` to create missing files or completely replace existing files ## deepagents-acp@0.1.21-rc.0 ### Patch Changes - Updated dependencies [[`d25097f`](https://github.com/langchain-ai/deepagentsjs/commit/d25097f78d0e66741da34e1d74551f3c19991126), [`dd142fe`](https://github.com/langchain-ai/deepagentsjs/commit/dd142fe4fc54c986d5bcf51211d9a839a427e931)]: - deepagents@1.12.0-rc.0 ## @langchain/daytona@1.0.0-rc.0 ### Patch Changes - Updated dependencies [[`d25097f`](https://github.com/langchain-ai/deepagentsjs/commit/d25097f78d0e66741da34e1d74551f3c19991126), [`dd142fe`](https://github.com/langchain-ai/deepagentsjs/commit/dd142fe4fc54c986d5bcf51211d9a839a427e931)]: - deepagents@1.12.0-rc.0 ## @langchain/deno@1.0.0-rc.0 ### Patch Changes - Updated dependencies [[`d25097f`](https://github.com/langchain-ai/deepagentsjs/commit/d25097f78d0e66741da34e1d74551f3c19991126), [`dd142fe`](https://github.com/langchain-ai/deepagentsjs/commit/dd142fe4fc54c986d5bcf51211d9a839a427e931)]: - deepagents@1.12.0-rc.0 ## @langchain/modal@1.0.0-rc.0 ### Patch Changes - Updated dependencies [[`d25097f`](https://github.com/langchain-ai/deepagentsjs/commit/d25097f78d0e66741da34e1d74551f3c19991126), [`dd142fe`](https://github.com/langchain-ai/deepagentsjs/commit/dd142fe4fc54c986d5bcf51211d9a839a427e931)]: - deepagents@1.12.0-rc.0 ## @langchain/node-vfs@1.0.0-rc.0 ### Patch Changes - [#674](https://github.com/langchain-ai/deepagentsjs/pull/674) [`dd142fe`](https://github.com/langchain-ai/deepagentsjs/commit/dd142fe4fc54c986d5bcf51211d9a839a427e931) Thanks [@hntrl](https://github.com/hntrl)! - fix: allow `VfsBackend.write` to overwrite existing files while continuing to reject symlinks - Updated dependencies [[`d25097f`](https://github.com/langchain-ai/deepagentsjs/commit/d25097f78d0e66741da34e1d74551f3c19991126), [`dd142fe`](https://github.com/langchain-ai/deepagentsjs/commit/dd142fe4fc54c986d5bcf51211d9a839a427e931)]: - deepagents@1.12.0-rc.0 ## @langchain/quickjs@1.0.0-rc.0 ### Patch Changes - Updated dependencies [[`d25097f`](https://github.com/langchain-ai/deepagentsjs/commit/d25097f78d0e66741da34e1d74551f3c19991126), [`dd142fe`](https://github.com/langchain-ai/deepagentsjs/commit/dd142fe4fc54c986d5bcf51211d9a839a427e931)]: - deepagents@1.12.0-rc.0 ## @langchain/sandbox-standard-tests@2.0.0-rc.0 ### Patch Changes - Updated dependencies [[`d25097f`](https://github.com/langchain-ai/deepagentsjs/commit/d25097f78d0e66741da34e1d74551f3c19991126), [`dd142fe`](https://github.com/langchain-ai/deepagentsjs/commit/dd142fe4fc54c986d5bcf51211d9a839a427e931)]: - deepagents@1.12.0-rc.0 ## @deepagents/evals@0.0.20-rc.0 ### Patch Changes - Updated dependencies [[`d25097f`](https://github.com/langchain-ai/deepagentsjs/commit/d25097f78d0e66741da34e1d74551f3c19991126), [`dd142fe`](https://github.com/langchain-ai/deepagentsjs/commit/dd142fe4fc54c986d5bcf51211d9a839a427e931)]: - deepagents@1.12.0-rc.0 Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@deepagents/evals
Generic eval harness for deepagents. Provides the runner interface,
runner registry, trajectory parsing, and custom vitest matchers with
LangSmith feedback integration.
Package exports
| Export | Description |
|---|---|
@deepagents/evals |
Core harness — EvalRunner, registry functions, parseTrajectory, getFinalText, custom matchers |
@deepagents/evals/deepagent |
registerDeepAgentRunner() — wires createDeepAgent into the generic runner interface |
@deepagents/evals/setup |
Side-effect import that registers all concrete runners (sonnet-4-5, gpt-4.1, etc.) |
Core concepts
EvalRunner
The central interface. A runner has a name, a run() method, and an
extend() method:
interface EvalRunner {
name: string;
run(params: RunAgentParams): Promise<AgentTrajectory>;
extend(overrides: Record<string, unknown>): EvalRunner;
}
run()takes invocation params only —{ query, initialFiles? }.extend()returns a new runner with agent configuration overrides (e.g.systemPrompt,tools,subagents) baked in. This keeps "what the agent is" separate from "what to ask it".
RunAgentParams
interface RunAgentParams {
query: string;
initialFiles?: Record<string, string>;
}
Pure invocation inputs. query is the user message; initialFiles seeds the
agent's virtual file system.
AgentTrajectory
interface AgentTrajectory {
steps: AgentStep[];
files: Record<string, string>;
}
The output of every run() call. steps is an ordered list of agent
turns (each containing an AIMessage action and any ToolMessage
observations). files is the final file-system snapshot.
Runner registry
flowchart LR
setup["setup.ts<br/><i>vitest setupFile</i>"]
deepagent["deepagent.ts<br/>registerDeepAgentRunner()"]
registry["index.ts<br/>registerRunner()"]
resolve["resolveRunner(name)"]
default["getDefaultRunner()<br/>reads EVAL_RUNNER env"]
test["test file<br/>runner.run() / runner.extend()"]
setup -- "calls for each model" --> deepagent
deepagent -- "wraps in DeepAgentEvalRunner" --> registry
default -- "looks up by name" --> registry
resolve -- "looks up by name" --> registry
test --> default
test --> resolve
setup.tsis loaded as a vitestsetupFile. It callsregisterDeepAgentRunner()for each model, which internally callsregisterRunner().getDefaultRunner()reads theEVAL_RUNNERenv var, looks up the runner by name, and returns it (cached).resolveRunner(name)is the lower-level lookup if you need a specific runner by name.
registerDeepAgentRunner
Bridges createDeepAgent to the generic EvalRunner interface:
registerDeepAgentRunner("sonnet-4-5", (config) =>
createDeepAgent({
...config,
model: new ChatAnthropic({ model: "claude-sonnet-4-5-20250929" }),
}),
);
The factory receives optional overrides (from extend()) and must return
an invokable agent. A default agent (no overrides) is built eagerly at
registration time and reused across run() calls for performance.
When extend() is called, a fresh agent is constructed with the overrides.
The DeepAgentEvalRunner handles:
- Converting
initialFilesstrings into theFileDataformat expected by the agent's state backend - Generating a unique
thread_idper invocation - Calling
ls.logOutputs()for LangSmith experiment tracking - Parsing the raw LangGraph result into an
AgentTrajectory
Custom vitest matchers
Imported automatically when you import from @deepagents/evals.
Each matcher also logs LangSmith feedback (scores) so results appear in
the experiment dashboard.
| Matcher | Description |
|---|---|
toHaveAgentSteps(n) |
Trajectory has exactly n steps |
toHaveToolCallRequests(n) |
Total tool-call count equals n |
toHaveToolCallInStep(step, match) |
Step (1-indexed) contains a tool call matching { name, argsContains?, argsEquals? } |
toHaveFinalTextContaining(text, caseInsensitive?) |
Last step's text content includes text |
Adding a new runner
To add support for a new model, add a registerDeepAgentRunner call in
src/setup.ts:
registerDeepAgentRunner("my-model", (config) =>
createDeepAgent({ ...config, model: new ChatMyProvider({ model: "my-model" }) }),
);
Then run evals with EVAL_RUNNER=my-model.
To add a completely different runner backend (not deepagents), implement
the EvalRunner interface directly and call registerRunner(), or use
the runner directly inside of the eval suite.
Development
pnpm build # Build with tsdown
pnpm typecheck # Type-check without emitting