@xopcai/xopc 0.0.434 → 0.0.436

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 (80) hide show
  1. package/dist/browser-ext/manifest.json +1 -1
  2. package/dist/extensions/telegram/xopc.extension.json +1 -1
  3. package/dist/gateway/static/root/assets/{automations-page-CmxICTM4.js → automations-page-BjbM15eY.js} +1 -1
  4. package/dist/gateway/static/root/assets/{automations-workspace-R6YNDdAO.js → automations-workspace-CqurzLYX.js} +2 -2
  5. package/dist/gateway/static/root/assets/{chat-page-BJ8PlDjZ.js → chat-page--wcFhTjW.js} +30 -30
  6. package/dist/gateway/static/root/assets/{index-DWQ4LbBn.js → index-C4moZbZv.js} +4 -4
  7. package/dist/gateway/static/root/assets/{personal-page-l9_vYfdJ.js → personal-page-BhuT79Wd.js} +1 -1
  8. package/dist/gateway/static/root/assets/{project-detail-page-BbyV8EiG.js → project-detail-page-CuugOYfe.js} +1 -1
  9. package/dist/gateway/static/root/assets/{route-preload-BWpw9qxc.js → route-preload-BQapekpy.js} +2 -2
  10. package/dist/gateway/static/root/assets/{settings-page-XJXcnE1_.js → settings-page-CedwaHM0.js} +1 -1
  11. package/dist/gateway/static/root/assets/{task-detail-page-DvX9JoEd.js → task-detail-page-_Og3plZL.js} +1 -1
  12. package/dist/gateway/static/root/index.html +3 -3
  13. package/dist/package.js +1 -1
  14. package/dist/src/agent/agent-manager.js +1 -1
  15. package/dist/src/agent/background-review/run-background-review.js +1 -1
  16. package/dist/src/agent/external-tools/cliProvider.js +2 -2
  17. package/dist/src/agent/external-tools/composio-provider.js +2 -2
  18. package/dist/src/agent/external-tools/endpoint-provider.js +2 -2
  19. package/dist/src/agent/service.js +1 -1
  20. package/dist/src/agent/skills/index.js +1 -1
  21. package/dist/src/agent/skills/managed-store.js +1 -1
  22. package/dist/src/agent/skills/skill-manage-ops.js +1 -1
  23. package/dist/src/agent/tool-manuals/computer.d.ts +1 -1
  24. package/dist/src/agent/tool-manuals/computer.js +1 -1
  25. package/dist/src/agent/tools/personal-read-tool.js +1 -1
  26. package/dist/src/agent/tools/xopc-use-tool.js +2 -2
  27. package/dist/src/agent-catalog/capabilities.js +2 -2
  28. package/dist/src/agent-catalog/repository.js +1 -1
  29. package/dist/src/automations/api/routes.js +2 -2
  30. package/dist/src/automations/capabilities/drafts.js +1 -1
  31. package/dist/src/automations/capabilities/write.js +1 -1
  32. package/dist/src/automations/configuration-conversation.js +1 -1
  33. package/dist/src/browser/providers/browser-ext-install.js +1 -1
  34. package/dist/src/capabilities/runtime/dispatcher.js +1 -1
  35. package/dist/src/capabilities/runtime/product.js +1 -1
  36. package/dist/src/cli/commands/agents.js +1 -1
  37. package/dist/src/cli/commands/models.js +1 -1
  38. package/dist/src/cli/commands/onboard/model.js +1 -1
  39. package/dist/src/cli/utils/init-workspace-core.js +1 -1
  40. package/dist/src/computer/broker.d.ts +5 -0
  41. package/dist/src/computer/broker.js +33 -9
  42. package/dist/src/computer/diagnostics.d.ts +340 -0
  43. package/dist/src/computer/diagnostics.js +4 -0
  44. package/dist/src/computer/errors.d.ts +340 -0
  45. package/dist/src/computer/errors.js +121 -4
  46. package/dist/src/computer/evaluation.d.ts +186 -0
  47. package/dist/src/computer/model-adapter.js +47 -20
  48. package/dist/src/computer/runtime.d.ts +170 -0
  49. package/dist/src/computer/runtime.js +36 -8
  50. package/dist/src/computer/stability-diagnostics.d.ts +23 -0
  51. package/dist/src/computer/stability-diagnostics.js +71 -0
  52. package/dist/src/computer/validation-diagnostics.d.ts +9 -0
  53. package/dist/src/computer/validation-diagnostics.js +54 -0
  54. package/dist/src/config/agent-profile.js +1 -1
  55. package/dist/src/execution-environments/local-worktree-manager.js +1 -1
  56. package/dist/src/extensions/agent-plugins/skill-catalog.js +1 -1
  57. package/dist/src/extensions/agent-plugins/validation.js +1 -1
  58. package/dist/src/gateway/agents-admin.js +1 -1
  59. package/dist/src/gateway/global-defaults-admin.js +1 -1
  60. package/dist/src/gateway/hono/routes/agents.js +1 -1
  61. package/dist/src/gateway/hono/routes/config-patch/misc.js +1 -1
  62. package/dist/src/gateway/hono/routes/notes.js +2 -2
  63. package/dist/src/gateway/hono/routes/phone-setup.js +1 -1
  64. package/dist/src/gateway/hono/routes/projects.js +2 -2
  65. package/dist/src/gateway/hono/routes/session-input-handler.js +1 -1
  66. package/dist/src/gateway/hono/routes/tasks.js +1 -1
  67. package/dist/src/gateway/image-generation-setup.js +1 -1
  68. package/dist/src/gateway/xopc-cloud-capability-setup.js +1 -1
  69. package/dist/src/imports/importService.js +1 -1
  70. package/dist/src/local-apps/service.js +1 -1
  71. package/dist/src/personal-agent/service.js +1 -1
  72. package/dist/src/realtime/runtime.js +13 -5
  73. package/dist/src/realtime/writer.d.ts +7 -0
  74. package/dist/src/realtime/writer.js +96 -30
  75. package/dist/src/runtime-tools/archive.js +1 -1
  76. package/dist/src/tasks/capabilities/read.js +2 -2
  77. package/dist/src/tasks/capabilities/write.js +1 -1
  78. package/dist/src/tui/backends/embedded-backend.js +1 -1
  79. package/dist/src/voice/realtime/persona-context.js +1 -1
  80. package/package.json +1 -1
