deepagents 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/graph.d.ts CHANGED
@@ -6,15 +6,17 @@
6
6
  * provided tools, creates task tool using createTaskTool(), and returns createReactAgent
7
7
  * with proper configuration. Ensures exact parameter matching and behavior with Python version.
8
8
  */
9
- import type { CreateDeepAgentParams } from "./types.js";
9
+ import { InteropZodObject } from "@langchain/core/utils/types";
10
+ import type { AnyAnnotationRoot, CreateDeepAgentParams } from "./types.js";
10
11
  import { z } from "zod";
11
12
  /**
12
13
  * Create a Deep Agent with TypeScript types for all parameters.
13
14
  * Combines built-in tools with provided tools, creates task tool using createTaskTool(),
14
15
  * and returns createReactAgent with proper configuration.
15
16
  * Ensures exact parameter matching and behavior with Python version.
17
+ *
16
18
  */
17
- export declare function createDeepAgent<StateSchema extends z.ZodObject<any, any, any, any, any>>(params?: CreateDeepAgentParams<StateSchema>): import("@langchain/langgraph").CompiledStateGraph<import("@langchain/langgraph").StateType<import("@langchain/langgraph/zod").InteropZodToStateDefinition<z.ZodObject<{
19
+ export declare function createDeepAgent<StateSchema extends z.ZodObject<any, any, any, any, any>, ContextSchema extends AnyAnnotationRoot | InteropZodObject = AnyAnnotationRoot>(params?: CreateDeepAgentParams<StateSchema, ContextSchema>): import("@langchain/langgraph").CompiledStateGraph<import("@langchain/langgraph").StateType<import("@langchain/langgraph/zod").InteropZodToStateDefinition<z.ZodObject<{
18
20
  messages: import("@langchain/langgraph/zod").ReducedZodChannel<z.ZodType<import("@langchain/core/messages").BaseMessage[], z.ZodTypeDef, import("@langchain/core/messages").BaseMessage[]>, import("@langchain/core/utils/types").InteropZodType<import("@langchain/langgraph").Messages>>;
19
21
  } & {
20
22
  todos: import("@langchain/langgraph/zod").ReducedZodChannel<z.ZodType<import("./types.js").Todo[], z.ZodTypeDef, import("./types.js").Todo[]>, import("@langchain/core/utils/types").InteropZodType<import("./types.js").Todo[] | null | undefined>>;
@@ -123,4 +125,4 @@ export declare function createDeepAgent<StateSchema extends z.ZodObject<any, any
123
125
  [x: string]: any;
124
126
  }>, {
125
127
  [x: string]: any;
126
- }>), import("@langchain/langgraph").StateDefinition>;
128
+ }>), import("@langchain/langgraph").StateDefinition, unknown>;
package/dist/graph.js CHANGED
@@ -12,6 +12,7 @@ import { createTaskTool } from "./subAgent.js";
12
12
  import { getDefaultModel } from "./model.js";
13
13
  import { writeTodos, readFile, writeFile, editFile, ls } from "./tools.js";
14
14
  import { DeepAgentState } from "./state.js";
15
+ import { createInterruptHook } from "./interrupt.js";
15
16
  /**
16
17
  * Base prompt that provides instructions about available tools
17
18
  * Ported from Python implementation to ensure consistent behavior
@@ -42,14 +43,19 @@ const BUILTIN_TOOLS = [
42
43
  * Combines built-in tools with provided tools, creates task tool using createTaskTool(),
43
44
  * and returns createReactAgent with proper configuration.
44
45
  * Ensures exact parameter matching and behavior with Python version.
46
+ *
45
47
  */
