lsd-pi 1.3.2 → 1.3.7

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 (205) hide show
  1. package/dist/cli.js +2 -1
  2. package/dist/lsd-settings-manager.d.ts +2 -0
  3. package/dist/lsd-settings-manager.js +5 -0
  4. package/dist/resource-loader.js +33 -3
  5. package/dist/resources/extensions/browser-tools/tools/codegen.js +5 -5
  6. package/dist/resources/extensions/browser-tools/tools/navigation.js +107 -178
  7. package/dist/resources/extensions/browser-tools/tools/network-mock.js +112 -167
  8. package/dist/resources/extensions/browser-tools/tools/pages.js +182 -234
  9. package/dist/resources/extensions/browser-tools/tools/refs.js +202 -461
  10. package/dist/resources/extensions/browser-tools/tools/session.js +176 -323
  11. package/dist/resources/extensions/browser-tools/tools/state-persistence.js +91 -154
  12. package/dist/resources/extensions/browser-tools/utils.js +1 -1
  13. package/dist/resources/extensions/cache-timer/index.js +3 -2
  14. package/dist/resources/extensions/slash-commands/extension-manifest.json +2 -2
  15. package/dist/resources/extensions/slash-commands/fast.js +73 -0
  16. package/dist/resources/extensions/slash-commands/index.js +2 -0
  17. package/dist/resources/extensions/slash-commands/plan.js +37 -12
  18. package/dist/resources/extensions/subagent/background-job-manager.js +13 -0
  19. package/dist/resources/extensions/subagent/in-process-runner.js +387 -0
  20. package/dist/resources/extensions/subagent/index.js +278 -626
  21. package/dist/resources/extensions/subagent/legacy-runner.js +503 -0
  22. package/dist/resources/extensions/voice/index.js +96 -36
  23. package/dist/resources/extensions/voice/push-to-talk.js +26 -0
  24. package/dist/welcome-screen.js +2 -2
  25. package/package.json +1 -1
  26. package/packages/pi-agent-core/dist/agent.d.ts +19 -0
  27. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  28. package/packages/pi-agent-core/dist/agent.js +16 -0
  29. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  30. package/packages/pi-agent-core/src/agent.ts +32 -2
  31. package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts +34 -1
  32. package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
  33. package/packages/pi-ai/dist/providers/openai-codex-responses.js +32 -4
  34. package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  35. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +127 -16
  36. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -1
  37. package/packages/pi-ai/dist/providers/openai-responses.d.ts +8 -1
  38. package/packages/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
  39. package/packages/pi-ai/dist/providers/openai-responses.fast-mode.test.d.ts +2 -0
  40. package/packages/pi-ai/dist/providers/openai-responses.fast-mode.test.d.ts.map +1 -0
  41. package/packages/pi-ai/dist/providers/openai-responses.fast-mode.test.js +67 -0
  42. package/packages/pi-ai/dist/providers/openai-responses.fast-mode.test.js.map +1 -0
  43. package/packages/pi-ai/dist/providers/openai-responses.js +21 -3
  44. package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
  45. package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  46. package/packages/pi-ai/dist/providers/simple-options.js +2 -0
  47. package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
  48. package/packages/pi-ai/dist/types.d.ts +5 -0
  49. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  50. package/packages/pi-ai/dist/types.js.map +1 -1
  51. package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +143 -20
  52. package/packages/pi-ai/src/providers/openai-codex-responses.ts +47 -4
  53. package/packages/pi-ai/src/providers/openai-responses.fast-mode.test.ts +73 -0
  54. package/packages/pi-ai/src/providers/openai-responses.ts +26 -3
  55. package/packages/pi-ai/src/providers/simple-options.ts +2 -0
  56. package/packages/pi-ai/src/types.ts +5 -0
  57. package/packages/pi-coding-agent/dist/core/keybindings.d.ts +1 -1
  58. package/packages/pi-coding-agent/dist/core/keybindings.d.ts.map +1 -1
  59. package/packages/pi-coding-agent/dist/core/keybindings.js +2 -0
  60. package/packages/pi-coding-agent/dist/core/keybindings.js.map +1 -1
  61. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  62. package/packages/pi-coding-agent/dist/core/sdk.js +4 -2
  63. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  64. package/packages/pi-coding-agent/dist/core/settings-manager.collapse-tool-calls.test.d.ts +2 -0
  65. package/packages/pi-coding-agent/dist/core/settings-manager.collapse-tool-calls.test.d.ts.map +1 -0
  66. package/packages/pi-coding-agent/dist/core/settings-manager.collapse-tool-calls.test.js +35 -0
  67. package/packages/pi-coding-agent/dist/core/settings-manager.collapse-tool-calls.test.js.map +1 -0
  68. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +12 -0
  69. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  70. package/packages/pi-coding-agent/dist/core/settings-manager.fast-mode.test.d.ts +2 -0
  71. package/packages/pi-coding-agent/dist/core/settings-manager.fast-mode.test.d.ts.map +1 -0
  72. package/packages/pi-coding-agent/dist/core/settings-manager.fast-mode.test.js +35 -0
  73. package/packages/pi-coding-agent/dist/core/settings-manager.fast-mode.test.js.map +1 -0
  74. package/packages/pi-coding-agent/dist/core/settings-manager.js +24 -0
  75. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  76. package/packages/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
  77. package/packages/pi-coding-agent/dist/core/slash-commands.js +1 -0
  78. package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
  79. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  80. package/packages/pi-coding-agent/dist/core/system-prompt.js +6 -1
  81. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  82. package/packages/pi-coding-agent/dist/core/tool-priority.d.ts +4 -0
  83. package/packages/pi-coding-agent/dist/core/tool-priority.d.ts.map +1 -0
  84. package/packages/pi-coding-agent/dist/core/tool-priority.js +18 -0
  85. package/packages/pi-coding-agent/dist/core/tool-priority.js.map +1 -0
  86. package/packages/pi-coding-agent/dist/core/tool-priority.test.d.ts +2 -0
  87. package/packages/pi-coding-agent/dist/core/tool-priority.test.d.ts.map +1 -0
  88. package/packages/pi-coding-agent/dist/core/tool-priority.test.js +27 -0
  89. package/packages/pi-coding-agent/dist/core/tool-priority.test.js.map +1 -0
  90. package/packages/pi-coding-agent/dist/core/tools/edit-diff.d.ts +5 -0
  91. package/packages/pi-coding-agent/dist/core/tools/edit-diff.d.ts.map +1 -1
  92. package/packages/pi-coding-agent/dist/core/tools/edit-diff.js +21 -0
  93. package/packages/pi-coding-agent/dist/core/tools/edit-diff.js.map +1 -1
  94. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js +16 -1
  95. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js.map +1 -1
  96. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-summary-line.test.d.ts +2 -0
  97. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-summary-line.test.d.ts.map +1 -0
  98. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-summary-line.test.js +34 -0
  99. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-summary-line.test.js.map +1 -0
  100. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.d.ts +45 -0
  101. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.d.ts.map +1 -0
  102. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.js +314 -0
  103. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.js.map +1 -0
  104. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.test.d.ts +2 -0
  105. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.test.d.ts.map +1 -0
  106. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.test.js +122 -0
  107. package/packages/pi-coding-agent/dist/modes/interactive/components/btw-overlay.test.js.map +1 -0
  108. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.d.ts +7 -5
  109. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.d.ts.map +1 -1
  110. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js +86 -28
  111. package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js.map +1 -1
  112. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts +4 -0
  113. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  114. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +23 -10
  115. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  116. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +8 -0
  117. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  118. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +52 -6
  119. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
  120. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +19 -0
  121. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  122. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +127 -14
  123. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  124. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.d.ts +14 -0
  125. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.d.ts.map +1 -0
  126. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.js +93 -0
  127. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-summary-line.js.map +1 -0
  128. package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.d.ts +2 -0
  129. package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.d.ts.map +1 -0
  130. package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.js +328 -0
  131. package/packages/pi-coding-agent/dist/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.js.map +1 -0
  132. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  133. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +123 -0
  134. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  135. package/packages/pi-coding-agent/dist/modes/interactive/controllers/extension-ui-controller.js +1 -1
  136. package/packages/pi-coding-agent/dist/modes/interactive/controllers/extension-ui-controller.js.map +1 -1
  137. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  138. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +7 -0
  139. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  140. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +4 -0
  141. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  142. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  143. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +9 -1
  144. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  145. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +103 -23
  146. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  147. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
  148. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +41 -0
  149. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
  150. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +4 -4
  151. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  152. package/packages/pi-coding-agent/package.json +1 -1
  153. package/packages/pi-coding-agent/src/core/keybindings.ts +4 -1
  154. package/packages/pi-coding-agent/src/core/sdk.ts +4 -2
  155. package/packages/pi-coding-agent/src/core/settings-manager.collapse-tool-calls.test.ts +46 -0
  156. package/packages/pi-coding-agent/src/core/settings-manager.fast-mode.test.ts +46 -0
  157. package/packages/pi-coding-agent/src/core/settings-manager.ts +36 -0
  158. package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -0
  159. package/packages/pi-coding-agent/src/core/system-prompt.ts +6 -1
  160. package/packages/pi-coding-agent/src/core/tool-priority.test.ts +30 -0
  161. package/packages/pi-coding-agent/src/core/tool-priority.ts +17 -0
  162. package/packages/pi-coding-agent/src/core/tools/edit-diff.test.ts +20 -0
  163. package/packages/pi-coding-agent/src/core/tools/edit-diff.ts +26 -0
  164. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-summary-line.test.ts +41 -0
  165. package/packages/pi-coding-agent/src/modes/interactive/components/btw-overlay.test.ts +172 -0
  166. package/packages/pi-coding-agent/src/modes/interactive/components/btw-overlay.ts +402 -0
  167. package/packages/pi-coding-agent/src/modes/interactive/components/diff.ts +105 -28
  168. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +21 -6
  169. package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +63 -6
  170. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +1262 -1138
  171. package/packages/pi-coding-agent/src/modes/interactive/components/tool-summary-line.ts +120 -0
  172. package/packages/pi-coding-agent/src/modes/interactive/controllers/__tests__/chat-controller.collapsed-tool-summary.test.ts +396 -0
  173. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +530 -398
  174. package/packages/pi-coding-agent/src/modes/interactive/controllers/extension-ui-controller.ts +1 -1
  175. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +7 -0
  176. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +4 -0
  177. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +109 -23
  178. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +60 -1
  179. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +4 -4
  180. package/packages/pi-tui/dist/components/editor.js +3 -3
  181. package/packages/pi-tui/dist/components/editor.js.map +1 -1
  182. package/packages/pi-tui/src/components/editor.ts +3 -3
  183. package/pkg/dist/modes/interactive/theme/themes.js +4 -4
  184. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  185. package/pkg/package.json +1 -1
  186. package/src/resources/extensions/browser-tools/tools/codegen.ts +5 -5
  187. package/src/resources/extensions/browser-tools/tools/navigation.ts +118 -196
  188. package/src/resources/extensions/browser-tools/tools/network-mock.ts +114 -205
  189. package/src/resources/extensions/browser-tools/tools/pages.ts +183 -237
  190. package/src/resources/extensions/browser-tools/tools/refs.ts +193 -507
  191. package/src/resources/extensions/browser-tools/tools/session.ts +182 -321
  192. package/src/resources/extensions/browser-tools/tools/state-persistence.ts +94 -172
  193. package/src/resources/extensions/browser-tools/utils.ts +1 -1
  194. package/src/resources/extensions/cache-timer/index.ts +3 -2
  195. package/src/resources/extensions/slash-commands/extension-manifest.json +2 -2
  196. package/src/resources/extensions/slash-commands/fast.ts +89 -0
  197. package/src/resources/extensions/slash-commands/index.ts +2 -0
  198. package/src/resources/extensions/slash-commands/plan.ts +42 -12
  199. package/src/resources/extensions/subagent/background-job-manager.ts +28 -0
  200. package/src/resources/extensions/subagent/in-process-runner.ts +534 -0
  201. package/src/resources/extensions/subagent/index.ts +489 -799
  202. package/src/resources/extensions/subagent/legacy-runner.ts +607 -0
  203. package/src/resources/extensions/voice/index.ts +308 -238
  204. package/src/resources/extensions/voice/push-to-talk.ts +42 -0
  205. package/src/resources/extensions/voice/tests/push-to-talk.test.ts +109 -0
