@beeos-ai/device-agent 0.15.0 → 0.16.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 (240) hide show
  1. package/README.md +35 -0
  2. package/dist/adapters/agent-gateway-client.d.ts +6 -68
  3. package/dist/adapters/agent-gateway-client.js +7 -67
  4. package/dist/adapters/agent-gateway-client.js.map +1 -1
  5. package/dist/adapters/device-compat.d.ts +1 -2
  6. package/dist/adapters/device-compat.js +2 -52
  7. package/dist/adapters/device-compat.js.map +1 -1
  8. package/dist/agent-runtime/action-guard.js +92 -17
  9. package/dist/agent-runtime/action-guard.js.map +1 -1
  10. package/dist/agent-runtime/adapters/base.d.ts +13 -9
  11. package/dist/agent-runtime/adapters/base.js.map +1 -1
  12. package/dist/agent-runtime/adapters/general-flash.d.ts +3 -3
  13. package/dist/agent-runtime/adapters/general-flash.js +2 -2
  14. package/dist/agent-runtime/adapters/general-flash.js.map +1 -1
  15. package/dist/agent-runtime/adapters/native-tools.d.ts +56 -0
  16. package/dist/agent-runtime/adapters/native-tools.js +416 -0
  17. package/dist/agent-runtime/adapters/native-tools.js.map +1 -0
  18. package/dist/agent-runtime/adapters/openai.d.ts +1 -2
  19. package/dist/agent-runtime/adapters/openai.js +5 -5
  20. package/dist/agent-runtime/adapters/openai.js.map +1 -1
  21. package/dist/agent-runtime/adapters/pro.d.ts +7 -37
  22. package/dist/agent-runtime/adapters/pro.js +7 -249
  23. package/dist/agent-runtime/adapters/pro.js.map +1 -1
  24. package/dist/agent-runtime/advanced/app-card.js +9 -2
  25. package/dist/agent-runtime/advanced/app-card.js.map +1 -1
  26. package/dist/agent-runtime/advanced/subgoal-verifier.d.ts +1 -0
  27. package/dist/agent-runtime/advanced/subgoal-verifier.js +30 -36
  28. package/dist/agent-runtime/advanced/subgoal-verifier.js.map +1 -1
  29. package/dist/agent-runtime/advanced/task-state.js +4 -9
  30. package/dist/agent-runtime/advanced/task-state.js.map +1 -1
  31. package/dist/agent-runtime/agent-runner.d.ts +2 -11
  32. package/dist/agent-runtime/agent-runner.js +69 -34
  33. package/dist/agent-runtime/agent-runner.js.map +1 -1
  34. package/dist/agent-runtime/core.d.ts +24 -46
  35. package/dist/agent-runtime/core.js +161 -228
  36. package/dist/agent-runtime/core.js.map +1 -1
  37. package/dist/agent-runtime/execution-checks.d.ts +40 -0
  38. package/dist/agent-runtime/execution-checks.js +133 -0
  39. package/dist/agent-runtime/execution-checks.js.map +1 -0
  40. package/dist/agent-runtime/execution-mode.d.ts +1 -8
  41. package/dist/agent-runtime/execution-mode.js +10 -30
  42. package/dist/agent-runtime/execution-mode.js.map +1 -1
  43. package/dist/agent-runtime/feedback.d.ts +4 -28
  44. package/dist/agent-runtime/feedback.js +4 -26
  45. package/dist/agent-runtime/feedback.js.map +1 -1
  46. package/dist/agent-runtime/form-prerequisites.d.ts +3 -0
  47. package/dist/agent-runtime/form-prerequisites.js +52 -0
  48. package/dist/agent-runtime/form-prerequisites.js.map +1 -0
  49. package/dist/agent-runtime/index.d.ts +2 -8
  50. package/dist/agent-runtime/index.js +2 -8
  51. package/dist/agent-runtime/index.js.map +1 -1
  52. package/dist/agent-runtime/{modes/orchestrator → knowledge}/app-guide.d.ts +1 -1
  53. package/dist/agent-runtime/{modes/orchestrator → knowledge}/app-guide.js +1 -1
  54. package/dist/agent-runtime/knowledge/app-guide.js.map +1 -0
  55. package/dist/agent-runtime/models/base.d.ts +3 -1
  56. package/dist/agent-runtime/models/client.js +30 -9
  57. package/dist/agent-runtime/models/client.js.map +1 -1
  58. package/dist/agent-runtime/models/reasoning.d.ts +10 -0
  59. package/dist/agent-runtime/models/reasoning.js +29 -0
  60. package/dist/agent-runtime/models/reasoning.js.map +1 -0
  61. package/dist/agent-runtime/models/runtime-registry.d.ts +2 -1
  62. package/dist/agent-runtime/models/runtime-registry.js +4 -2
  63. package/dist/agent-runtime/models/runtime-registry.js.map +1 -1
  64. package/dist/agent-runtime/models/vlm/autoglm.js +6 -2
  65. package/dist/agent-runtime/models/vlm/autoglm.js.map +1 -1
  66. package/dist/agent-runtime/models/vlm/base.js +1 -12
  67. package/dist/agent-runtime/models/vlm/base.js.map +1 -1
  68. package/dist/agent-runtime/models/vlm/index.d.ts +0 -4
  69. package/dist/agent-runtime/models/vlm/index.js +0 -4
  70. package/dist/agent-runtime/models/vlm/index.js.map +1 -1
  71. package/dist/agent-runtime/modes/hybrid/index.d.ts +2 -12
  72. package/dist/agent-runtime/modes/hybrid/index.js +10 -27
  73. package/dist/agent-runtime/modes/hybrid/index.js.map +1 -1
  74. package/dist/agent-runtime/modes/hybrid/planner/base.d.ts +4 -44
  75. package/dist/agent-runtime/modes/hybrid/planner/base.js +3 -21
  76. package/dist/agent-runtime/modes/hybrid/planner/base.js.map +1 -1
  77. package/dist/agent-runtime/modes/hybrid/planner/llm-planner.d.ts +1 -1
  78. package/dist/agent-runtime/modes/hybrid/planner/llm-planner.js +9 -6
  79. package/dist/agent-runtime/modes/hybrid/planner/llm-planner.js.map +1 -1
  80. package/dist/agent-runtime/modes/hybrid/planner/prompts.d.ts +1 -17
  81. package/dist/agent-runtime/modes/hybrid/planner/prompts.js +65 -160
  82. package/dist/agent-runtime/modes/hybrid/planner/prompts.js.map +1 -1
  83. package/dist/agent-runtime/plan-executor.d.ts +13 -14
  84. package/dist/agent-runtime/plan-executor.js +236 -122
  85. package/dist/agent-runtime/plan-executor.js.map +1 -1
  86. package/dist/agent-runtime/pro-memory.js +1 -1
  87. package/dist/agent-runtime/pro-memory.js.map +1 -1
  88. package/dist/agent-runtime/pro-operator.js +8 -2
  89. package/dist/agent-runtime/pro-operator.js.map +1 -1
  90. package/dist/agent-runtime/pro-perception.d.ts +1 -0
  91. package/dist/agent-runtime/pro-perception.js +4 -2
  92. package/dist/agent-runtime/pro-perception.js.map +1 -1
  93. package/dist/agent-runtime/pro-target-check.d.ts +2 -2
  94. package/dist/agent-runtime/pro-target-check.js +102 -17
  95. package/dist/agent-runtime/pro-target-check.js.map +1 -1
  96. package/dist/agent-runtime/prompts/operator.d.ts +2 -0
  97. package/dist/agent-runtime/prompts/operator.js +69 -0
  98. package/dist/agent-runtime/prompts/operator.js.map +1 -0
  99. package/dist/agent-runtime/prompts/verification.d.ts +2 -0
  100. package/dist/agent-runtime/prompts/verification.js +52 -0
  101. package/dist/agent-runtime/prompts/verification.js.map +1 -0
  102. package/dist/agent-runtime/skills/replay.d.ts +4 -14
  103. package/dist/agent-runtime/skills/replay.js +46 -27
  104. package/dist/agent-runtime/skills/replay.js.map +1 -1
  105. package/dist/agent-runtime/tool-batch.d.ts +10 -0
  106. package/dist/agent-runtime/tool-batch.js +51 -0
  107. package/dist/agent-runtime/tool-batch.js.map +1 -0
  108. package/dist/agent-runtime/visual-state.d.ts +2 -0
  109. package/dist/agent-runtime/visual-state.js +24 -0
  110. package/dist/agent-runtime/visual-state.js.map +1 -0
  111. package/dist/agent-runtime/vlm.d.ts +1 -1
  112. package/dist/agent-runtime/vlm.js +1 -1
  113. package/dist/api.js +3 -1
  114. package/dist/api.js.map +1 -1
  115. package/dist/app/agent-host.js +6 -2
  116. package/dist/app/agent-host.js.map +1 -1
  117. package/dist/app/multi-device-host.js +4 -5
  118. package/dist/app/multi-device-host.js.map +1 -1
  119. package/dist/app/session-manager.d.ts +3 -45
  120. package/dist/app/session-manager.js +8 -9
  121. package/dist/app/session-manager.js.map +1 -1
  122. package/dist/bootstrap.js +25 -84
  123. package/dist/bootstrap.js.map +1 -1
  124. package/dist/config/loader.js +12 -1
  125. package/dist/config/loader.js.map +1 -1
  126. package/dist/config/schema.d.ts +7 -2
  127. package/dist/config/schema.js +8 -5
  128. package/dist/config/schema.js.map +1 -1
  129. package/dist/core/abortable-read.d.ts +1 -0
  130. package/dist/core/abortable-read.js +24 -0
  131. package/dist/core/abortable-read.js.map +1 -0
  132. package/dist/device/ui-xml.d.ts +4 -0
  133. package/dist/device/ui-xml.js +35 -13
  134. package/dist/device/ui-xml.js.map +1 -1
  135. package/dist/fleet/adapters/process/node-process-manager.d.ts +2 -1
  136. package/dist/fleet/adapters/process/node-process-manager.js +11 -19
  137. package/dist/fleet/adapters/process/node-process-manager.js.map +1 -1
  138. package/dist/inbound/acp/handlers/models.js +11 -8
  139. package/dist/inbound/acp/handlers/models.js.map +1 -1
  140. package/dist/inbound/acp/handlers/session.d.ts +1 -4
  141. package/dist/inbound/acp/handlers/session.js +3 -6
  142. package/dist/inbound/acp/handlers/session.js.map +1 -1
  143. package/dist/inbound/bma/agent.d.ts +47 -0
  144. package/dist/inbound/bma/agent.js +130 -0
  145. package/dist/inbound/bma/agent.js.map +1 -0
  146. package/dist/inbound/bma/command.d.ts +15 -0
  147. package/dist/inbound/bma/command.js +98 -0
  148. package/dist/inbound/bma/command.js.map +1 -0
  149. package/dist/inbound/bma/model-proxy.d.ts +22 -0
  150. package/dist/inbound/bma/model-proxy.js +130 -0
  151. package/dist/inbound/bma/model-proxy.js.map +1 -0
  152. package/dist/inbound/cli/main.js +12 -2
  153. package/dist/inbound/cli/main.js.map +1 -1
  154. package/dist/inbound/cli/run-artifacts.js +16 -7
  155. package/dist/inbound/cli/run-artifacts.js.map +1 -1
  156. package/dist/inbound/cli/run-command.d.ts +7 -0
  157. package/dist/inbound/cli/run-command.js +37 -29
  158. package/dist/inbound/cli/run-command.js.map +1 -1
  159. package/dist/index.d.ts +1 -10
  160. package/dist/index.js +1 -6
  161. package/dist/index.js.map +1 -1
  162. package/dist/mcp-client/autospawn.d.ts +7 -9
  163. package/dist/mcp-client/autospawn.js +16 -12
  164. package/dist/mcp-client/autospawn.js.map +1 -1
  165. package/dist/mcp-client/client.d.ts +6 -3
  166. package/dist/mcp-client/client.js +31 -13
  167. package/dist/mcp-client/client.js.map +1 -1
  168. package/dist/mcp-client/runtime.d.ts +5 -2
  169. package/dist/plugins/agent-sync/index.d.ts +32 -17
  170. package/dist/plugins/agent-sync/index.js +223 -232
  171. package/dist/plugins/agent-sync/index.js.map +1 -1
  172. package/dist/plugins/message-bus/inbound.d.ts +0 -32
  173. package/dist/plugins/message-bus/inbound.js +3 -0
  174. package/dist/plugins/message-bus/inbound.js.map +1 -1
  175. package/dist/plugins/message-bus/ms-channel-notifier.d.ts +1 -0
  176. package/dist/plugins/message-bus/ms-channel-notifier.js +16 -8
  177. package/dist/plugins/message-bus/ms-channel-notifier.js.map +1 -1
  178. package/dist/plugins/native-chat/deadline.d.ts +2 -0
  179. package/dist/plugins/native-chat/deadline.js +16 -0
  180. package/dist/plugins/native-chat/deadline.js.map +1 -0
  181. package/dist/plugins/native-chat/index.d.ts +46 -0
  182. package/dist/plugins/native-chat/index.js +331 -0
  183. package/dist/plugins/native-chat/index.js.map +1 -0
  184. package/dist/plugins/native-chat/reply-stream.d.ts +50 -0
  185. package/dist/plugins/native-chat/reply-stream.js +81 -0
  186. package/dist/plugins/native-chat/reply-stream.js.map +1 -0
  187. package/dist/plugins/native-chat/session-notifier.d.ts +16 -0
  188. package/dist/plugins/native-chat/session-notifier.js +130 -0
  189. package/dist/plugins/native-chat/session-notifier.js.map +1 -0
  190. package/dist/ports/agent-core.d.ts +2 -0
  191. package/dist/ports/agent-host.d.ts +2 -0
  192. package/dist/ports/agent-host.js +0 -21
  193. package/dist/ports/agent-host.js.map +1 -1
  194. package/dist/ports/device.d.ts +0 -1
  195. package/dist/ports/device.js +0 -1
  196. package/dist/ports/device.js.map +1 -1
  197. package/dist/runtime-authority/device-prompt.gen.d.ts +54 -0
  198. package/dist/runtime-authority/device-prompt.gen.js +19 -0
  199. package/dist/runtime-authority/device-prompt.gen.js.map +1 -0
  200. package/dist/types.d.ts +10 -0
  201. package/dist/types.js +1 -0
  202. package/dist/types.js.map +1 -1
  203. package/package.json +7 -5
  204. package/dist/adapters/device-desktop.d.ts +0 -49
  205. package/dist/adapters/device-desktop.js +0 -132
  206. package/dist/adapters/device-desktop.js.map +0 -1
  207. package/dist/agent-runtime/factory.d.ts +0 -24
  208. package/dist/agent-runtime/factory.js +0 -25
  209. package/dist/agent-runtime/factory.js.map +0 -1
  210. package/dist/agent-runtime/models/vlm/guiowl.d.ts +0 -1
  211. package/dist/agent-runtime/models/vlm/guiowl.js +0 -249
  212. package/dist/agent-runtime/models/vlm/guiowl.js.map +0 -1
  213. package/dist/agent-runtime/models/vlm/maiui.d.ts +0 -1
  214. package/dist/agent-runtime/models/vlm/maiui.js +0 -142
  215. package/dist/agent-runtime/models/vlm/maiui.js.map +0 -1
  216. package/dist/agent-runtime/models/vlm/qwen38.d.ts +0 -1
  217. package/dist/agent-runtime/models/vlm/qwen38.js +0 -241
  218. package/dist/agent-runtime/models/vlm/qwen38.js.map +0 -1
  219. package/dist/agent-runtime/models/vlm/qwenvl.d.ts +0 -1
  220. package/dist/agent-runtime/models/vlm/qwenvl.js +0 -202
  221. package/dist/agent-runtime/models/vlm/qwenvl.js.map +0 -1
  222. package/dist/agent-runtime/modes/orchestrator/app-guide.js.map +0 -1
  223. package/dist/agent-runtime/modes/orchestrator/index.d.ts +0 -41
  224. package/dist/agent-runtime/modes/orchestrator/index.js +0 -218
  225. package/dist/agent-runtime/modes/orchestrator/index.js.map +0 -1
  226. package/dist/agent-runtime/modes/orchestrator/prompt.d.ts +0 -7
  227. package/dist/agent-runtime/modes/orchestrator/prompt.js +0 -53
  228. package/dist/agent-runtime/modes/orchestrator/prompt.js.map +0 -1
  229. package/dist/agent-runtime/reflection.d.ts +0 -100
  230. package/dist/agent-runtime/reflection.js +0 -241
  231. package/dist/agent-runtime/reflection.js.map +0 -1
  232. package/dist/agent-runtime/reflectors/action-reflector.d.ts +0 -97
  233. package/dist/agent-runtime/reflectors/action-reflector.js +0 -234
  234. package/dist/agent-runtime/reflectors/action-reflector.js.map +0 -1
  235. package/dist/agent-runtime/reflectors/policy.d.ts +0 -56
  236. package/dist/agent-runtime/reflectors/policy.js +0 -111
  237. package/dist/agent-runtime/reflectors/policy.js.map +0 -1
  238. package/dist/agent-runtime/reflectors/trajectory-reflector.d.ts +0 -93
  239. package/dist/agent-runtime/reflectors/trajectory-reflector.js +0 -224
  240. package/dist/agent-runtime/reflectors/trajectory-reflector.js.map +0 -1
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * agent-runtime/plan-executor — runs a structured Plan by spinning up
3
- * one `AgentLoop` per `PlanStep`.
3
+ * one `AgentLoop` per `PlanStep` for legacy callers. Pro instead executes
4
+ * the entire goal continuously, using plan steps only as guidance.
4
5
  *