46
48
  export function createDeepAgent(params = {}) {
47
- const { tools = [], instructions, model = getDefaultModel(), subagents = [], } = params;
49
+ const { tools = [], instructions, model = getDefaultModel(), subagents = [], postModelHook, contextSchema, interruptConfig = {}, builtinTools, } = params;
48
50
  const stateSchema = params.stateSchema
49
51
  ? DeepAgentState.extend(params.stateSchema.shape)
50
52
  : DeepAgentState;
53
+ // Filter built-in tools if builtinTools parameter is provided
54
+ const selectedBuiltinTools = builtinTools
55
+ ? BUILTIN_TOOLS.filter((tool) => builtinTools.some((bt) => bt === tool.name))
56
+ : BUILTIN_TOOLS;
51
57
  // Combine built-in tools with provided tools
52
- const allTools = [...BUILTIN_TOOLS, ...tools];
58
+ const allTools = [...selectedBuiltinTools, ...tools];
53
59
  // Create task tool using createTaskTool() if subagents are provided
54
60
  if (subagents.length > 0) {
55
61
  // Create tools map for task tool creation
@@ -71,11 +77,28 @@ export function createDeepAgent(params = {}) {
71
77
  const finalInstructions = instructions
72
78
  ? instructions + BASE_PROMPT
73
79
  : BASE_PROMPT;
80
+ // Should never be the case that both are specified
81
+ if (postModelHook && Object.keys(interruptConfig).length > 0) {
82
+ throw new Error("Cannot specify both postModelHook and interruptConfig together. " +
83
+ "Use either interruptConfig for tool interrupts or postModelHook for custom post-processing.");
84
+ }
85
+ let selectedPostModelHook;
86
+ if (postModelHook !== undefined) {
87
+ selectedPostModelHook = postModelHook;
88
+ }
89
+ else if (Object.keys(interruptConfig).length > 0) {
90
+ selectedPostModelHook = createInterruptHook(interruptConfig);
91
+ }
92
+ else {
93
+ selectedPostModelHook = undefined;
94
+ }
74
95
  // Return createReactAgent with proper configuration
75
96
  return createReactAgent({
76
97
  llm: model,
77
98
  tools: allTools,
78
99
  stateSchema,
79
100
  messageModifier: finalInstructions,
101
+ contextSchema,
102
+ postModelHook: selectedPostModelHook,
80
103
  });
81
104
  }
@@ -0,0 +1,2 @@
1
+ import type { DeepAgentStateType, ToolInterruptConfig } from "./types.js";
2
+ export declare function createInterruptHook(toolConfigs: ToolInterruptConfig, messagePrefix?: string): (state: DeepAgentStateType) => Promise<Partial<DeepAgentStateType> | void>;
@@ -0,0 +1,103 @@
1
+ import { interrupt } from "@langchain/langgraph";
2
+ import { isAIMessage, AIMessage, ToolMessage } from "@langchain/core/messages";
3
+ export function createInterruptHook(toolConfigs, messagePrefix = "Tool execution requires approval") {
4
+ /**
5
+ * Create a post model hook that handles interrupts using native LangGraph schemas.
6
+ *
7
+ * Args:
8
+ * toolConfigs: Record mapping tool names to HumanInterruptConfig objects
9
+ * messagePrefix: Optional message prefix for interrupt descriptions
10
+ */
11
+ Object.entries(toolConfigs).forEach(([tool, interruptConfig]) => {
12
+ if (interruptConfig &&
13
+ typeof interruptConfig === "object" &&
14
+ interruptConfig.allow_ignore) {
15
+ throw new Error(`For ${tool} we get allow_ignore = true - we currently don't support ignore.`);
16
+ }
17
+ });
18
+ return async function interruptHook(state) {
19
+ const messages = state.messages || [];
20
+ if (!messages.length) {
21
+ return;
22
+ }
23
+ const lastMessage = messages[messages.length - 1];
24
+ if (!isAIMessage(lastMessage) ||
25
+ !lastMessage.tool_calls ||
26
+ !lastMessage.tool_calls.length) {
27
+ return;
28
+ }
29
+ const interruptToolCalls = [];
30
+ const autoApprovedToolCalls = [];
31
+ for (const toolCall of lastMessage.tool_calls) {
32
+ const toolName = toolCall.name;
33
+ if (toolName in toolConfigs) {
34
+ interruptToolCalls.push(toolCall);
35
+ }
36
+ else {
37
+ autoApprovedToolCalls.push(toolCall);
38
+ }
39
+ }
40
+ if (!interruptToolCalls.length) {
41
+ return;
42
+ }
43
+ const approvedToolCalls = [...autoApprovedToolCalls];
44
+ if (interruptToolCalls.length > 1) {
45
+ throw new Error("Right now, interrupt hook only works when one tool requires interrupts");
46
+ }
47
+ const toolCall = interruptToolCalls[0];
48
+ const toolName = toolCall.name;
49
+ const toolArgs = toolCall.args;
50
+ const description = `${messagePrefix}\n\nTool: ${toolName}\nArgs: ${JSON.stringify(toolArgs, null, 2)}`;
51
+ const toolConfig = toolConfigs[toolName];
52
+ const defaultToolConfig = {
53
+ allow_accept: true,
54
+ allow_edit: true,
55
+ allow_respond: true,
56
+ allow_ignore: false,
57
+ };
58
+ const request = {
59
+ action_request: {
60
+ action: toolName,
61
+ args: toolArgs,
62
+ },
63
+ config: typeof toolConfig === "object" ? toolConfig : defaultToolConfig,
64
+ description: description,
65
+ };
66
+ const res = await interrupt([request]);
67
+ const responses = Array.isArray(res) ? res : [res];
68
+ if (responses.length !== 1) {
69
+ throw new Error(`Expected a list of one response, got ${responses}`);
70
+ }
71
+ const response = responses[0];
72
+ if (response.type === "accept") {
73
+ approvedToolCalls.push(toolCall);
74
+ }
75
+ else if (response.type === "edit") {
76
+ const edited = response.args;
77
+ const newToolCall = {
78
+ name: edited.action,
79
+ args: edited.args,
80
+ id: toolCall.id,
81
+ };
82
+ approvedToolCalls.push(newToolCall);
83
+ }
84
+ else if (response.type === "response") {
85
+ if (!toolCall.id) {
86
+ throw new Error("Tool call must have an ID for response type");
87
+ }
88
+ const responseMessage = new ToolMessage({
89
+ tool_call_id: toolCall.id,
90
+ content: response.args,
91
+ });
92
+ return { messages: [responseMessage] };
93
+ }
94
+ else {
95
+ throw new Error(`Unknown response type: ${response.type}`);
96
+ }
97
+ const updatedLastMessage = new AIMessage({
98
+ ...lastMessage,
99
+ tool_calls: approvedToolCalls,
100
+ });
101
+ return { messages: [updatedLastMessage] };
102
+ };
103
+ }
package/dist/tools.d.ts CHANGED
@@ -43,15 +43,13 @@ export declare const writeTodos: import("@langchain/core/tools").DynamicStructur
43
43
  status: "pending" | "in_progress" | "completed";
44
44
  content: string;
45
45
  }[];
46
- }, {
47
- update: {
48
- todos: {
49
- status: "pending" | "in_progress" | "completed";
50
- content: string;
51
- }[];
52
- messages: ToolMessage[];
53
- };
54
- }>;
46
+ }, Command<unknown, {
47
+ todos: {
48
+ status: "pending" | "in_progress" | "completed";
49
+ content: string;
50
+ }[];
51
+ messages: ToolMessage[];
52
+ }, string>>;
55
53
  /**
56
54
  * List files tool - returns list of files from state.files
57
55
  * Equivalent to Python's ls function
package/dist/tools.js CHANGED
@@ -15,7 +15,7 @@ import { WRITE_TODOS_DESCRIPTION, EDIT_DESCRIPTION, TOOL_DESCRIPTION, } from "./
15
15
  * Uses getCurrentTaskInput() instead of Python's InjectedState
16
16
  */