@@ -88,6 +88,176 @@ export declare const ComputerEvaluationRunSchema: z.ZodObject<{
88
88
  invalid_envelope: "invalid_envelope";
89
89
  output_limit: "output_limit";
90
90
  }>>;
91
+ validation: z.ZodOptional<z.ZodObject<{
92
+ action: z.ZodEnum<{
93
+ type: "type";
94
+ key: "key";
95
+ unknown: "unknown";
96
+ answer: "answer";
97
+ wait: "wait";
98
+ typeText: "typeText";
99
+ batch: "batch";
100
+ terminate: "terminate";
101
+ activate: "activate";
102
+ showMenu: "showMenu";
103
+ click: "click";
104
+ drag: "drag";
105
+ setValue: "setValue";
106
+ pressKeys: "pressKeys";
107
+ scroll: "scroll";
108
+ activateSequence: "activateSequence";
109
+ interact: "interact";
110
+ takeover: "takeover";
111
+ finished: "finished";
112
+ button_plan: "button_plan";
113
+ activate_sequence: "activate_sequence";
114
+ show_menu: "show_menu";
115
+ set_value: "set_value";
116
+ left_click: "left_click";
117
+ right_click: "right_click";
118
+ double_click: "double_click";
119
+ hscroll: "hscroll";
120
+ }>;
121
+ stage: z.ZodEnum<{
122
+ plan: "plan";
123
+ schema: "schema";
124
+ converted_action: "converted_action";
125
+ typing_target: "typing_target";
126
+ keyboard: "keyboard";
127
+ }>;
128
+ issues: z.ZodArray<z.ZodObject<{
129
+ path: z.ZodArray<z.ZodUnion<readonly [z.ZodEnum<{
130
+ reason: "reason";
131
+ keys: "keys";
132
+ value: "value";
133
+ name: "name";
134
+ time: "time";
135
+ from: "from";
136
+ action: "action";
137
+ when: "when";
138
+ label: "label";
139
+ text: "text";
140
+ kind: "kind";
141
+ status: "status";
142
+ durationMs: "durationMs";
143
+ role: "role";
144
+ to: "to";
145
+ actions: "actions";
146
+ count: "count";
147
+ x: "x";
148
+ y: "y";
149
+ point: "point";
150
+ arguments: "arguments";
151
+ ref: "ref";
152
+ button: "button";
153
+ deltaX: "deltaX";
154
+ deltaY: "deltaY";
155
+ refs: "refs";
156
+ pixels: "pixels";
157
+ steps: "steps";
158
+ coordinate: "coordinate";
159
+ unknown_field: "unknown_field";
160
+ proposal: "proposal";
161
+ claimedSuccess: "claimedSuccess";
162
+ }>, z.ZodNumber]>>;
163
+ code: z.ZodEnum<{
164
+ custom: "custom";
165
+ invalid_type: "invalid_type";
166
+ unrecognized_keys: "unrecognized_keys";
167
+ invalid_union: "invalid_union";
168
+ invalid_value: "invalid_value";
169
+ invalid_format: "invalid_format";
170
+ too_big: "too_big";
171
+ too_small: "too_small";
172
+ not_multiple_of: "not_multiple_of";
173
+ missing_point: "missing_point";
174
+ outside_frame: "outside_frame";
175
+ editable_target_missing: "editable_target_missing";
176
+ editable_target_ambiguous: "editable_target_ambiguous";
177
+ invalid_context: "invalid_context";
178
+ unsupported_key: "unsupported_key";
179
+ plan_not_grounded: "plan_not_grounded";
180
+ }>;
181
+ action: z.ZodEnum<{
182
+ type: "type";
183
+ key: "key";
184
+ unknown: "unknown";
185
+ answer: "answer";
186
+ wait: "wait";
187
+ typeText: "typeText";
188
+ batch: "batch";
189
+ terminate: "terminate";
190
+ activate: "activate";
191
+ showMenu: "showMenu";
192
+ click: "click";
193
+ drag: "drag";
194
+ setValue: "setValue";
195
+ pressKeys: "pressKeys";
196
+ scroll: "scroll";
197
+ activateSequence: "activateSequence";
198
+ interact: "interact";
199
+ takeover: "takeover";
200
+ finished: "finished";
201
+ button_plan: "button_plan";
202
+ activate_sequence: "activate_sequence";
203
+ show_menu: "show_menu";
204
+ set_value: "set_value";
205
+ left_click: "left_click";
206
+ right_click: "right_click";
207
+ double_click: "double_click";
208
+ hscroll: "hscroll";
209
+ }>;
210
+ }, z.core.$strict>>;
211
+ }, z.core.$strict>>;
212
+ stability: z.ZodOptional<z.ZodObject<{
213
+ stage: z.ZodEnum<{
214
+ initial_capture: "initial_capture";
215
+ pre_dispatch: "pre_dispatch";
216
+ post_action: "post_action";
217
+ }>;
218
+ samples: z.ZodNumber;
219
+ action: z.ZodOptional<z.ZodEnum<{
220
+ type: "type";
221
+ key: "key";
222
+ unknown: "unknown";
223
+ answer: "answer";
224
+ wait: "wait";
225
+ typeText: "typeText";
226
+ batch: "batch";
227
+ terminate: "terminate";
228
+ activate: "activate";
229
+ showMenu: "showMenu";
230
+ click: "click";
231
+ drag: "drag";
232
+ setValue: "setValue";
233
+ pressKeys: "pressKeys";
234
+ scroll: "scroll";
235
+ activateSequence: "activateSequence";
236
+ interact: "interact";
237
+ takeover: "takeover";
238
+ finished: "finished";
239
+ button_plan: "button_plan";
240
+ activate_sequence: "activate_sequence";
241
+ show_menu: "show_menu";
242
+ set_value: "set_value";
243
+ left_click: "left_click";
244
+ right_click: "right_click";
245
+ double_click: "double_click";
246
+ hscroll: "hscroll";
247
+ }>>;
248
+ changes: z.ZodArray<z.ZodEnum<{
249
+ window_identity: "window_identity";
250
+ window_geometry: "window_geometry";
251
+ image_dimensions: "image_dimensions";
252
+ accessibility_structure: "accessibility_structure";
253
+ accessibility_text: "accessibility_text";
254
+ accessibility_state: "accessibility_state";
255
+ accessibility_geometry: "accessibility_geometry";
256
+ visual_or_unexposed_state: "visual_or_unexposed_state";
257
+ deadline: "deadline";
258
+ }>>;
259
+ changedElementIndices: z.ZodArray<z.ZodNumber>;
260
+ }, z.core.$strict>>;
91
261
  serviceErrorCode: z.ZodOptional<z.ZodEnum<{
92
262
  provider_error: "provider_error";
93
263
  max_input_tokens_exceeded: "max_input_tokens_exceeded";
@@ -114,6 +284,22 @@ export declare function computerReportMeasurements(report: ComputerSessionReport
114
284
  httpStatus?: number;
115
285
  requestId?: string;
116
286
  validationReason?: "invalid_json" | "invalid_arguments" | "missing_call" | "multiple_calls" | "invalid_envelope" | "output_limit";
287
+ validation?: {
288
+ action: "type" | "key" | "unknown" | "answer" | "wait" | "typeText" | "batch" | "terminate" | "activate" | "showMenu" | "click" | "drag" | "setValue" | "pressKeys" | "scroll" | "activateSequence" | "interact" | "takeover" | "finished" | "button_plan" | "activate_sequence" | "show_menu" | "set_value" | "left_click" | "right_click" | "double_click" | "hscroll";
289
+ stage: "plan" | "schema" | "converted_action" | "typing_target" | "keyboard";
290
+ issues: {
291
+ path: (number | "reason" | "keys" | "value" | "name" | "time" | "from" | "action" | "when" | "label" | "text" | "kind" | "status" | "durationMs" | "role" | "to" | "actions" | "count" | "x" | "y" | "point" | "arguments" | "ref" | "button" | "deltaX" | "deltaY" | "refs" | "pixels" | "steps" | "coordinate" | "unknown_field" | "proposal" | "claimedSuccess")[];
292
+ code: "custom" | "invalid_type" | "unrecognized_keys" | "invalid_union" | "invalid_value" | "invalid_format" | "too_big" | "too_small" | "not_multiple_of" | "missing_point" | "outside_frame" | "editable_target_missing" | "editable_target_ambiguous" | "invalid_context" | "unsupported_key" | "plan_not_grounded";
293
+ action: "type" | "key" | "unknown" | "answer" | "wait" | "typeText" | "batch" | "terminate" | "activate" | "showMenu" | "click" | "drag" | "setValue" | "pressKeys" | "scroll" | "activateSequence" | "interact" | "takeover" | "finished" | "button_plan" | "activate_sequence" | "show_menu" | "set_value" | "left_click" | "right_click" | "double_click" | "hscroll";
294
+ }[];
295
+ };
296
+ stability?: {
297
+ stage: "initial_capture" | "pre_dispatch" | "post_action";
298
+ samples: number;
299
+ changes: ("window_identity" | "window_geometry" | "image_dimensions" | "accessibility_structure" | "accessibility_text" | "accessibility_state" | "accessibility_geometry" | "visual_or_unexposed_state" | "deadline")[];
300
+ changedElementIndices: number[];
301
+ action?: "type" | "key" | "unknown" | "answer" | "wait" | "typeText" | "batch" | "terminate" | "activate" | "showMenu" | "click" | "drag" | "setValue" | "pressKeys" | "scroll" | "activateSequence" | "interact" | "takeover" | "finished" | "button_plan" | "activate_sequence" | "show_menu" | "set_value" | "left_click" | "right_click" | "double_click" | "hscroll";
302
+ };
117
303
  serviceErrorCode?: "provider_error" | "max_input_tokens_exceeded" | "max_tokens_exceeded" | "model_capability_unsupported" | "unsupported_request_field" | "invalid_image" | "request_too_large" | "invalid_request" | "free_pool_unavailable";
118
304
  };
119
305
  durationMs: number;
@@ -2,6 +2,7 @@ import { ComputerActionSchema, ComputerPrimitiveActionSchema, init_src } from ".
2
2
  import { ComputerButtonPlan, ComputerButtonPlanSchema } from "./semantic-plan.js";
3
3
  import { ComputerDiagnosticSchema, ComputerOperationError, computerDiagnostic } from "./errors.js";
4
4
  import { normalizeComputerKeys } from "./keyboard.js";
5
+ import { modelValidation } from "./validation-diagnostics.js";
5
6
  import { randomUUID } from "node:crypto";
6
7
  import { z } from "zod";
7
8
  //#region src/computer/model-adapter.ts
@@ -36,11 +37,15 @@ const StructuredProposalSchema = z.union(ComputerProposalSchema.options.map((opt
36
37
  kind: z.literal("action"),
37
38
  action: StructuredActionSchema
38
39
  }).strict() : option));