@@ -0,0 +1,387 @@
1
+ import { createAgentSession, getAgentDir, SessionManager } from "@gsd/pi-coding-agent";
2
+ import { resolveConfiguredSubagentModel } from "./configured-model.js";
3
+ import { resolveSubagentModel } from "./model-resolution.js";
4
+ import { readBudgetSubagentModelFromSettings } from "./legacy-runner.js";
5
+ import { loadEffectivePreferences } from "../shared/preferences.js";
6
+ const MAX_AGENT_DURATION_MS = 30 * 60 * 1000;
7
+ export const MAX_IN_PROCESS_SUBAGENT_DEPTH = 3;
8
+ export const MAX_ACTIVE_DESCENDANTS = 8;
9
+ const NESTED_EXTENSION_TOOL_ALLOWLIST = new Set([
10
+ "subagent",
11
+ "await_subagent",
12
+ "bg_shell",
13
+ "fetch_page",
14
+ "resolve_library",
15
+ "get_library_docs",
16
+ "tool_search",
17
+ "tool_enable",
18
+ "Skill",
19
+ ]);
20
+ const parentSessionIdByChildSessionId = new Map();
21
+ const childSessionIdsByParentSessionId = new Map();
22
+ const handleBySessionId = new Map();
23
+ let activeDescendantCount = 0;
24
+ function getFinalOutput(messages) {
25
+ for (let i = messages.length - 1; i >= 0; i--) {
26
+ const msg = messages[i];
27
+ if (msg.role === "assistant") {
28
+ for (const part of msg.content) {
29
+ if (part.type === "text")
30
+ return part.text;
31
+ }
32
+ }
33
+ }
34
+ return "";
35
+ }
36
+ function toErrorString(error) {
37
+ return error instanceof Error ? error.message : String(error);
38
+ }
39
+ function createUnknownAgentResult(agents, agentName, task, step, parentSessionFile) {
40
+ const available = agents.map((a) => `"${a.name}"`).join(", ") || "none";
41
+ return {
42
+ agent: agentName,
43
+ agentSource: "unknown",
44
+ task,
45
+ exitCode: 1,
46
+ messages: [],
47
+ stderr: `Unknown agent: "${agentName}". Available agents: ${available}.`,
48
+ usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, contextTokens: 0, turns: 0 },
49
+ step,
50
+ parentSessionFile,
51
+ };
52
+ }
53
+ function createResolvedHandle(result) {
54
+ const resultPromise = Promise.resolve(result);
55
+ const handle = {
56
+ result: resultPromise,
57
+ isBusy: () => false,
58
+ prompt: async () => undefined,
59
+ steer: async () => undefined,
60
+ followUp: async () => undefined,
61
+ abort: () => undefined,
62
+ dispose: () => undefined,
63
+ };
64
+ return { handle, currentResult: result, resultPromise };
65
+ }
66
+ function reserveDescendantSlot(depth) {
67
+ if (depth <= 1)
68
+ return () => undefined;
69
+ if (activeDescendantCount >= MAX_ACTIVE_DESCENDANTS)
70
+ return null;
71
+ activeDescendantCount += 1;
72
+ let released = false;
73
+ return () => {
74
+ if (released)
75
+ return;
76
+ released = true;
77
+ activeDescendantCount = Math.max(0, activeDescendantCount - 1);
78
+ };
79
+ }
80
+ function linkParentChildSession(parentSessionId, childSessionId) {
81
+ parentSessionIdByChildSessionId.set(childSessionId, parentSessionId);
82
+ const children = childSessionIdsByParentSessionId.get(parentSessionId) ?? new Set();
83
+ children.add(childSessionId);
84
+ childSessionIdsByParentSessionId.set(parentSessionId, children);
85
+ }
86
+ function unlinkSessionFromParent(sessionId) {
87
+ const parentSessionId = parentSessionIdByChildSessionId.get(sessionId);
88
+ if (!parentSessionId)
89
+ return;
90
+ parentSessionIdByChildSessionId.delete(sessionId);
91
+ const siblings = childSessionIdsByParentSessionId.get(parentSessionId);
92
+ if (!siblings)
93
+ return;
94
+ siblings.delete(sessionId);
95
+ if (siblings.size === 0) {
96
+ childSessionIdsByParentSessionId.delete(parentSessionId);
97
+ }
98
+ }
99
+ function abortDescendantTree(sessionId, visited = new Set()) {
100
+ if (visited.has(sessionId))
101
+ return;
102
+ visited.add(sessionId);
103
+ const descendants = childSessionIdsByParentSessionId.get(sessionId);
104
+ if (!descendants || descendants.size === 0)
105
+ return;
106
+ for (const childSessionId of descendants) {
107
+ handleBySessionId.get(childSessionId)?.abort();
108
+ abortDescendantTree(childSessionId, visited);
109
+ }
110
+ }
111
+ function resolveRequestedToolNames(agent, defaultActiveToolNames) {
112
+ const requested = agent.tools && agent.tools.length > 0 ? agent.tools : defaultActiveToolNames;
113
+ return [...new Set(requested)];
114
+ }
115
+ function applyNestedExtensionToolPolicy(toolNames, extensionToolNames, nestingDepth) {
116
+ if (nestingDepth <= 1) {
117
+ return { activeToolNames: toolNames, droppedTools: [] };
118
+ }
119
+ const activeToolNames = [];
120
+ const droppedTools = [];
121
+ for (const toolName of toolNames) {
122
+ if (!extensionToolNames.has(toolName)) {
123
+ activeToolNames.push(toolName);
124
+ continue;
125
+ }
126
+ if (NESTED_EXTENSION_TOOL_ALLOWLIST.has(toolName)) {
127
+ activeToolNames.push(toolName);
128
+ }
129
+ else {
130
+ droppedTools.push(toolName);
131
+ }
132
+ }
133
+ return { activeToolNames, droppedTools };
134
+ }
135
+ export async function startInProcessSingleAgent(defaultCwd, agents, agentName, task, cwd, step, modelOverride, parentModel, signal, onUpdate, makeDetails, parentSessionFile, depth, parentSessionId, ancestry, onSubagentEvent) {
136
+ const agent = agents.find((candidate) => candidate.name === agentName);
137
+ if (!agent) {
138
+ return createResolvedHandle(createUnknownAgentResult(agents, agentName, task, step, parentSessionFile));
139
+ }
140
+ const nestingDepth = depth ?? 1;
141
+ if (nestingDepth > MAX_IN_PROCESS_SUBAGENT_DEPTH) {
142
+ return createResolvedHandle({
143
+ agent: agentName,
144
+ agentSource: agent.source,
145
+ task,
146
+ exitCode: 1,
147
+ messages: [],
148
+ stderr: `Max subagent depth (${MAX_IN_PROCESS_SUBAGENT_DEPTH}) exceeded.`,
149
+ usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, contextTokens: 0, turns: 0 },
150
+ step,
151
+ parentSessionFile,
152
+ });
153
+ }
154
+ const parentAgentName = ancestry && ancestry.length > 0 ? ancestry[ancestry.length - 1] : undefined;
155
+ if (parentAgentName && parentAgentName === agentName) {
156
+ return createResolvedHandle({
157
+ agent: agentName,
158
+ agentSource: agent.source,
159
+ task,
160
+ exitCode: 1,
161
+ messages: [],
162
+ stderr: `Subagent "${agentName}" cannot spawn another subagent with the same name as itself.`,
163
+ usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, contextTokens: 0, turns: 0 },
164
+ step,
165
+ parentSessionFile,
166
+ });
167
+ }
168
+ const releaseDescendantSlot = reserveDescendantSlot(nestingDepth);
169
+ if (nestingDepth > 1 && !releaseDescendantSlot) {
170
+ return createResolvedHandle({
171
+ agent: agentName,
172
+ agentSource: agent.source,
173
+ task,
174
+ exitCode: 1,
175
+ messages: [],
176
+ stderr: `Maximum active descendant subagents (${MAX_ACTIVE_DESCENDANTS}) reached. Wait for running descendants to finish or cancel one before spawning more.`,
177
+ usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, contextTokens: 0, turns: 0 },
178
+ step,
179
+ parentSessionFile,
180
+ });
181
+ }
182
+ const releaseDescendantSlotOnce = (() => {
183
+ let released = false;
184
+ return () => {
185
+ if (released)
186
+ return;
187
+ released = true;
188
+ releaseDescendantSlot?.();
189
+ };
190
+ })();
191
+ const preferences = loadEffectivePreferences()?.preferences;
192
+ const settingsBudgetModel = readBudgetSubagentModelFromSettings();
193
+ const resolvedModel = resolveConfiguredSubagentModel(agent, preferences, settingsBudgetModel);
194
+ const inferredModel = resolveSubagentModel({ name: agent.name, model: resolvedModel }, { overrideModel: modelOverride, parentModel });
195
+ const currentResult = {
196
+ agent: agentName,
197
+ agentSource: agent.source,
198
+ task,
199
+ exitCode: 0,
200
+ messages: [],
201
+ stderr: "",
202
+ usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, contextTokens: 0, turns: 0 },
203
+ model: inferredModel,
204
+ step,
205
+ parentSessionFile,
206
+ };
207
+ const emitUpdate = () => {
208
+ if (!onUpdate)
209
+ return;
210
+ onUpdate({
211
+ content: [{ type: "text", text: getFinalOutput(currentResult.messages) || "(running...)" }],
212
+ details: makeDetails([currentResult]),
213
+ });
214
+ };
215
+ const effectiveCwd = cwd ?? defaultCwd;
216
+ const sessionManager = SessionManager.inMemory(effectiveCwd);
217
+ let session;
218
+ try {
219
+ const created = await createAgentSession({
220
+ cwd: effectiveCwd,
221
+ agentDir: getAgentDir(),
222
+ sessionManager,
223
+ });
224
+ session = created.session;
225
+ await session.bindExtensions({});
226
+ }
227
+ catch (error) {
228
+ releaseDescendantSlotOnce();
229
+ currentResult.exitCode = 1;
230
+ currentResult.stderr = `Failed to initialize in-process subagent session: ${toErrorString(error)}`;
231
+ return createResolvedHandle(currentResult);
232
+ }
233
+ if (inferredModel) {
234
+ const [provider, modelId] = inferredModel.split("/");
235
+ if (provider && modelId) {
236
+ const model = session.modelRegistry.find(provider, modelId);
237
+ if (!model) {
238
+ session.dispose();
239
+ releaseDescendantSlotOnce();
240
+ currentResult.exitCode = 1;
241
+ currentResult.stderr = `Unable to resolve model ${inferredModel} for in-process subagent.`;
242
+ return createResolvedHandle(currentResult);
243
+ }
244
+ await session.setModel(model);
245
+ currentResult.model = `${model.provider}/${model.id}`;
246
+ }
247
+ }
248
+ const defaultActiveToolNames = session.getActiveToolNames();
249
+ const requestedToolNames = resolveRequestedToolNames(agent, defaultActiveToolNames);
250
+ const extensionToolNames = new Set(session.extensionRunner?.getAllRegisteredTools().map((registered) => registered.definition.name) ?? []);
251
+ const { activeToolNames: resolvedActiveToolNames, droppedTools } = applyNestedExtensionToolPolicy(requestedToolNames, extensionToolNames, nestingDepth);
252
+ session.setActiveToolsByName(resolvedActiveToolNames);
253
+ const ancestryChain = ancestry && ancestry.length > 0 ? ancestry.join(" -> ") : "root";
254
+ const nestedPolicyLine = droppedTools.length > 0
255
+ ? `Nested safety policy disabled extension tools: ${droppedTools.join(", ")}.`
256
+ : "";
257
+ const antiRecursionPrompt = [
258
+ `You are already the ${agentName} subagent for this session.`,
259
+ "Do not spawn or delegate to another subagent with the same name as yourself.",
260
+ `If the user asks you to continue ${agentName} work, do that work directly in this session.`,
261
+ `Original delegated task: ${task}`,
262
+ `Current subagent depth: ${nestingDepth}/${MAX_IN_PROCESS_SUBAGENT_DEPTH}.`,
263
+ `Subagent ancestry: ${ancestryChain}.`,
264
+ nestedPolicyLine,
265
+ ].filter(Boolean).join("\n");
266
+ const appendedParts = [antiRecursionPrompt, agent.systemPrompt.trim()].filter((part) => part.length > 0);
267
+ if (appendedParts.length > 0) {
268
+ const appendedPrompt = `${session.systemPrompt}\n\n${appendedParts.join("\n\n")}`;
269
+ session.agent.setSystemPrompt(appendedPrompt);
270
+ }
271
+ let completed = false;
272
+ let disposed = false;
273
+ const unsubscribe = session.subscribe((event) => {
274
+ onSubagentEvent?.(event, currentResult);
275
+ if (event?.type !== "message_end" || !event.message)
276
+ return;
277
+ const message = event.message;
278
+ currentResult.messages.push(message);
279
+ if (message.role === "assistant") {
280
+ currentResult.usage.turns++;
281
+ const usage = message.usage;
282
+ if (usage) {
283
+ currentResult.usage.input += usage.input || 0;
284
+ currentResult.usage.output += usage.output || 0;
285
+ currentResult.usage.cacheRead += usage.cacheRead || 0;
286
+ currentResult.usage.cacheWrite += usage.cacheWrite || 0;
287
+ currentResult.usage.cost += usage.cost?.total || 0;
288
+ currentResult.usage.contextTokens = usage.totalTokens || 0;
289
+ }
290
+ if (message.model)
291
+ currentResult.model = message.model;
292
+ if (message.stopReason)
293
+ currentResult.stopReason = message.stopReason;
294
+ if (message.errorMessage)
295
+ currentResult.errorMessage = message.errorMessage;
296
+ }
297
+ emitUpdate();
298
+ });
299
+ const sessionId = session.sessionId;
300
+ const dispose = () => {
301
+ if (disposed)
302
+ return;
303
+ disposed = true;
304
+ if (sessionId) {
305
+ handleBySessionId.delete(sessionId);
306
+ unlinkSessionFromParent(sessionId);
307
+ }
308
+ releaseDescendantSlotOnce();
309
+ unsubscribe();
310
+ session.dispose();
311
+ };
312
+ const handle = {
313
+ result: Promise.resolve(currentResult),
314
+ sessionId,
315
+ isBusy: () => session.isStreaming,
316
+ prompt: (message, images) => session.prompt(message, { images }),
317
+ steer: (message, images) => session.steer(message, images),
318
+ followUp: (message, images) => session.followUp(message, images),
319
+ abort: () => {
320
+ if (sessionId) {
321
+ abortDescendantTree(sessionId);
322
+ }
323
+ void session.abort();
324
+ },
325
+ dispose,
326
+ };
327
+ if (sessionId) {
328
+ handleBySessionId.set(sessionId, handle);
329
+ if (parentSessionId) {
330
+ linkParentChildSession(parentSessionId, sessionId);
331
+ }
332
+ }
333
+ let timeoutTimer;
334
+ const timeoutPromise = new Promise((_, reject) => {
335
+ timeoutTimer = setTimeout(() => {
336
+ handle.abort();
337
+ reject(new Error(`In-process subagent timed out after ${MAX_AGENT_DURATION_MS}ms.`));
338
+ }, MAX_AGENT_DURATION_MS);
339
+ if (typeof timeoutTimer === "object" && "unref" in timeoutTimer)
340
+ timeoutTimer.unref();
341
+ });
342
+ const runPromise = (async () => {
343
+ if (signal?.aborted) {
344
+ handle.abort();
345
+ throw new Error("Subagent was aborted");
346
+ }
347
+ const onAbort = () => handle.abort();
348
+ signal?.addEventListener("abort", onAbort, { once: true });
349
+ try {
350
+ await session.prompt(task);
351
+ completed = true;
352
+ }
353
+ finally {
354
+ signal?.removeEventListener("abort", onAbort);
355
+ }
356
+ })();
357
+ const resultPromise = (async () => {
358
+ try {
359
+ await Promise.race([runPromise, timeoutPromise]);
360
+ }
361
+ catch (error) {
362
+ currentResult.exitCode = 1;
363
+ currentResult.stderr = toErrorString(error);
364
+ if (signal?.aborted)
365
+ currentResult.stopReason = "aborted";
366
+ }
367
+ finally {
368
+ if (timeoutTimer)
369
+ clearTimeout(timeoutTimer);
370
+ if (!completed && signal?.aborted) {
371
+ currentResult.stopReason = "aborted";
372
+ }
373
+ dispose();
374
+ }
375
+ return currentResult;
376
+ })();
377
+ handle.result = resultPromise;
378
+ return {
379
+ handle,
380
+ currentResult,
381
+ resultPromise,
382
+ };
383
+ }
384
+ export async function runInProcessSingleAgent(defaultCwd, agents, agentName, task, cwd, step, modelOverride, parentModel, signal, onUpdate, makeDetails, parentSessionFile, depth, parentSessionId, ancestry, onSubagentEvent) {
385
+ const started = await startInProcessSingleAgent(defaultCwd, agents, agentName, task, cwd, step, modelOverride, parentModel, signal, onUpdate, makeDetails, parentSessionFile, depth, parentSessionId, ancestry, onSubagentEvent);
386
+ return started.resultPromise;
387
+ }