17
17
  export const writeTodos = tool((input, config) => {
18
- return {
18
+ return new Command({
19
19
  update: {
20
20
  todos: input.todos,
21
21
  messages: [
@@ -25,7 +25,7 @@ export const writeTodos = tool((input, config) => {
25
25
  }),
26
26
  ],
27
27
  },
28
- };
28
+ });
29
29
  }, {
30
30
  name: "write_todos",
31
31
  description: WRITE_TODOS_DESCRIPTION,
package/dist/types.d.ts CHANGED
@@ -11,6 +11,10 @@ import type { StructuredTool } from "@langchain/core/tools";
11
11
  import type { DeepAgentState } from "./state.js";
12
12
  import { z } from "zod";
13
13
  import { Runnable } from "@langchain/core/runnables";
14
+ import { AnnotationRoot } from "@langchain/langgraph";
15
+ import { InteropZodObject } from "@langchain/core/utils/types";
16
+ import type { HumanInterruptConfig } from "@langchain/langgraph/prebuilt";
17
+ export type AnyAnnotationRoot = AnnotationRoot<any>;
14
18
  export type InferZodObjectShape<T> = T extends z.ZodObject<infer Shape> ? Shape : never;
15
19
  /**
16
20
  * SubAgent interface matching Python's TypedDict structure
@@ -28,19 +32,19 @@ export interface Todo {
28
32
  }
29
33
  export type DeepAgentStateType = z.infer<typeof DeepAgentState>;
30
34
  export type LanguageModelLike = Runnable<BaseLanguageModelInput, LanguageModelOutput>;
31
- /**
32
- * Parameters for createDeepAgent function with TypeScript types
33
- */
34
- export interface CreateDeepAgentParams<StateSchema extends z.ZodObject<any, any, any, any, any>> {
35
+ export type PostModelHook = (state: DeepAgentStateType, model: LanguageModelLike) => Promise<Partial<DeepAgentStateType> | void>;
36
+ export type ToolInterruptConfig = Record<string, HumanInterruptConfig | boolean>;
37
+ export interface CreateDeepAgentParams<StateSchema extends z.ZodObject<any, any, any, any, any>, ContextSchema extends AnyAnnotationRoot | InteropZodObject = AnyAnnotationRoot> {
35
38
  tools?: StructuredTool[];
36
39
  instructions?: string;
37
40
  model?: LanguageModelLike;
38
41
  subagents?: SubAgent[];
39
42
  stateSchema?: StateSchema;
43
+ contextSchema?: ContextSchema;
44
+ postModelHook?: PostModelHook;
45
+ interruptConfig?: ToolInterruptConfig;
46
+ builtinTools?: string[];
40
47
  }
41
- /**
42
- * Parameters for createTaskTool function
43
- */
44
48
  export interface CreateTaskToolParams<StateSchema extends z.ZodObject<any, any, any, any, any>> {
45
49
  subagents: SubAgent[];
46
50
  tools?: Record<string, StructuredTool>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepagents",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "Deep Agents - a library for building controllable AI agents with LangGraph",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -41,7 +41,7 @@
41
41
  "dependencies": {
42
42
  "@langchain/anthropic": "^0.3.25",
43
43
  "@langchain/core": "^0.3.66",
44
- "@langchain/langgraph": "^0.4.2",
44
+ "@langchain/langgraph": "^0.4.6",
45
45
  "zod": "^3.25.32"
46
46
  },
47
47
  "devDependencies": {