[PR #526] [MERGED] feat(deepagents): implement harness profiles #538

Closed
opened 2026-06-05 17:23:36 -04:00 by yindo · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/langchain-ai/deepagentsjs/pull/526
Author: @colifran
Created: 5/7/2026
Status: Merged
Merged: 5/11/2026
Merged by: @colifran

Base: mainHead: colifran/harness-profiles


📝 Commits (10+)

📊 Changes

25 files changed (+2491 additions, -24 deletions)

View changed files

.changeset/wild-kings-scream.md (+5 -0)
📝 libs/deepagents/src/agent.test.ts (+2 -1)
📝 libs/deepagents/src/agent.ts (+95 -23)
📝 libs/deepagents/src/index.ts (+17 -0)
libs/deepagents/src/profiles/harness/builtins.test.ts (+174 -0)
libs/deepagents/src/profiles/harness/builtins/anthropic-haiku-4-5.ts (+30 -0)
libs/deepagents/src/profiles/harness/builtins/anthropic-opus-4-7.ts (+42 -0)
libs/deepagents/src/profiles/harness/builtins/anthropic-sonnet-4-6.ts (+36 -0)
libs/deepagents/src/profiles/harness/builtins/index.ts (+25 -0)
libs/deepagents/src/profiles/harness/builtins/openai-codex.ts (+59 -0)
libs/deepagents/src/profiles/harness/create.test.ts (+129 -0)
libs/deepagents/src/profiles/harness/create.ts (+104 -0)
libs/deepagents/src/profiles/harness/index.ts (+33 -0)
libs/deepagents/src/profiles/harness/merge.test.ts (+215 -0)
libs/deepagents/src/profiles/harness/merge.ts (+131 -0)
libs/deepagents/src/profiles/harness/registry.test.ts (+246 -0)
libs/deepagents/src/profiles/harness/registry.ts (+319 -0)
libs/deepagents/src/profiles/harness/serialization.test.ts (+205 -0)
libs/deepagents/src/profiles/harness/serialization.ts (+173 -0)
libs/deepagents/src/profiles/harness/types.test.ts (+31 -0)

...and 5 more files

📄 Description

Summary

Introduces harness profiles which is a way to declaratively control how agents behave at runtime without changing which model is used. A profile can override the system prompt, hide tools, add or remove middleware, and configure the general-purpose subagent. Profiles are registered by provider or model key ("anthropic", "openai:gpt-5.4") and looked up automatically when createDeepAgent is called.

The system ships with built-in profiles for Anthropic Opus 4.7, Sonnet 4.6, Haiku 4.5, and OpenAI Codex that include vendor-recommended prompting guidance. Users can register their own profiles on top and registrations merge additively so provider-wide defaults compose with model-specific overrides.

Profiles are plain frozen objects with Zod schemas for parsing from JSON/YAML config files, including prototype-pollution protection for untrusted input.

Tests

Unit tests cover key validation, profile construction and freezing, serialization round-trips, poison-key rejection, merge semantics across all field types, registry lookup with provider fallback, and prompt overlay behavior. Built-in profiles are tested for correct registration and expected content.

Also verified end-to-end via a standalone script against LangSmith and confirmed the custom suffix appears in the system prompt and excluded tools are absent from the model call.

Usage Example

import { HumanMessage } from "@langchain/core/messages";
import { createDeepAgent, registerHarnessProfile } from "deepagents";

registerHarnessProfile("anthropic:claude-sonnet-4-6", {
  systemPromptSuffix: "Always respond in exactly one sentence.",
  excludedTools: ["grep"],
  generalPurposeSubagent: {
    description: "A customized GP subagent via harness profile.",
  },
});

const agent = createDeepAgent({
  model: "anthropic:claude-sonnet-4-6",
});

const result = await agent.invoke({
  messages: [new HumanMessage("What is the capital of France?")],
});

const lastMessage = result.messages[result.messages.length - 1];
console.log("Response:", lastMessage.content);

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/langchain-ai/deepagentsjs/pull/526 **Author:** [@colifran](https://github.com/colifran) **Created:** 5/7/2026 **Status:** ✅ Merged **Merged:** 5/11/2026 **Merged by:** [@colifran](https://github.com/colifran) **Base:** `main` ← **Head:** `colifran/harness-profiles` --- ### 📝 Commits (10+) - [`15fb37b`](https://github.com/langchain-ai/deepagentsjs/commit/15fb37b4d0e834fb0e4c24a372fdc0d5b9f868c6) harness profiles wip - [`5efbc58`](https://github.com/langchain-ai/deepagentsjs/commit/5efbc58ea78d038a99071407def9c78f33f4c555) implement core types, validation logic, and serialization - [`334bed8`](https://github.com/langchain-ai/deepagentsjs/commit/334bed8be3a0a58c21df2f28df6cb7dd604056d3) refactor - [`1651138`](https://github.com/langchain-ai/deepagentsjs/commit/165113818191052a9d1c5ec9bc90a398f9b21287) implement merge, registry and lookup logic - [`354bb9d`](https://github.com/langchain-ai/deepagentsjs/commit/354bb9d3211a767b7e1553fb9409fb91675766ae) implement built in harness profiles - [`d6f16c0`](https://github.com/langchain-ai/deepagentsjs/commit/d6f16c0e84c3ce24a13febb062d4f937fe25613f) formatting - [`63eadf7`](https://github.com/langchain-ai/deepagentsjs/commit/63eadf711a4cdb4fa86e9afde64d815a9644f6b8) wire harness profiles into create deep agents - [`fd7851b`](https://github.com/langchain-ai/deepagentsjs/commit/fd7851bec2444ddd343b79109b66587b03ae8b71) linter - [`4c45711`](https://github.com/langchain-ai/deepagentsjs/commit/4c457116c4efc0491acdbf66b9fc84c017ce0db0) changeset - [`ae2a517`](https://github.com/langchain-ai/deepagentsjs/commit/ae2a517a647b48e2a61b46f681792cb848ab857f) empty commit ### 📊 Changes **25 files changed** (+2491 additions, -24 deletions) <details> <summary>View changed files</summary> ➕ `.changeset/wild-kings-scream.md` (+5 -0) 📝 `libs/deepagents/src/agent.test.ts` (+2 -1) 📝 `libs/deepagents/src/agent.ts` (+95 -23) 📝 `libs/deepagents/src/index.ts` (+17 -0) ➕ `libs/deepagents/src/profiles/harness/builtins.test.ts` (+174 -0) ➕ `libs/deepagents/src/profiles/harness/builtins/anthropic-haiku-4-5.ts` (+30 -0) ➕ `libs/deepagents/src/profiles/harness/builtins/anthropic-opus-4-7.ts` (+42 -0) ➕ `libs/deepagents/src/profiles/harness/builtins/anthropic-sonnet-4-6.ts` (+36 -0) ➕ `libs/deepagents/src/profiles/harness/builtins/index.ts` (+25 -0) ➕ `libs/deepagents/src/profiles/harness/builtins/openai-codex.ts` (+59 -0) ➕ `libs/deepagents/src/profiles/harness/create.test.ts` (+129 -0) ➕ `libs/deepagents/src/profiles/harness/create.ts` (+104 -0) ➕ `libs/deepagents/src/profiles/harness/index.ts` (+33 -0) ➕ `libs/deepagents/src/profiles/harness/merge.test.ts` (+215 -0) ➕ `libs/deepagents/src/profiles/harness/merge.ts` (+131 -0) ➕ `libs/deepagents/src/profiles/harness/registry.test.ts` (+246 -0) ➕ `libs/deepagents/src/profiles/harness/registry.ts` (+319 -0) ➕ `libs/deepagents/src/profiles/harness/serialization.test.ts` (+205 -0) ➕ `libs/deepagents/src/profiles/harness/serialization.ts` (+173 -0) ➕ `libs/deepagents/src/profiles/harness/types.test.ts` (+31 -0) _...and 5 more files_ </details> ### 📄 Description ### Summary Introduces harness profiles which is a way to declaratively control how agents behave at runtime without changing which model is used. A profile can override the system prompt, hide tools, add or remove middleware, and configure the general-purpose subagent. Profiles are registered by provider or model key ("anthropic", "openai:gpt-5.4") and looked up automatically when `createDeepAgent` is called. The system ships with built-in profiles for Anthropic Opus 4.7, Sonnet 4.6, Haiku 4.5, and OpenAI Codex that include vendor-recommended prompting guidance. Users can register their own profiles on top and registrations merge additively so provider-wide defaults compose with model-specific overrides. Profiles are plain frozen objects with Zod schemas for parsing from JSON/YAML config files, including prototype-pollution protection for untrusted input. ### Tests Unit tests cover key validation, profile construction and freezing, serialization round-trips, poison-key rejection, merge semantics across all field types, registry lookup with provider fallback, and prompt overlay behavior. Built-in profiles are tested for correct registration and expected content. Also verified end-to-end via a standalone script against LangSmith and confirmed the custom suffix appears in the system prompt and excluded tools are absent from the model call. ### Usage Example ```ts import { HumanMessage } from "@langchain/core/messages"; import { createDeepAgent, registerHarnessProfile } from "deepagents"; registerHarnessProfile("anthropic:claude-sonnet-4-6", { systemPromptSuffix: "Always respond in exactly one sentence.", excludedTools: ["grep"], generalPurposeSubagent: { description: "A customized GP subagent via harness profile.", }, }); const agent = createDeepAgent({ model: "anthropic:claude-sonnet-4-6", }); const result = await agent.invoke({ messages: [new HumanMessage("What is the capital of France?")], }); const lastMessage = result.messages[result.messages.length - 1]; console.log("Response:", lastMessage.content); ``` --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
yindo added the pull-request label 2026-06-05 17:23:36 -04:00
yindo closed this issue 2026-06-05 17:23:36 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/deepagentsjs#538