@ddlqhd/agent-sdk 0.1.1 → 0.2.1

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.
Files changed (40) hide show
  1. package/README.md +2 -1
  2. package/dist/{chunk-742JTNYI.js → chunk-D3UZNLZO.js} +570 -77
  3. package/dist/chunk-D3UZNLZO.js.map +1 -0
  4. package/dist/{chunk-AJD3DTL7.cjs → chunk-JXAJQGV5.cjs} +756 -107
  5. package/dist/chunk-JXAJQGV5.cjs.map +1 -0
  6. package/dist/{chunk-DQFTAD3I.cjs → chunk-NYZD3THB.cjs} +573 -76
  7. package/dist/chunk-NYZD3THB.cjs.map +1 -0
  8. package/dist/{chunk-Q3L4GIBG.cjs → chunk-P2X3AMDK.cjs} +115 -117
  9. package/dist/chunk-P2X3AMDK.cjs.map +1 -0
  10. package/dist/{chunk-THKEF32L.js → chunk-TKUPLTGJ.js} +110 -114
  11. package/dist/chunk-TKUPLTGJ.js.map +1 -0
  12. package/dist/{chunk-DXMVWGLJ.js → chunk-UHENMHUS.js} +744 -100
  13. package/dist/chunk-UHENMHUS.js.map +1 -0
  14. package/dist/cli/index.cjs +40 -31
  15. package/dist/cli/index.cjs.map +1 -1
  16. package/dist/cli/index.js +14 -5
  17. package/dist/cli/index.js.map +1 -1
  18. package/dist/{index-DGPDMbW5.d.cts → index-CnrY1ZA2.d.ts} +36 -14
  19. package/dist/{index-nEfayAzD.d.ts → index-DzBt4ewK.d.cts} +36 -14
  20. package/dist/index.cjs +128 -88
  21. package/dist/index.d.cts +42 -22
  22. package/dist/index.d.ts +42 -22
  23. package/dist/index.js +3 -3
  24. package/dist/models/index.cjs +14 -10
  25. package/dist/models/index.d.cts +7 -2
  26. package/dist/models/index.d.ts +7 -2
  27. package/dist/models/index.js +1 -1
  28. package/dist/tools/index.cjs +65 -57
  29. package/dist/tools/index.d.cts +3 -3
  30. package/dist/tools/index.d.ts +3 -3
  31. package/dist/tools/index.js +1 -1
  32. package/dist/{types-BLf9IqRs.d.cts → types-BUwjMwNH.d.cts} +279 -13
  33. package/dist/{types-BLf9IqRs.d.ts → types-BUwjMwNH.d.ts} +279 -13
  34. package/package.json +11 -11
  35. package/dist/chunk-742JTNYI.js.map +0 -1
  36. package/dist/chunk-AJD3DTL7.cjs.map +0 -1
  37. package/dist/chunk-DQFTAD3I.cjs.map +0 -1
  38. package/dist/chunk-DXMVWGLJ.js.map +0 -1
  39. package/dist/chunk-Q3L4GIBG.cjs.map +0 -1
  40. package/dist/chunk-THKEF32L.js.map +0 -1