39
- function validateTypingProposal(proposal, input) {
40
- if (proposal.kind === "action" && proposal.action.kind === "batch") for (const action of proposal.action.actions) validateTypingProposal({
40
+ function validateTypingProposal(proposal, input, path = ["action"], root = proposal) {
41
+ if (proposal.kind === "action" && proposal.action.kind === "batch") proposal.action.actions.forEach((action, index) => validateTypingProposal({
41
42
  kind: "action",
42
43
  action
43
- }, input);
44
+ }, input, [
45
+ ...path,
46
+ "actions",
47
+ index
48
+ ], root));
44
49
  if (proposal.kind === "action" && proposal.action.kind === "pressKeys") {
45
50
  let platform = "darwin";
46
51
  try {
@@ -49,15 +54,21 @@ function validateTypingProposal(proposal, input) {
49
54
  try {
50
55
  proposal.action.keys = normalizeComputerKeys(proposal.action.keys, platform);
51
56
  } catch {
52
- throw invalidOutput("invalid_arguments");
57
+ throw invalidOutput("invalid_arguments", void 0, modelValidation(root, "keyboard", void 0, {
58
+ path: [...path, "keys"],
59
+ code: "unsupported_key"
60
+ }));
53
61
  }
54
62
  }
55
63
  if (proposal.kind !== "action" || proposal.action.kind !== "typeText") return;
56
64
  const point = proposal.action.point;
57
- if (!point || point.x >= input.width || point.y >= input.height) throw invalidOutput("invalid_arguments");
65
+ if (!point || point.x >= input.width || point.y >= input.height) throw invalidOutput("invalid_arguments", void 0, modelValidation(root, "typing_target", void 0, {
66
+ path: [...path, "point"],
67
+ code: point ? "outside_frame" : "missing_point"
68
+ }));
58
69
  try {
59
70
  const context = JSON.parse(input.summary);
60
- if ((Array.isArray(context.elements) ? context.elements.filter((e) => {
71
+ const fields = Array.isArray(context.elements) ? context.elements.filter((e) => {
61
72
  if (!["AXTextField", "AXTextArea"].includes(String(e.role)) || e.enabled === false || e.inputAllowed === false || /password|passcode|验证码|密码|one.time.code/i.test(String(e.label ?? ""))) return false;
62
73
  const b = e.bounds;
63
74
  return b && [
@@ -66,9 +77,17 @@ function validateTypingProposal(proposal, input) {
66
77
  b.width,
67
78
  b.height
68
79
  ].every(Number.isFinite) && b.width > 0 && b.height > 0 && point.x >= b.x && point.y >= b.y && point.x < b.x + b.width && point.y < b.y + b.height;
69
- }) : []).length !== 1) throw invalidOutput("invalid_arguments");
70
- } catch {
71
- throw invalidOutput("invalid_arguments");
80
+ }) : [];
81
+ if (fields.length !== 1) throw invalidOutput("invalid_arguments", void 0, modelValidation(root, "typing_target", void 0, {
82
+ path: [...path, "point"],
83
+ code: fields.length ? "editable_target_ambiguous" : "editable_target_missing"
84
+ }));
85
+ } catch (error) {
86
+ if (computerDiagnostic(error)) throw error;
87
+ throw invalidOutput("invalid_arguments", void 0, modelValidation(root, "typing_target", void 0, {
88
+ path: [...path, "point"],
89
+ code: "invalid_context"
90
+ }));
72
91
  }
73
92
  }
74
93
  const Coordinate = z.tuple([z.number().finite().min(0).max(1e3), z.number().finite().min(0).max(1e3)]);
@@ -275,7 +294,7 @@ function parseGuiPlusProposal(content, width, height) {
275
294
  name: z.literal("computer_use"),
276
295
  arguments: GuiArgs
277
296
  }).strict().safeParse(raw);
278
- if (!parsed.success) throw invalidOutput("invalid_arguments");
297
+ if (!parsed.success) throw invalidOutput("invalid_arguments", void 0, modelValidation(raw, "schema", parsed.error));
279
298
  return parsed.data;
280
299
  })().arguments;
281
300
  const point = "coordinate" in a && a.coordinate ? {
@@ -367,19 +386,20 @@ function parseGuiPlusProposal(content, width, height) {
367
386
  break;
368
387
  }
369
388
  const parsed = ComputerActionSchema.safeParse(action);
370
- if (!parsed.success) throw invalidOutput("invalid_arguments");
389
+ if (!parsed.success) throw invalidOutput("invalid_arguments", void 0, modelValidation(action, "converted_action", parsed.error));
371
390
  return {
372
391
  kind: "action",
373
392
  action: parsed.data
374
393
  };
375
394
  }
376
395
  const invalidReplies = /* @__PURE__ */ new WeakMap();
377
- function invalidOutput(validationReason, errorCode = "COMPUTER_INVALID_MODEL_OUTPUT") {
396
+ function invalidOutput(validationReason, errorCode = "COMPUTER_INVALID_MODEL_OUTPUT", validation) {
378
397
  return new ComputerOperationError({
379
398
  errorCode,
380
399
  phase: "model",
381
400
  diagnosticId: randomUUID(),
382
- validationReason
401
+ validationReason,
402
+ ...validation ? { validation } : {}
383
403
  });
384
404
  }
385
405
  /** One format-only re-prediction is safe before any input has been proposed or dispatched. */
@@ -561,14 +581,19 @@ var ChatCompletionsComputerAdapter = class {
561
581
  const structured = c.profile === "structured-tools-v1";
562
582
  const proposalSchema = !input.formatCorrection && input.maxPlanActions && input.maxPlanActions > 1 ? z.union([StructuredProposalSchema, ComputerButtonPlanSchema]) : StructuredProposalSchema;
563
583
  const parseProposal = (args) => {
564
- const proposal = z.object({ proposal: proposalSchema }).strict().parse(args).proposal;
584
+ const parsed = z.object({ proposal: proposalSchema }).strict().safeParse(args);
585
+ if (!parsed.success) throw invalidOutput("invalid_arguments", void 0, modelValidation(args, "schema", parsed.error));
586
+ const proposal = parsed.data.proposal;
565
587
  if (proposal.kind !== "button_plan") {
566
588
  validateTypingProposal(proposal, input);
567
589
  return proposal;
568
590
  }
569
591
  this.plan.install(proposal, input.goal, Math.min(6, input.maxPlanActions ?? 0));
570
592
  const action = this.plan.next(input);
571
- if (!action) throw invalidOutput("invalid_arguments");
593
+ if (!action) throw invalidOutput("invalid_arguments", void 0, modelValidation(proposal, "plan", void 0, {
594
+ path: ["steps"],
595
+ code: "plan_not_grounded"
596
+ }));
572
597
  return {
573
598
  kind: "action",
574
599
  action
@@ -674,8 +699,9 @@ var ChatCompletionsComputerAdapter = class {
674
699
  kind: "answer",
675
700
  text: answerSchema.parse(args).text
676
701
  } : parseProposal(args);
677
- } catch {
678
- throw invalidOutput("invalid_arguments");
702
+ } catch (error) {
703
+ if (computerDiagnostic(error)) throw error;
704
+ throw invalidOutput("invalid_arguments", void 0, modelValidation({}, "schema", error));
679
705
  }
680
706
  }
681
707
  const envelope = z.object({ choices: z.array(z.object({
@@ -711,8 +737,9 @@ var ChatCompletionsComputerAdapter = class {
711
737
  kind: "answer",
712
738
  text: answerSchema.parse(args).text
713
739
  } : parseProposal(args);
714
- } catch {
715
- throw invalidOutput("invalid_arguments");
740
+ } catch (error) {
741
+ if (computerDiagnostic(error)) throw error;
742
+ throw invalidOutput("invalid_arguments", void 0, modelValidation({}, "schema", error));
716
743
  }
717
744
  }
718
745
  };
@@ -917,7 +944,7 @@ var OpenAIResponsesComputerAdapter = class {
917
944
  let pointer;
918
945
  const append = (action) => {
919
946
  const parsed = ComputerActionSchema.safeParse(action);
920
- if (!parsed.success) throw invalidOutput("invalid_arguments");
947
+ if (!parsed.success) throw invalidOutput("invalid_arguments", void 0, modelValidation(action, "converted_action", parsed.error));
921
948
  proposals.push({
922
949
  kind: "action",
923
950
  action: parsed.data
@@ -82,6 +82,176 @@ declare const Reply: z.ZodObject<{
82
82
  invalid_envelope: "invalid_envelope";
83
83
  output_limit: "output_limit";
84
84
  }>>;
85
+ validation: z.ZodOptional<z.ZodObject<{
86
+ action: z.ZodEnum<{
87
+ type: "type";
88
+ key: "key";
89
+ unknown: "unknown";
90
+ answer: "answer";
91
+ wait: "wait";
92
+ typeText: "typeText";
93
+ batch: "batch";
94
+ terminate: "terminate";
95
+ activate: "activate";
96
+ showMenu: "showMenu";
97
+ click: "click";
98
+ drag: "drag";
99
+ setValue: "setValue";
100
+ pressKeys: "pressKeys";
101
+ scroll: "scroll";
102
+ activateSequence: "activateSequence";
103
+ interact: "interact";
104
+ takeover: "takeover";
105
+ finished: "finished";
106
+ button_plan: "button_plan";
107
+ activate_sequence: "activate_sequence";
108
+ show_menu: "show_menu";
109
+ set_value: "set_value";
110
+ left_click: "left_click";
111
+ right_click: "right_click";
112
+ double_click: "double_click";
113
+ hscroll: "hscroll";
114
+ }>;
115
+ stage: z.ZodEnum<{
116
+ plan: "plan";
117
+ schema: "schema";
118
+ converted_action: "converted_action";
119
+ typing_target: "typing_target";
120
+ keyboard: "keyboard";
121
+ }>;
122
+ issues: z.ZodArray<z.ZodObject<{
123
+ path: z.ZodArray<z.ZodUnion<readonly [z.ZodEnum<{
124
+ reason: "reason";
125
+ keys: "keys";
126
+ value: "value";
127
+ name: "name";
128
+ time: "time";
129
+ from: "from";
130
+ action: "action";
131
+ when: "when";
132
+ label: "label";
133
+ text: "text";
134
+ kind: "kind";
135
+ status: "status";
136
+ durationMs: "durationMs";
137
+ role: "role";
138
+ to: "to";
139
+ actions: "actions";
140
+ count: "count";
141
+ x: "x";
142
+ y: "y";
143
+ point: "point";
144
+ arguments: "arguments";
145
+ ref: "ref";
146
+ button: "button";
147
+ deltaX: "deltaX";
148
+ deltaY: "deltaY";
149
+ refs: "refs";
150
+ pixels: "pixels";
151
+ steps: "steps";
152
+ coordinate: "coordinate";
153
+ unknown_field: "unknown_field";
154
+ proposal: "proposal";
155
+ claimedSuccess: "claimedSuccess";
156
+ }>, z.ZodNumber]>>;
157
+ code: z.ZodEnum<{
158
+ custom: "custom";
159
+ invalid_type: "invalid_type";
160
+ unrecognized_keys: "unrecognized_keys";
161
+ invalid_union: "invalid_union";
162
+ invalid_value: "invalid_value";
163
+ invalid_format: "invalid_format";
164
+ too_big: "too_big";
165
+ too_small: "too_small";
166
+ not_multiple_of: "not_multiple_of";
167
+ missing_point: "missing_point";
168
+ outside_frame: "outside_frame";
169
+ editable_target_missing: "editable_target_missing";
170
+ editable_target_ambiguous: "editable_target_ambiguous";
171
+ invalid_context: "invalid_context";
172
+ unsupported_key: "unsupported_key";
173
+ plan_not_grounded: "plan_not_grounded";
174
+ }>;
175
+ action: z.ZodEnum<{
176
+ type: "type";
177
+ key: "key";
178
+ unknown: "unknown";
179
+ answer: "answer";
180
+ wait: "wait";
181
+ typeText: "typeText";
182
+ batch: "batch";
183
+ terminate: "terminate";
184
+ activate: "activate";
185
+ showMenu: "showMenu";
186
+ click: "click";
187
+ drag: "drag";
188
+ setValue: "setValue";
189
+ pressKeys: "pressKeys";
190
+ scroll: "scroll";
191
+ activateSequence: "activateSequence";
192
+ interact: "interact";
193
+ takeover: "takeover";
194
+ finished: "finished";
195
+ button_plan: "button_plan";
196
+ activate_sequence: "activate_sequence";
197
+ show_menu: "show_menu";
198
+ set_value: "set_value";
199
+ left_click: "left_click";
200
+ right_click: "right_click";
201
+ double_click: "double_click";
202
+ hscroll: "hscroll";
203
+ }>;
204
+ }, z.core.$strict>>;
205
+ }, z.core.$strict>>;
206
+ stability: z.ZodOptional<z.ZodObject<{
207
+ stage: z.ZodEnum<{
208
+ initial_capture: "initial_capture";
209
+ pre_dispatch: "pre_dispatch";
210
+ post_action: "post_action";
211
+ }>;
212
+ samples: z.ZodNumber;
213
+ action: z.ZodOptional<z.ZodEnum<{
214
+ type: "type";
215
+ key: "key";
216
+ unknown: "unknown";
217
+ answer: "answer";
218
+ wait: "wait";
219
+ typeText: "typeText";
220
+ batch: "batch";
221
+ terminate: "terminate";
222
+ activate: "activate";
223
+ showMenu: "showMenu";
224
+ click: "click";
225
+ drag: "drag";
226
+ setValue: "setValue";
227
+ pressKeys: "pressKeys";
228
+ scroll: "scroll";
229
+ activateSequence: "activateSequence";
230
+ interact: "interact";
231
+ takeover: "takeover";
232
+ finished: "finished";
233
+ button_plan: "button_plan";
234
+ activate_sequence: "activate_sequence";
235
+ show_menu: "show_menu";
236
+ set_value: "set_value";
237
+ left_click: "left_click";
238
+ right_click: "right_click";
239
+ double_click: "double_click";
240
+ hscroll: "hscroll";
241
+ }>>;
242
+ changes: z.ZodArray<z.ZodEnum<{
243
+ window_identity: "window_identity";
244
+ window_geometry: "window_geometry";
245
+ image_dimensions: "image_dimensions";
246
+ accessibility_structure: "accessibility_structure";
247
+ accessibility_text: "accessibility_text";
248
+ accessibility_state: "accessibility_state";
249
+ accessibility_geometry: "accessibility_geometry";
250
+ visual_or_unexposed_state: "visual_or_unexposed_state";
251
+ deadline: "deadline";
252
+ }>>;
253
+ changedElementIndices: z.ZodArray<z.ZodNumber>;
254
+ }, z.core.$strict>>;
85
255
  httpStatus: z.ZodOptional<z.ZodNumber>;
86
256
  requestId: z.ZodOptional<z.ZodString>;
87
257
  serviceErrorCode: z.ZodOptional<z.ZodEnum<{
@@ -15,6 +15,7 @@ import { ComputerNativeTimingSchema, ComputerSessionDiagnostics } from "./diagno
15
15
  import { executeComputerProgram } from "./program-runtime.js";
16
16
  import { ComputerExpectationSchema, ComputerTaskState, verifyComputerExpectation } from "./task-state.js";
17
17
  import { executeComputerBatch } from "./batch.js";
18
+ import { ComputerStabilityTracker } from "./stability-diagnostics.js";
18
19
  import { randomUUID } from "node:crypto";
19
20
  import { z } from "zod";
20
21
  import { setTimeout } from "node:timers/promises";
@@ -720,7 +721,7 @@ var ComputerRuntime = class {
720
721
  expect: context.expectation,
721
722
  flowId: context.flowId
722
723
  };
723
- this.reserveRescue(s, signal);
724
+ this.reserveRescue(s, signal, result.diagnostic);
724
725
  } else if (status.value.status !== "ready") return this.present(status.value);
725
726
  if (input.op === "step") {
726
727
  if (input.flowId || s.lastFlowId) s.adapter?.reset?.();
@@ -741,6 +742,7 @@ var ComputerRuntime = class {
741
742
  owner
742
743
  }, signal);
743
744
  try {
745
+ if (observed.value.diagnostic && observed.value.errorCode) throw new ComputerOperationError(observed.value.diagnostic);
744
746
  const verification = verifyComputerExpectation(input.expect, observed.value.observation);
745
747
  if (input.op === "observe") s.diagnostics.verify(verification);
746
748
  if (input.op === "observe" && !input.question) return {
@@ -859,7 +861,7 @@ var ComputerRuntime = class {
859
861
  phase = "dispatch";
860
862
  const result = await this.dispatchAction(s, e, signal, goalContext);
861
863
  if (!this.isUndispatchedChange(result)) return result;
862
- this.reserveRescue(s, signal);
864
+ this.reserveRescue(s, signal, result.diagnostic);
863
865
  } finally {
864
866
  observed.frame?.fill(0);
865
867
  }
@@ -878,12 +880,15 @@ var ComputerRuntime = class {
878
880
  isUndispatchedChange(result) {
879
881
  return result.status === "ready" && result.errorCode === "COMPUTER_OBSERVATION_CHANGED" && !result.receipt;
880
882
  }
881
- reserveRescue(s, signal) {
883
+ reserveRescue(s, signal, diagnostic) {
882
884
  signal.throwIfAborted();
883
885
  const limit = Math.min(s.rescueLimit, this.getConfig().computer.maxRescuesPerSession);
884
886
  if (s.rescues >= limit) {
885
887
  s.diagnostics.count("rescueExhaustions");
886
- throw new Error("COMPUTER_UI_UNSTABLE");
888
+ throw diagnostic ? new ComputerOperationError({
889
+ ...diagnostic,
890
+ errorCode: "COMPUTER_UI_UNSTABLE"
891
+ }) : /* @__PURE__ */ new Error("COMPUTER_UI_UNSTABLE");
887
892
  }
888
893
  s.rescues++;
889
894
  s.diagnostics.count("rescueAttempts");
@@ -925,8 +930,10 @@ var ComputerRuntime = class {
925
930
  const receipt = reply.value.receipt;
926
931
  const nativeMs = reply.value.nativeMs;
927
932
  let stable = false;
933
+ const stability = new ComputerStabilityTracker("post_action", envelope.action.kind);
928
934
  try {
929
935
  for (let sample = 0; sample < 3; sample++) {
936
+ await setTimeout(100, void 0, { signal });
930
937
  const next = await this.send(s, {
931
938
  op: "observe",
932
939
  sessionId: s.id,
@@ -942,22 +949,43 @@ var ComputerRuntime = class {
942
949
  nativeMs
943
950
  }
944
951
  };
952
+ if (reply.value.diagnostic?.stability) reply.value.diagnostic = {
953
+ ...reply.value.diagnostic,
954
+ stability: {
955
+ ...reply.value.diagnostic.stability,
956
+ stage: "post_action",
957
+ action: envelope.action.kind
958
+ }
959
+ };
945
960
  previous.frame?.fill(0);
946
961
  if (previous.value.brokerEpoch !== next.value.brokerEpoch || previous.value.generation !== next.value.generation || previous.value.grantId !== next.value.grantId) {
947
962
  reply.value.errorCode = "COMPUTER_GRANT_REVOKED";
948
963
  break;
949
964
  }
950
965
  const a = previous.value.observation, b = next.value.observation;
966
+ if (a && b) stability.compare(a, b);
951
967
  stable = next.value.status === "ready" && !next.value.errorCode && !!a && !!b && previous.value.brokerEpoch === next.value.brokerEpoch && previous.value.generation === next.value.generation && previous.value.grantId === next.value.grantId && a.stateDigest === b.stateDigest && JSON.stringify(a.target) === JSON.stringify(b.target);
952
968
  if (stable || next.value.status !== "ready" || next.value.errorCode) break;
953
969
  }
954
- if (!stable && !reply.value.errorCode) reply.value.errorCode = "COMPUTER_UI_UNSTABLE";
955
- } catch {
970
+ if (!stable && !reply.value.errorCode) {
971
+ reply.value.errorCode = "COMPUTER_UI_UNSTABLE";
972
+ reply.value.diagnostic = stability.diagnostic("COMPUTER_UI_UNSTABLE", 4);
973
+ }
974
+ } catch (error) {
956
975
  reply.frame?.fill(0);
976
+ const diagnostic = computerDiagnostic(error);
957
977
  reply = { value: {
958
978
  ...reply.value,
959
979
  receipt,
960
- errorCode: signal?.aborted ? "COMPUTER_OPERATION_ABORTED" : "COMPUTER_POST_ACTION_OBSERVATION_FAILED"
980
+ errorCode: signal?.aborted ? "COMPUTER_OPERATION_ABORTED" : diagnostic?.errorCode ?? "COMPUTER_POST_ACTION_OBSERVATION_FAILED",
981
+ ...diagnostic ? { diagnostic: {
982
+ ...diagnostic,
983
+ ...diagnostic.stability ? { stability: {
984
+ ...diagnostic.stability,
985
+ stage: "post_action",
986
+ action: envelope.action.kind
987
+ } } : {}
988
+ } } : {}
961
989
  } };
962
990
  }
963
991
  }
@@ -984,7 +1012,7 @@ var ComputerRuntime = class {
984
1012
  const verification = verifyComputerExpectation(context?.expectation, reply.value.observation, context?.before);
985
1013
  if (reply.value.receipt) s.diagnostics.record(reply.value.receipt, context?.before, reply.value.observation, verification);
986
1014
  const failureCode = reply.value.errorCode ?? (reply.value.receipt?.dispatch === "unknown" || reply.value.receipt?.dispatch === "started" ? reply.value.receipt.errorCode ?? "COMPUTER_NATIVE_ACTION_FAILED" : void 0);
987
- if (failureCode) s.diagnostics.fail(new Error(failureCode), "dispatch", reply.value.receipt?.dispatch ?? "notStarted");
1015
+ if (failureCode) s.diagnostics.fail(reply.value.diagnostic ? new ComputerOperationError(reply.value.diagnostic) : new Error(failureCode), "dispatch", reply.value.receipt?.dispatch ?? "notStarted");
988
1016
  if (context && reply.value.receipt) {
989
1017
  s.task.record(context.goal, envelope.action, context.before, reply.value.receipt, reply.value.observation, verification);
990
1018
  s.flowCapture.record(envelope.action, context.before, reply.value.receipt, reply.value.observation, context.expectation, verification);