5
6
  * This is the bridge between the *strategy* tier (`IPlanner`) and the
6
7
  * *act* tier (`AgentLoop` + `IModelAdapter` + `IMcpRuntime`):
@@ -49,6 +50,8 @@ const REPLAN_TERMINATORS = new Set([
49
50
  export class PlanExecutor {
50
51
  opts;
51
52
  deadline = Infinity;
53
+ signal;
54
+ progress;
52
55
  static DEFAULT_MAX_STEPS = 30;
53
56
  static DEFAULT_TIMEOUT_MS = 5 * 60 * 1000;
54
57
  static DEFAULT_MAX_REPLANS = 2;
@@ -56,12 +59,61 @@ export class PlanExecutor {
56
59
  this.opts = opts;
57
60
  }
58
61
  async run() {
62
+ const timeoutMs = this.opts.timeoutMs ?? PlanExecutor.DEFAULT_TIMEOUT_MS;
63
+ const budget = new AbortController();
64
+ this.deadline = Date.now() + timeoutMs;
65
+ this.signal = this.opts.signal ? AbortSignal.any([this.opts.signal, budget.signal]) : budget.signal;
66
+ const timer = setTimeout(() => budget.abort(new Error("Task deadline reached")), timeoutMs);
67
+ try {
68
+ const result = await this.runInternal();
69
+ this.progress = () => result;
70
+ this.signal.throwIfAborted();
71
+ return result;
72
+ }
73
+ catch (error) {
74
+ if (!this.signal.aborted)
75
+ throw error;
76
+ const cancelled = Boolean(this.opts.signal?.aborted);
77
+ return {
78
+ steps: 0, usage: { inputTokens: 0, outputTokens: 0 },
79
+ history: [], notes: [], plansEmitted: 0, replans: 0, reactFallbackUsed: false,
80
+ ...this.progress?.(),
81
+ ok: false,
82
+ finalText: cancelled ? "Task cancelled" : `plan executor exceeded ${timeoutMs}ms budget`,
83
+ terminator: cancelled ? "cancelled" : "timeout", cancelled,
84
+ };
85
+ }
86
+ finally {
87
+ clearTimeout(timer);
88
+ }
89
+ }
90
+ // Bound observation and supervisor waits, even if a provider ignores abort.
91
+ async bounded(operation) {
92
+ this.signal?.throwIfAborted();
93
+ const signal = this.signal;
94
+ let onAbort = () => { };
95
+ const interrupted = new Promise((_, reject) => {
96
+ onAbort = () => reject(signal.reason);
97
+ signal.addEventListener("abort", onAbort, { once: true });
98
+ });
99
+ try {
100
+ const result = await Promise.race([Promise.resolve().then(() => {
101
+ signal.throwIfAborted();
102
+ return operation();
103
+ }), interrupted]);
104
+ signal.throwIfAborted();
105
+ return result;
106
+ }
107
+ finally {
108
+ signal.removeEventListener("abort", onAbort);
109
+ }
110
+ }
111
+ async runInternal() {
59
112
  const maxSteps = this.opts.maxSteps ?? PlanExecutor.DEFAULT_MAX_STEPS;
60
113
  const timeoutMs = this.opts.timeoutMs ?? PlanExecutor.DEFAULT_TIMEOUT_MS;
61
114
  const maxReplans = this.opts.maxReplans ?? PlanExecutor.DEFAULT_MAX_REPLANS;
62
115
  const maxLocalRecoveries = this.opts.maxLocalRecoveries ?? 0;
63
- const deadline = Date.now() + timeoutMs;
64
- this.deadline = deadline;
116
+ const deadline = this.deadline;
65
117
  const reactFallback = this.opts.reactFallback ?? true;
66
118
  const usage = { inputTokens: 0, outputTokens: 0 };
67
119
  const history = [];
@@ -74,13 +126,9 @@ export class PlanExecutor {
74
126
  let pendingRecovery;
75
127
  let lastTerminator = "error";
76
128
  let lastFinalText = "";
77
- /**
78
- * Phase 2.2 / 2.3 — most recent non-`on_track` verdict from any inner
79
- * AgentLoop. Threaded into the next `PlanContext.trajectoryVerdict`
80
- * so the planner can pivot the plan rather than re-deriving the
81
- * failure mode.
82
- */
83
- let lastTrajectoryVerdict;
129
+ this.progress = () => ({ ok: false, finalText: lastFinalText, steps: stepsConsumed,
130
+ usage, history, notes, plansEmitted, replans, reactFallbackUsed,
131
+ terminator: lastTerminator, cancelled: false });
84
132
  /**
85
133
  * KISS hardening — append-only feedback ring across the whole plan
86
134
  * run. Each inner AgentLoop's `feedbackLog` is concatenated here
@@ -99,15 +147,17 @@ export class PlanExecutor {
99
147
  // ReAct loop so the user-visible task can still make progress.
100
148
  let firstPlanRes;
101
149
  try {
102
- firstPlanRes = await this.opts.planner.makePlan({
150
+ const observation = await this.snapshotForPlanner();
151
+ firstPlanRes = await this.bounded(() => this.opts.planner.makePlan({
103
152
  goal: this.opts.goal,
104
153
  history: [],
105
- observation: await this.snapshotForPlanner(),
154
+ observation,
106
155
  advancedKnowledge: this.opts.advancedKnowledge,
107
156
  advancedTaskState: advancedTaskState?.render(),
108
- }, { signal: this.opts.signal });
157
+ }, { signal: this.signal }));
109
158
  }
110
159
  catch (e) {
160
+ this.signal?.throwIfAborted();
111
161
  await this.fireError(`makePlan failed: ${errMsg(e)}`);
112
162
  if (reactFallback) {
113
163
  const planFbRemaining = deadline - Date.now();
@@ -138,11 +188,11 @@ export class PlanExecutor {
138
188
  observationMode: this.opts.observationMode,
139
189
  maxSteps: Math.max(1, maxSteps - stepsConsumed),
140
190
  timeoutMs: planFbRemaining,
141
- signal: this.opts.signal,
191
+ signal: this.signal,
142
192
  hooks: this.opts.hooks,
143
- reflector: this.opts.reflector,
193
+ executionChecks: this.opts.executionChecks,
144
194
  }).run();
145
- await this.verifyFallback(fb);
195
+ this.signal?.throwIfAborted();
146
196
  stepsConsumed += fb.steps;
147
197
  accumulateUsage(usage, fb.usage);
148
198
  history.push(...fb.history);
@@ -167,24 +217,13 @@ export class PlanExecutor {
167
217
  accumulateUsage(usage, firstPlanRes.usage);
168
218
  plansEmitted += 1;
169
219
  await this.firePlan(plan, /*isReplan*/ false, replans);
220
+ if (this.opts.advancedKnowledge && this.opts.adapter.nativeTools) {
221
+ return this.runContinuousPro(plan, usage, proMemory);
222
+ }
170
223
  // ── Main loop: walk the plan ───────────────────────────────────────
171
224
  let cur = 0;
172
225
  while (cur < plan.steps.length) {
173
- if (this.opts.signal?.aborted) {
174
- return this.finish({
175
- ok: false,
176
- finalText: "Task cancelled",
177
- stepsConsumed,
178
- usage,
179
- history,
180
- notes,
181
- plansEmitted,
182
- replans,
183
- reactFallbackUsed,
184
- terminator: "cancelled",
185
- cancelled: true,
186
- });
187
- }
226
+ this.signal?.throwIfAborted();
188
227
  if (Date.now() > deadline) {
189
228
  return this.finish({
190
229
  ok: false,
@@ -217,8 +256,13 @@ export class PlanExecutor {
217
256
  });
218
257
  }
219
258
  const step = plan.steps[cur];
220
- let subBudget = clamp(step.maxSteps ?? this.opts.perStepBudget ?? defaultPerStepBudget(plan.steps.length, maxSteps), 1, stepsLeft);
221
- let innerTask = formatStepAsTask(this.opts.goal, plan, cur, this.opts.advancedKnowledge, advancedTaskState?.render(notes));
259
+ let subBudget = clamp(
260
+ // Native Pro milestones can be entire forms. Their default budget is
261
+ // shared globally, not evenly divided across unrelated milestones.
262
+ step.maxSteps ?? this.opts.perStepBudget ??
263
+ (this.opts.advancedKnowledge && this.opts.adapter.nativeTools
264
+ ? stepsLeft : defaultPerStepBudget(plan.steps.length, maxSteps)), 1, stepsLeft);
265
+ let innerTask = formatStepAsTask(this.opts.goal, plan, cur, this.opts.advancedKnowledge, advancedTaskState?.render(notes), Boolean(this.opts.adapter.nativeTools));
222
266
  if (pendingRecovery) {
223
267
  innerTask += `\n# LOCAL RECOVERY\n${pendingRecovery}\n` +
224
268
  "Observe the current screen before acting. Repair only this sub-task: " +
@@ -255,6 +299,7 @@ export class PlanExecutor {
255
299
  }
256
300
  const result = await new AgentLoop({
257
301
  task: innerTask,
302
+ taskContext: { rootGoal: this.opts.goal, currentMilestone: step.description },
258
303
  proOperator: Boolean(this.opts.advancedKnowledge),
259
304
  proMemory,
260
305
  priorHistory: history,
@@ -264,16 +309,15 @@ export class PlanExecutor {
264
309
  observationMode: this.opts.observationMode,
265
310
  maxSteps: subBudget,
266
311
  timeoutMs: innerRemaining,
267
- signal: this.opts.signal,
312
+ signal: this.signal,
268
313
  hooks: this.opts.hooks,
269
- reflector: this.opts.reflector,
314
+ executionChecks: this.opts.executionChecks,
270
315
  }).run();
271
316
  stepsConsumed += result.steps;
272
317
  accumulateUsage(usage, result.usage);
273
318
  history.push(...result.history);
274
319
  notes.push(...result.notes);
275
- if (result.trajectoryVerdict)
276
- lastTrajectoryVerdict = result.trajectoryVerdict;
320
+ this.signal?.throwIfAborted();
277
321
  aggregatedFeedback.push(...result.feedbackLog);
278
322
  // Cap the buffer so a long-running plan with many failures doesn't
279
323
  // grow memory unboundedly — we only ever surface the last 3 entries
@@ -286,37 +330,6 @@ export class PlanExecutor {
286
330
  lastFinalText = result.finalText;
287
331
  let effectiveTerminator = result.terminator;
288
332
  let effectiveFinalText = result.finalText;
289
- if (SUCCESS_TERMINATORS.has(result.terminator) && this.opts.subgoalVerifier) {
290
- const verification = await this.opts.subgoalVerifier.verify({
291
- goal: this.opts.goal,
292
- plan,
293
- step,
294
- observation: await this.snapshotForPlanner(),
295
- recentHistory: history,
296
- executorMessage: result.finalText,
297
- advancedKnowledge: this.opts.advancedKnowledge,
298
- }, this.opts.signal);
299
- accumulateUsage(usage, verification.usage);
300
- await this.fireSupervisorVerdict(step, verification);
301
- if (verification.verdict === "unverified") {
302
- return this.finish({ ok: false, finalText: verification.reason, stepsConsumed, usage, history, notes,
303
- plansEmitted, replans, reactFallbackUsed, terminator: "error", cancelled: false });
304
- }
305
- // A subgoal verdict cannot skip remaining work or the root-goal audit.
306
- if (verification.verdict === "not_achieved") {
307
- advancedTaskState?.recordRecovery({
308
- description: step.description,
309
- reason: verification.reason,
310
- guidance: verification.guidance,
311
- });
312
- effectiveTerminator = "reflection_veto";
313
- effectiveFinalText = [verification.reason, verification.guidance]
314
- .filter(Boolean)
315
- .join("; ");
316
- lastTerminator = effectiveTerminator;
317
- lastFinalText = effectiveFinalText;
318
- }
319
- }
320
333
  if (SUCCESS_TERMINATORS.has(effectiveTerminator)) {
321
334
  advancedTaskState?.recordCompleted({
322
335
  description: step.description,
@@ -400,8 +413,7 @@ export class PlanExecutor {
400
413
  notes: notes.length > 0 ? [...notes] : undefined,
401
414
  // Phase 2.2 / 2.3 — surface the most recent trajectory verdict so
402
415
  // the planner can react to "off_track" / "stuck" explicitly.
403
- trajectoryVerdict: lastTrajectoryVerdict,
404
- // KISS hardening — surface the last 3 reflector feedback entries
416
+ // KISS hardening — surface the last 3 executionChecks feedback entries
405
417
  // accumulated across **all** sub-tasks so the planner sees the
406
418
  // precise failure trail (pre-sanity vetoes, MCP failures,
407
419
  // trajectory verdicts) rather than having to parse
@@ -410,7 +422,7 @@ export class PlanExecutor {
410
422
  failureChain: aggregatedFeedback.length > 0 ? aggregatedFeedback.slice(-3) : undefined,
411
423
  };
412
424
  try {
413
- const repl = await this.opts.planner.replan(ctx, { signal: this.opts.signal });
425
+ const repl = await this.bounded(() => this.opts.planner.replan(ctx, { signal: this.signal }));
414
426
  accumulateUsage(usage, repl.usage);
415
427
  plan = repl.plan;
416
428
  plansEmitted += 1;
@@ -419,6 +431,7 @@ export class PlanExecutor {
419
431
  continue;
420
432
  }
421
433
  catch (e) {
434
+ this.signal?.throwIfAborted();
422
435
  // planner blew up — fall through to ReAct fallback
423
436
  await this.fireError(`replan failed: ${errMsg(e)}`);
424
437
  }
@@ -454,11 +467,11 @@ export class PlanExecutor {
454
467
  observationMode: this.opts.observationMode,
455
468
  maxSteps: Math.max(1, maxSteps - stepsConsumed),
456
469
  timeoutMs: fbRemaining,
457
- signal: this.opts.signal,
470
+ signal: this.signal,
458
471
  hooks: this.opts.hooks,
459
- reflector: this.opts.reflector,
472
+ executionChecks: this.opts.executionChecks,
460
473
  }).run();
461
- await this.verifyFallback(fallback);
474
+ this.signal?.throwIfAborted();
462
475
  stepsConsumed += fallback.steps;
463
476
  accumulateUsage(usage, fallback.usage);
464
477
  history.push(...fallback.history);
@@ -510,7 +523,79 @@ export class PlanExecutor {
510
523
  cancelled: false,
511
524
  });
512
525
  }
526
+ async runContinuousPro(plan, usage, memory) {
527
+ const history = [];
528
+ const notes = [];
529
+ const maxSteps = this.opts.maxSteps ?? PlanExecutor.DEFAULT_MAX_STEPS;
530
+ const maxReplans = this.opts.maxReplans ?? PlanExecutor.DEFAULT_MAX_REPLANS;
531
+ let stepsConsumed = 0;
532
+ let replans = 0;
533
+ let plansEmitted = 1;
534
+ let finalText = "";
535
+ let terminator = "error";
536
+ this.progress = () => ({ ok: false, finalText, steps: stepsConsumed, usage, history,
537
+ notes, plansEmitted, replans, reactFallbackUsed: false, terminator, cancelled: false });
538
+ while (stepsConsumed < maxSteps) {
539
+ this.signal?.throwIfAborted();
540
+ const remaining = this.deadline - Date.now();
541
+ if (remaining <= 0) {
542
+ terminator = "timeout";
543
+ finalText = "Task deadline reached";
544
+ break;
545
+ }
546
+ const result = await new AgentLoop({
547
+ task: this.opts.goal,
548
+ taskContext: { rootGoal: this.opts.goal, currentMilestone: this.opts.goal },
549
+ operatorGuidance: `Plan guidance (not separate tasks):\n${describePlan(plan)}\n` +
550
+ "Keep working on the ORIGINAL full task. Completing a milestone only updates progress; " +
551
+ "it does not finish this task. Record completed work and requested facts with take_note. " +
552
+ "Handle local blockers and alternative routes yourself. Finish only when the whole task " +
553
+ "is satisfied, or report a concrete blocker honestly. Preserve prior completed work.\n" +
554
+ (this.opts.advancedKnowledge ?? ""),
555
+ proOperator: true, proMemory: memory, priorHistory: history,
556
+ env: this.opts.env, mcp: this.opts.mcp, adapter: this.opts.adapter,
557
+ observationMode: this.opts.observationMode,
558
+ maxSteps: maxSteps - stepsConsumed, timeoutMs: remaining,
559
+ signal: this.signal, hooks: this.opts.hooks, executionChecks: this.opts.executionChecks,
560
+ }).run();
561
+ stepsConsumed += result.steps;
562
+ accumulateUsage(usage, result.usage);
563
+ history.push(...result.history);
564
+ notes.push(...result.notes);
565
+ finalText = result.finalText;
566
+ terminator = result.terminator;
567
+ this.signal?.throwIfAborted();
568
+ if (SUCCESS_TERMINATORS.has(terminator) || terminator === "call_for_user" ||
569
+ terminator === "cancelled" || stepsConsumed >= maxSteps ||
570
+ !REPLAN_TERMINATORS.has(terminator) || replans >= maxReplans)
571
+ break;
572
+ replans += 1;
573
+ try {
574
+ const observation = await this.snapshotForPlanner();
575
+ const revised = await this.bounded(() => this.opts.planner.replan({
576
+ goal: this.opts.goal, previousPlan: plan, observation, history,
577
+ notes: [...notes], advancedKnowledge: this.opts.advancedKnowledge,
578
+ failureReason: `Whole-task operator stopped with ${terminator}: ${finalText}. ` +
579
+ "Revise the route, preserving completed work and collected facts.",
580
+ failureChain: result.feedbackLog.slice(-3),
581
+ }, { signal: this.signal }));
582
+ accumulateUsage(usage, revised.usage);
583
+ plan = revised.plan;
584
+ plansEmitted += 1;
585
+ await this.firePlan(plan, true, replans);
586
+ }
587
+ catch (error) {
588
+ this.signal?.throwIfAborted();
589
+ await this.fireError(`replan failed: ${errMsg(error)}`);
590
+ break;
591
+ }
592
+ }
593
+ return this.finish({ ok: SUCCESS_TERMINATORS.has(terminator), finalText,
594
+ stepsConsumed, usage, history, notes, plansEmitted, replans,
595
+ reactFallbackUsed: false, terminator, cancelled: terminator === "cancelled" });
596
+ }
513
597
  async firePlan(plan, isReplan, replanCount) {
598
+ this.signal?.throwIfAborted();
514
599
  if (!this.opts.hooks?.onReasoning)
515
600
  return;
516
601
  try {
@@ -521,6 +606,7 @@ export class PlanExecutor {
521
606
  }
522
607
  }
523
608
  async fireError(message) {
609
+ this.signal?.throwIfAborted();
524
610
  if (!this.opts.hooks?.onError)
525
611
  return;
526
612
  try {
@@ -530,57 +616,79 @@ export class PlanExecutor {
530
616
  // ditto
531
617
  }
532
618
  }
533
- async verifyFallback(result) {
534
- if (!this.opts.subgoalVerifier || !SUCCESS_TERMINATORS.has(result.terminator))
535
- return;
536
- const step = { idx: 1, description: this.opts.goal, expectedOutcome: this.opts.goal };
537
- const verification = await this.opts.subgoalVerifier.verify({ goal: this.opts.goal,
538
- plan: { goal: this.opts.goal, steps: [step] }, step, observation: await this.snapshotForPlanner(),
539
- recentHistory: result.history, executorMessage: result.finalText, advancedKnowledge: this.opts.advancedKnowledge,
540
- }, this.opts.signal);
541
- accumulateUsage(result.usage, verification.usage);
542
- await this.fireSupervisorVerdict(step, verification);
543
- if (verification.verdict === "unverified" || verification.verdict === "not_achieved") {
544
- result.terminator = verification.verdict === "unverified" ? "error" : "reflection_veto";
545
- result.finalText = verification.reason;
546
- }
547
- }
548
- async fireSupervisorVerdict(step, verification) {
549
- if (!this.opts.hooks?.onReasoning || verification.verdict === "achieved")
550
- return;
551
- try {
552
- const guidance = verification.guidance ? `; guidance: ${verification.guidance}` : "";
553
- await this.opts.hooks.onReasoning(`[supervisor] subgoal ${step.idx}: ${verification.verdict} — ${verification.reason}${guidance}\n`);
554
- }
555
- catch {
556
- // Observability hooks never control execution.
557
- }
558
- }
559
619
  async finish(args) {
560
- if (args.ok && this.opts.subgoalVerifier) {
620
+ const policy = this.opts.resultVerification ?? "final";
621
+ if (args.ok && (this.opts.advancedKnowledge || this.opts.resultVerification) && policy !== "off" && !this.opts.subgoalVerifier) {
622
+ args.ok = false;
623
+ args.terminator = "error";
624
+ args.finalText = `Original task completion could not be verified: no result checker configured\nExecutor report (unverified): ${args.finalText}`;
625
+ }
626
+ if (args.ok && this.opts.subgoalVerifier && policy !== "off") {
627
+ let rejected = false;
628
+ let deficiency = "";
561
629
  try {
562
- this.opts.signal?.throwIfAborted();
563
- const remaining = this.deadline - Date.now();
564
- if (remaining <= 0)
565
- throw new Error("Task deadline reached before final audit");
566
- const timeout = AbortSignal.timeout(Math.ceil(remaining));
567
- const signal = this.opts.signal ? AbortSignal.any([this.opts.signal, timeout]) : timeout;
568
- const step = { idx: 1, description: this.opts.goal, expectedOutcome: this.opts.goal };
569
- const audit = await this.opts.subgoalVerifier.verify({ scope: "task", goal: this.opts.goal,
570
- plan: { goal: this.opts.goal, steps: [step] }, step, observation: await this.snapshotForPlanner(),
571
- recentHistory: args.history, executorMessage: args.finalText, notes: args.notes,
572
- }, signal);
573
- signal.throwIfAborted();
574
- accumulateUsage(args.usage, audit.usage);
575
- args.ok = audit.verdict === "task_complete" && Boolean(audit.finalAnswer?.trim());
576
- args.finalText = audit.finalAnswer || audit.reason;
577
- args.terminator = args.ok ? "done" : audit.verdict === "not_achieved" ? "reflection_veto" : "error";
630
+ for (let attempt = 0; attempt < 2; attempt++) {
631
+ this.signal?.throwIfAborted();
632
+ const remaining = this.deadline - Date.now();
633
+ if (remaining <= 0)
634
+ throw new Error("Task deadline reached before final audit");
635
+ const signal = this.signal;
636
+ const step = { idx: 1, description: this.opts.goal, expectedOutcome: this.opts.goal };
637
+ const observation = await this.snapshotForPlanner();
638
+ const verifier = this.opts.subgoalVerifier;
639
+ const audit = await this.bounded(() => verifier.verify({ scope: "task", goal: this.opts.goal,
640
+ plan: { goal: this.opts.goal, steps: [step] }, step, observation,
641
+ recentHistory: args.history, executorMessage: args.finalText, notes: args.notes,
642
+ }, signal));
643
+ signal.throwIfAborted();
644
+ accumulateUsage(args.usage, audit.usage);
645
+ if (audit.verdict === "task_complete") {
646
+ args.finalText = audit.finalAnswer?.trim() || args.finalText;
647
+ rejected = false;
648
+ args.ok = true;
649
+ args.terminator = "done";
650
+ break;
651
+ }
652
+ if (audit.verdict !== "not_achieved")
653
+ throw new Error(audit.reason || "No conclusive verification");
654
+ rejected = true;
655
+ deficiency = audit.reason;
656
+ args.ok = false;
657
+ args.terminator = "reflection_veto";
658
+ args.finalText = audit.finalAnswer || audit.reason;
659
+ const repairSteps = (this.opts.maxSteps ?? PlanExecutor.DEFAULT_MAX_STEPS) - args.stepsConsumed;
660
+ if (attempt > 0 || repairSteps <= 0)
661
+ break;
662
+ // Repair only concrete missing requirements, never a checker outage.
663
+ const repair = await new AgentLoop({
664
+ task: `Original task: ${this.opts.goal}\nRepair ONLY this verified deficiency: ${audit.reason}\n${audit.guidance ?? ""}\nDo not repeat already completed operations.`,
665
+ taskContext: { rootGoal: this.opts.goal, currentMilestone: audit.reason },
666
+ priorHistory: args.history, proOperator: Boolean(this.opts.adapter.nativeTools || this.opts.advancedKnowledge),
667
+ env: this.opts.env, mcp: this.opts.mcp, adapter: this.opts.adapter,
668
+ observationMode: this.opts.observationMode, maxSteps: repairSteps,
669
+ timeoutMs: Math.max(1, this.deadline - Date.now()), signal: this.signal,
670
+ hooks: this.opts.hooks, executionChecks: this.opts.executionChecks,
671
+ }).run();
672
+ args.stepsConsumed += repair.steps;
673
+ accumulateUsage(args.usage, repair.usage);
674
+ args.history.push(...repair.history);
675
+ args.notes.push(...repair.notes);
676
+ this.signal?.throwIfAborted();
677
+ if (!SUCCESS_TERMINATORS.has(repair.terminator)) {
678
+ args.terminator = repair.terminator;
679
+ args.finalText = repair.finalText;
680
+ args.cancelled = repair.cancelled;
681
+ break;
682
+ }
683
+ args.finalText = repair.finalText;
684
+ }
578
685
  }
579
686
  catch (error) {
580
- args.ok = false;
581
687
  args.cancelled = Boolean(this.opts.signal?.aborted);
582
- args.terminator = args.cancelled ? "cancelled" : Date.now() >= this.deadline ? "timeout" : "error";
583
- args.finalText = `Original task completion could not be verified: ${errMsg(error)}`;
688
+ const deadlineReached = Date.now() >= this.deadline || Boolean(this.signal?.aborted);
689
+ args.ok = false;
690
+ args.terminator = args.cancelled ? "cancelled" : deadlineReached ? "timeout" : rejected ? "reflection_veto" : "error";
691
+ args.finalText = `${deficiency ? `Unresolved requirement: ${deficiency}. ` : ""}Original task completion could not be verified: ${errMsg(error)}\nExecutor report (unverified): ${args.finalText}`;
584
692
  }
585
693
  }
586
694
  return {
@@ -605,6 +713,9 @@ export class PlanExecutor {
605
713
  * cannot be collected.
606
714
  */
607
715
  async snapshotForPlanner() {
716
+ return this.bounded(() => this.collectSnapshotForPlanner());
717
+ }
718
+ async collectSnapshotForPlanner() {
608
719
  if (this.opts.observationMode === "xml") {
609
720
  let uiDump;
610
721
  try {
@@ -704,7 +815,7 @@ function errMsg(e) {
704
815
  * goal it serves and what the upcoming sub-tasks look like, but the
705
816
  * primary instruction is still the current step's description.
706
817
  */
707
- function formatStepAsTask(rootGoal, plan, idx, advancedKnowledge, advancedTaskState) {
818
+ function formatStepAsTask(rootGoal, plan, idx, advancedKnowledge, advancedTaskState, nativeOperator = false) {
708
819
  const step = plan.steps[idx];
709
820
  const advanced = Boolean(advancedKnowledge);
710
821
  const upcoming = plan.steps
@@ -718,8 +829,11 @@ function formatStepAsTask(rootGoal, plan, idx, advancedKnowledge, advancedTaskSt
718
829
  // supervisor tiers retain the root goal, while the mobile actor sees only
719
830
  // one grounded subgoal. Showing AutoGLM the root goal causes it to race
720
831
  // ahead and execute later plan items inside the current child loop.
832
+ // Native Pro needs the original literal field values as reference data;
833
+ // its current-subtask scope still forbids executing later milestones.
721
834
  const goalLine = advanced
722
- ? "# Scope: execute exactly one planner-assigned sub-task."
835
+ ? "# Scope: execute exactly one planner-assigned sub-task." +
836
+ (nativeOperator ? `\n# Original request (reference constraints only, not permission to execute later sub-tasks):\n${rootGoal}` : "")
723
837
  : `# Goal: ${rootGoal}`;
724
838
  const scopeRule = advanced
725
839
  ? [