@@ -261,10 +261,12 @@ var ToolRegistry = class {
261
261
  outputHandler;
262
262
  hookManager = null;
263
263
  executionPolicy;
264
+ hookObserver;
264
265
  constructor(config) {
265
266
  const enableOutputHandler = config?.enableOutputHandler !== false;
266
267
  this.outputHandler = enableOutputHandler ? createOutputHandler(config?.userBasePath) : null;
267
268
  this.executionPolicy = config?.executionPolicy;
269
+ this.hookObserver = config?.hookObserver;
268
270
  }
269
271
  /**
270
272
  * 工具名是否在 {@link ToolExecutionPolicy.disallowedTools} 中(无策略时为 false)。
@@ -331,6 +333,14 @@ var ToolRegistry = class {
331
333
  ...extra
332
334
  };
333
335
  }
336
+ hookObserverCtx(eventType, name, options) {
337
+ return {
338
+ eventType,
339
+ toolName: name,
340
+ toolCallId: options?.toolCallId,
341
+ projectDir: options?.projectDir
342
+ };
343
+ }
334
344
  /**
335
345
  * 注册工具
336
346
  */
@@ -401,6 +411,11 @@ var ToolRegistry = class {
401
411
  }
402
412
  const tool = this.tools.get(name);
403
413
  if (!tool) {
414
+ if (hookMgr) {
415
+ this.hookObserver?.onHookStart?.(
416
+ this.hookObserverCtx("postToolUseFailure", name, options)
417
+ );
418
+ }
404
419
  const ctx = this.buildHookContext("postToolUseFailure", name, rawArgsObj, options, {
405
420
  errorMessage: `Tool "${name}" not found`,
406
421
  failureKind: "tool_error"
@@ -416,6 +431,11 @@ var ToolRegistry = class {
416
431
  const initial = tool.parameters.safeParse(args);
417
432
  if (!initial.success) {
418
433
  const msg = `Invalid arguments for tool "${name}": ${initial.error.issues.map((i) => i.message).join(", ")}`;
434
+ if (hookMgr) {
435
+ this.hookObserver?.onHookStart?.(
436
+ this.hookObserverCtx("postToolUseFailure", name, options)
437
+ );
438
+ }
419
439
  await hookMgr?.executePostToolUseFailure(
420
440
  this.buildHookContext("postToolUseFailure", name, rawArgsObj, options, {
421
441
  errorMessage: msg,
@@ -426,9 +446,17 @@ var ToolRegistry = class {
426
446
  }
427
447
  workingInput = initial.data;
428
448
  if (hookMgr) {
449
+ this.hookObserver?.onHookStart?.(
450
+ this.hookObserverCtx("preToolUse", name, options)
451
+ );
429
452
  const pre = await hookMgr.executePreToolUse(
430
453
  this.buildHookContext("preToolUse", name, workingInput, options)
431
454
  );
455
+ this.hookObserver?.onHookDecision?.({
456
+ ...this.hookObserverCtx("preToolUse", name, options),
457
+ allowed: pre.allowed,
458
+ reason: pre.reason
459
+ });
432
460
  if (!pre.allowed) {
433
461
  return {
434
462
  content: pre.reason ?? "Blocked by hook",
@@ -438,6 +466,9 @@ var ToolRegistry = class {
438
466
  const merged = tool.parameters.safeParse(pre.updatedInput ?? workingInput);
439
467
  if (!merged.success) {
440
468
  const msg = `Invalid arguments after hook merge for tool "${name}": ${merged.error.issues.map((i) => i.message).join(", ")}`;
469
+ this.hookObserver?.onHookStart?.(
470
+ this.hookObserverCtx("postToolUseFailure", name, options)
471
+ );
441
472
  await hookMgr.executePostToolUseFailure(
442
473
  this.buildHookContext("postToolUseFailure", name, workingInput, options, {
443
474
  errorMessage: msg,
@@ -457,6 +488,11 @@ var ToolRegistry = class {
457
488
  const result = await tool.handler(handlerArgs, executionContext);
458
489
  const toolResultRaw = result;
459
490
  if (result.isError) {
491
+ if (hookMgr) {
492
+ this.hookObserver?.onHookStart?.(
493
+ this.hookObserverCtx("postToolUseFailure", name, options)
494
+ );
495
+ }
460
496
  await hookMgr?.executePostToolUseFailure(
461
497
  this.buildHookContext("postToolUseFailure", name, workingInput, options, {
462
498
  errorMessage: result.content,
@@ -474,6 +510,11 @@ var ToolRegistry = class {
474
510
  { args: handlerArgs }
475
511
  );
476
512
  }
513
+ if (hookMgr) {
514
+ this.hookObserver?.onHookStart?.(
515
+ this.hookObserverCtx("postToolUse", name, options)
516
+ );
517
+ }
477
518
  await hookMgr?.executePostToolUse(
478
519
  this.buildHookContext("postToolUse", name, workingInput, options, {
479
520
  toolResultRaw,
@@ -483,6 +524,11 @@ var ToolRegistry = class {
483
524
  return finalResult;
484
525
  } catch (error) {
485
526
  const msg = `Error executing tool "${name}": ${error instanceof Error ? error.message : String(error)}`;
527
+ if (hookMgr) {
528
+ this.hookObserver?.onHookStart?.(
529
+ this.hookObserverCtx("postToolUseFailure", name, options)
530
+ );
531
+ }
486
532
  await hookMgr?.executePostToolUseFailure(
487
533
  this.buildHookContext("postToolUseFailure", name, workingInput, options, {
488
534
  errorMessage: msg,
@@ -2143,128 +2189,52 @@ var webSearchTool = createTool({
2143
2189
  function getWebTools() {
2144
2190
  return [webFetchTool, webSearchTool];
2145
2191
  }
2146
- var tasks = /* @__PURE__ */ new Map();
2147
- var nextId = 1;
2148
- var taskCreateTool = createTool({
2149
- name: "TaskCreate",
2192
+ var todoStatusEnum = zod.z.enum(["pending", "in_progress", "completed"]);
2193
+ var todoWriteTool = createTool({
2194
+ name: "TodoWrite",
2150
2195
  category: "planning",
2151
- description: `Use this tool to create a structured task list for your current coding session. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.
2196
+ description: `MUST USE for multi-step tasks. Creates a structured task list to track progress. Call this tool FIRST before executing any complex task.
2152
2197
 
2153
- ## When to Use This Tool
2198
+ Any number of tasks may be "in_progress" when work runs in parallel. Zero in_progress is fine (e.g. all pending or all completed).
2154
2199
 
2155
- - Complex multi-step tasks - When a task requires 3 or more distinct steps or actions
2156
- - Non-trivial and complex tasks - Tasks that require careful planning or multiple operations
2157
- - User explicitly requests todo list - When the user directly asks you to use the task list
2158
- - User provides multiple tasks - When users provide a list of things to be done
2200
+ **Before you finish your assistant response for a multi-step request**, call \`TodoWrite\` again so **every** item in the list has status \`completed\`, unless you are explicitly pausing mid-work for a follow-up turn. Do not leave dangling \`pending\` or \`in_progress\` items when the work for this request is done.
2159
2201
 
2160
- ## When NOT to Use
2202
+ **Replanning:** If execution shows the earlier plan was wrong, incomplete, or no longer fits (wrong order, missing steps, obsolete items), call \`TodoWrite\` anytime with an updated full list\u2014add, remove, merge, or rewrite steps as needed.
2161
2203
 
2162
- - There is only a single, straightforward task
2163
- - The task is trivial and tracking it provides no organizational benefit
2164
- - The task can be completed in less than 3 trivial steps
2165
-
2166
- All tasks are created with status pending.`,
2204
+ Triggers: multi-step tasks, multiple files/components, user provides task list.
2205
+ Skip: single simple task, informational questions.`,
2167
2206
  parameters: zod.z.object({
2168
- subject: zod.z.string().describe("A brief title for the task"),
2169
- description: zod.z.string().describe("What needs to be done"),
2170
- activeForm: zod.z.string().optional().describe('Present continuous form shown in spinner when in_progress (e.g., "Running tests")')
2171
- }),
2172
- handler: async ({ subject, description, activeForm }) => {
2173
- const id = String(nextId++);
2174
- const task = {
2175
- id,
2176
- subject,
2177
- description,
2178
- status: "pending",
2179
- ...activeForm && { activeForm }
2180
- };
2181
- tasks.set(id, task);
2182
- return {
2183
- content: `Task created [${id}]: ${subject}`,
2184
- metadata: { task }
2185
- };
2186
- }
2187
- });
2188
- var taskUpdateTool = createTool({
2189
- name: "TaskUpdate",
2190
- category: "planning",
2191
- description: `Use this tool to update a task in the task list.
2192
-
2193
- ## When to Use This Tool
2194
-
2195
- **Mark tasks as completed:**
2196
- - When you have completed the work described in a task
2197
- - IMPORTANT: Always mark your assigned tasks as completed when you finish them
2198
-
2199
- **Delete tasks:**
2200
- - When a task is no longer relevant or was created in error
2201
-
2202
- ## Status Workflow
2203
-
2204
- Status progresses: pending \u2192 in_progress \u2192 completed`,
2205
- parameters: zod.z.object({
2206
- taskId: zod.z.string().describe("The ID of the task to update"),
2207
- status: zod.z.enum(["pending", "in_progress", "completed", "deleted"]).optional().describe("New status for the task"),
2208
- subject: zod.z.string().optional().describe("New subject for the task"),
2209
- description: zod.z.string().optional().describe("New description for the task"),
2210
- activeForm: zod.z.string().optional().describe("Present continuous form shown in spinner when in_progress")
2207
+ todos: zod.z.array(
2208
+ zod.z.object({
2209
+ content: zod.z.string().describe('Brief description of the task in imperative form (e.g., "Run tests")'),
2210
+ activeForm: zod.z.string().optional().describe(
2211
+ 'Optional present-continuous label for in-progress UI (e.g., "Running tests"). Omit if not needed.'
2212
+ ),
2213
+ status: todoStatusEnum.describe("Task status: pending, in_progress, or completed")
2214
+ })
2215
+ ).min(1).describe(
2216
+ "Full updated todo list. Refresh this whenever progress or the plan changes. When finishing the multi-step work, all entries should be completed."
2217
+ )
2211
2218
  }),
2212
- handler: async ({ taskId, status, subject, description, activeForm }) => {
2213
- const task = tasks.get(taskId);
2214
- if (!task) {
2215
- return {
2216
- content: `Task ${taskId} not found`,
2217
- isError: true
2218
- };
2219
- }
2220
- if (status === "deleted") {
2221
- tasks.delete(taskId);
2222
- return { content: `Task ${taskId} deleted` };
2223
- }
2224
- if (status) task.status = status;
2225
- if (subject) task.subject = subject;
2226
- if (description) task.description = description;
2227
- if (activeForm) task.activeForm = activeForm;
2228
- const icon = task.status === "completed" ? "x" : task.status === "in_progress" ? ">" : " ";
2229
- return {
2230
- content: `Task [${taskId}] updated: [${icon}] ${task.subject}`,
2231
- metadata: { task }
2232
- };
2233
- }
2234
- });
2235
- var taskListTool = createTool({
2236
- name: "TaskList",
2237
- category: "planning",
2238
- description: `Use this tool to list all tasks in the task list.
2239
-
2240
- ## Output
2241
-
2242
- Returns a summary of each task:
2243
- - id: Task identifier (use with TaskUpdate)
2244
- - subject: Brief description of the task
2245
- - status: pending, in_progress, or completed`,
2246
- parameters: zod.z.object({}),
2247
- handler: async () => {
2248
- if (tasks.size === 0) {
2249
- return { content: "No tasks in the list." };
2250
- }
2219
+ handler: async ({ todos }) => {
2251
2220
  const lines = [];
2252
- for (const [, task] of tasks) {
2253
- const icon = task.status === "completed" ? "x" : task.status === "in_progress" ? ">" : " ";
2254
- lines.push(`[${icon}] [${task.id}] ${task.subject}`);
2221
+ for (const todo of todos) {
2222
+ const icon = todo.status === "completed" ? "x" : todo.status === "in_progress" ? ">" : " ";
2223
+ lines.push(`[${icon}] ${todo.content}`);
2255
2224
  }
2256
- const pending = [...tasks.values()].filter((t) => t.status === "pending").length;
2257
- const inProgress = [...tasks.values()].filter((t) => t.status === "in_progress").length;
2258
- const completed = [...tasks.values()].filter((t) => t.status === "completed").length;
2225
+ const pending = todos.filter((todo) => todo.status === "pending").length;
2226
+ const inProgress = todos.filter((todo) => todo.status === "in_progress").length;
2227
+ const completed = todos.filter((todo) => todo.status === "completed").length;
2259
2228
  return {
2260
- content: `Tasks (${completed} completed, ${inProgress} in progress, ${pending} pending):
2229
+ content: `Task list updated (${completed} completed, ${inProgress} in progress, ${pending} pending):
2261
2230
 
2262
- ${lines.join("\n")}`
2231
+ ${lines.join("\n")}`,
2232
+ metadata: { todos }
2263
2233
  };
2264
2234
  }
2265
2235
  });
2266
- function getTaskTools() {
2267
- return [taskCreateTool, taskUpdateTool, taskListTool];
2236
+ function getPlanningTools() {
2237
+ return [todoWriteTool];
2268
2238
  }
2269
2239
  var questionsSchema = zod.z.object({
2270
2240
  questions: zod.z.array(
@@ -2420,10 +2390,35 @@ ${availableList}`,
2420
2390
  function getSkillTools(skillRegistry) {
2421
2391
  return [createSkillTool(skillRegistry)];
2422
2392
  }
2393
+
2394
+ // src/tools/builtin/subagent-profiles.ts
2395
+ var SUBAGENT_TYPES = ["general-purpose", "explore"];
2396
+ var EXPLORE_SYSTEM_APPEND = `## Subagent role: explore
2397
+
2398
+ You are running as a read-focused subagent. Prefer **Read**, **Glob**, and **Grep** to locate and cite evidence; use **WebFetch** / **WebSearch** when external facts are needed. Summarize findings with file paths and short excerpts. If your tool list includes editing or shell (for example when the parent set \`allowed_tools\` explicitly), use those only when strictly necessary for the delegated task.`;
2399
+ var SUBAGENT_EXPLORE_DEFAULT_TOOL_NAMES = [
2400
+ "Read",
2401
+ "Glob",
2402
+ "Grep",
2403
+ "WebFetch",
2404
+ "WebSearch"
2405
+ ];
2406
+ function subagentExploreDefaultsUnavailableMessage() {
2407
+ const listed = SUBAGENT_EXPLORE_DEFAULT_TOOL_NAMES.join(", ");
2408
+ return `Explore subagent: none of the default tools (${listed}) are available from the parent agent. Register them on the parent, widen parent tools, or pass allowed_tools.`;
2409
+ }
2410
+ function resolveSubagentTypeAppend(type, subagent) {
2411
+ const custom = subagent?.subagentTypePrompts?.[type];
2412
+ if (custom !== void 0) {
2413
+ const trimmed = custom.trim();
2414
+ return trimmed === "" ? void 0 : custom;
2415
+ }
2416
+ return type === "explore" ? EXPLORE_SYSTEM_APPEND : void 0;
2417
+ }
2423
2418
  var subagentRequestSchema = zod.z.object({
2424
2419
  prompt: zod.z.string().min(1).describe("Task prompt for the subagent. Include all required context."),
2425
2420
  description: zod.z.string().optional().describe("Short 3-5 words task label for logs and metadata."),
2426
- subagent_type: zod.z.enum(["general-purpose", "explore"]).default("general-purpose").describe("Subagent profile/type to use."),
2421
+ subagent_type: zod.z.enum(SUBAGENT_TYPES).default("general-purpose").describe("Subagent profile/type to use."),
2427
2422
  allowed_tools: zod.z.array(zod.z.string().min(1)).optional().describe("Optional allowlist of tool names for the subagent."),
2428
2423
  max_iterations: zod.z.number().int().min(1).optional().describe("Maximum reasoning iterations for the subagent."),
2429
2424
  timeout_ms: zod.z.number().int().min(1e3).optional().describe("Timeout for this subagent run in milliseconds."),
@@ -2449,7 +2444,8 @@ When NOT to use this tool:
2449
2444
 
2450
2445
  Usage notes:
2451
2446
  - Always pass a short description and a complete prompt with all required context
2452
- - Use subagent_type to select behavior; default is general-purpose
2447
+ - Use subagent_type: **general-purpose** (default) for balanced work, or **explore** for read-focused runs (SDK appends explore instructions; if you omit allowed_tools and subagent.defaultAllowedTools, tools default to Read/Glob/Grep/WebFetch/WebSearch)
2448
+ - Optional system_prompt is merged after the type-specific fragment; override per-type text via AgentConfig.subagent.subagentTypePrompts if needed
2453
2449
  - Subagents do not inherit parent conversation history, only the prompt you provide
2454
2450
  - Subagents cannot spawn other subagents (no nested Agent calls)`,
2455
2451
  parameters: subagentRequestSchema,
@@ -2475,7 +2471,7 @@ function getAllBuiltinTools(skillRegistry, interactionOptions) {
2475
2471
  ...getShellTools(),
2476
2472
  ...getGrepTools(),
2477
2473
  ...getWebTools(),
2478
- ...getTaskTools(),
2474
+ ...getPlanningTools(),
2479
2475
  ...getInteractionTools(interactionOptions),
2480
2476
  ...getSubagentTools(),
2481
2477
  ...getSkillTools(skillRegistry)
@@ -2893,6 +2889,8 @@ exports.MAX_LINE_LENGTH = MAX_LINE_LENGTH2;
2893
2889
  exports.OUTPUT_CONFIG = OUTPUT_CONFIG;
2894
2890
  exports.OutputHandler = OutputHandler;
2895
2891
  exports.PaginationHintStrategy = PaginationHintStrategy;
2892
+ exports.SUBAGENT_EXPLORE_DEFAULT_TOOL_NAMES = SUBAGENT_EXPLORE_DEFAULT_TOOL_NAMES;
2893
+ exports.SUBAGENT_TYPES = SUBAGENT_TYPES;
2896
2894
  exports.SmartTruncateStrategy = SmartTruncateStrategy;
2897
2895
  exports.ToolRegistry = ToolRegistry;
2898
2896
  exports.agentTool = agentTool;
@@ -2914,11 +2912,11 @@ exports.getFileSystemTools = getFileSystemTools;
2914
2912
  exports.getGlobalRegistry = getGlobalRegistry;
2915
2913
  exports.getGrepTools = getGrepTools;
2916
2914
  exports.getInteractionTools = getInteractionTools;
2915
+ exports.getPlanningTools = getPlanningTools;
2917
2916
  exports.getSafeBuiltinTools = getSafeBuiltinTools;
2918
2917
  exports.getShellTools = getShellTools;
2919
2918
  exports.getSkillTools = getSkillTools;
2920
2919
  exports.getSubagentTools = getSubagentTools;
2921
- exports.getTaskTools = getTaskTools;
2922
2920
  exports.getWebTools = getWebTools;
2923
2921
  exports.globTool = globTool;
2924
2922
  exports.grepTool = grepTool;
@@ -2929,13 +2927,13 @@ exports.mergeCommandHookLayers = mergeCommandHookLayers;
2929
2927
  exports.parseHooksSettingsFile = parseHooksSettingsFile;
2930
2928
  exports.questionTool = questionTool;
2931
2929
  exports.readFileTool = readFileTool;
2930
+ exports.resolveSubagentTypeAppend = resolveSubagentTypeAppend;
2931
+ exports.subagentExploreDefaultsUnavailableMessage = subagentExploreDefaultsUnavailableMessage;
2932
2932
  exports.subagentRequestSchema = subagentRequestSchema;
2933
- exports.taskCreateTool = taskCreateTool;
2934
- exports.taskListTool = taskListTool;
2935
- exports.taskUpdateTool = taskUpdateTool;
2933
+ exports.todoWriteTool = todoWriteTool;
2936
2934
  exports.truncateMatchLineForDisplay = truncateMatchLineForDisplay;
2937
2935
  exports.webFetchTool = webFetchTool;
2938
2936
  exports.webSearchTool = webSearchTool;
2939
2937
  exports.writeFileTool = writeFileTool;
2940
- //# sourceMappingURL=chunk-Q3L4GIBG.cjs.map
2941
- //# sourceMappingURL=chunk-Q3L4GIBG.cjs.map
2938
+ //# sourceMappingURL=chunk-P2X3AMDK.cjs.map
2939
+ //# sourceMappingURL=chunk-P2X3AMDK.cjs.map