@xopcai/xopc 0.0.291 → 0.0.293

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 (148) hide show
  1. package/dist/browser-ext/dist/assets/{auth-B2CDTr_F.js → auth-C8gJZEsn.js} +13 -2
  2. package/dist/browser-ext/dist/background.js +5 -2
  3. package/dist/browser-ext/dist/sidepanel.html +1 -1
  4. package/dist/browser-ext/dist/sidepanel.js +1 -1
  5. package/dist/browser-ext/manifest.json +1 -1
  6. package/dist/extensions/telegram/xopc.extension.json +1 -1
  7. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BCtrkF15.js → agent-avatar-dicebear-DBoiUaYJ.js} +1 -1
  8. package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-D2eYNelh.js → agent-defaults-settings-panel-BBBTq1DQ.js} +1 -1
  9. package/dist/gateway/static/root/assets/{agents-BedA5XwI.js → agents-DLyyYg6o.js} +1 -1
  10. package/dist/gateway/static/root/assets/{app-management-settings-panel-Md562Fo-.js → app-management-settings-panel-Dt33QQO_.js} +1 -1
  11. package/dist/gateway/static/root/assets/{appearance-settings-BiBFI4BM.js → appearance-settings-TbZePT0h.js} +1 -1
  12. package/dist/gateway/static/root/assets/{apps-page-Corla83b.js → apps-page-D1xQLM8o.js} +1 -1
  13. package/dist/gateway/static/root/assets/{archive-plugin-A_Unp751.js → archive-plugin-BlhqSDGJ.js} +1 -1
  14. package/dist/gateway/static/root/assets/{attachment-load-D6idSUyP.js → attachment-load-DYN6uTdY.js} +1 -1
  15. package/dist/gateway/static/root/assets/{automations-page-C6j71Lgs.js → automations-page-vR2Ox-54.js} +1 -1
  16. package/dist/gateway/static/root/assets/{automations-workspace-DjZdhLQ5.js → automations-workspace-Bq2HWxpx.js} +1 -1
  17. package/dist/gateway/static/root/assets/{binary-plugins-BkKYh-8v.js → binary-plugins-BwJI5t0J.js} +1 -1
  18. package/dist/gateway/static/root/assets/{block-editor-CDcMvaku.js → block-editor-CSVyQoll.js} +1 -1
  19. package/dist/gateway/static/root/assets/{browser-automations-page-C64k4TBH.js → browser-automations-page-BZ3-XyQW.js} +1 -1
  20. package/dist/gateway/static/root/assets/{browser-settings-page-1k5rj_qR.js → browser-settings-page-BIJNmJgx.js} +1 -1
  21. package/dist/gateway/static/root/assets/{capabilities-settings-panel-B2NvoTYb.js → capabilities-settings-panel-B9gmXaV6.js} +1 -1
  22. package/dist/gateway/static/root/assets/{channels-settings-DExixzp4.js → channels-settings-CVbrTHRw.js} +1 -1
  23. package/dist/gateway/static/root/assets/{chat-terminal-dock-B9eKFkbg.js → chat-terminal-dock-BraLmomg.js} +1 -1
  24. package/dist/gateway/static/root/assets/{computer-model-settings-DW6j2lsn.js → computer-model-settings-DgLCyFBM.js} +1 -1
  25. package/dist/gateway/static/root/assets/{computer-settings-page-C2Qyw63Q.js → computer-settings-page-BnbrU0bt.js} +1 -1
  26. package/dist/gateway/static/root/assets/{connectors-page-C3ubZz7K.js → connectors-page-D1fqQ8a3.js} +1 -1
  27. package/dist/gateway/static/root/assets/{date-picker-BdxjXVKL.js → date-picker-C2z8-QnA.js} +1 -1
  28. package/dist/gateway/static/root/assets/{dependency-picker-CXOa4uh4.js → dependency-picker-BsC_4LIh.js} +1 -1
  29. package/dist/gateway/static/root/assets/{desktop-pet-CBWiAaSv.js → desktop-pet-Dk0QTgXU.js} +1 -1
  30. package/dist/gateway/static/root/assets/{desktop-pet-settings-BX1aILDK.js → desktop-pet-settings-Dj7bIWMk.js} +1 -1
  31. package/dist/gateway/static/root/assets/{device-pairing-wizard-bqm_Yf4i.js → device-pairing-wizard-BpJkOK07.js} +1 -1
  32. package/dist/gateway/static/root/assets/{extension-debug-page-B4MMerja.js → extension-debug-page-C-A8q7eR.js} +1 -1
  33. package/dist/gateway/static/root/assets/{extension-page-B3ZtINak.js → extension-page-BQitxYaL.js} +1 -1
  34. package/dist/gateway/static/root/assets/{extension-settings-page-8BkQVh0z.js → extension-settings-page-C1TqQn1x.js} +1 -1
  35. package/dist/gateway/static/root/assets/{gateway-settings-ZyhacQX5.js → gateway-settings-B6zLZO7B.js} +1 -1
  36. package/dist/gateway/static/root/assets/{heartbeat-settings-Bllcxm2A.js → heartbeat-settings-CB9zJjx1.js} +1 -1
  37. package/dist/gateway/static/root/assets/{home-page-Cv2e8XBR.js → home-page-C5CwdYuu.js} +1 -1
  38. package/dist/gateway/static/root/assets/{index-BD5uNzie.css → index-Ds8Q4MZJ.css} +1 -1
  39. package/dist/gateway/static/root/assets/{index-B7EieIE4.js → index-im9qTn_e.js} +43 -43
  40. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-6A6JOHTI.js → keyboard-shortcuts-settings-DpmGojOS.js} +1 -1
  41. package/dist/gateway/static/root/assets/{local-app-workbench-page-Cipj52Zq.js → local-app-workbench-page-BAnnVjV6.js} +1 -1
  42. package/dist/gateway/static/root/assets/{local-apps-page-bD-m7YHJ.js → local-apps-page-DVWnUNKI.js} +1 -1
  43. package/dist/gateway/static/root/assets/{logs-page-D5feO2yw.js → logs-page-BuuEU9H4.js} +1 -1
  44. package/dist/gateway/static/root/assets/{management-settings-B7mz0_44.js → management-settings-DuPqqO2p.js} +1 -1
  45. package/dist/gateway/static/root/assets/{media-plugins-DQ2HfMeG.js → media-plugins-C1mHdgxN.js} +1 -1
  46. package/dist/gateway/static/root/assets/{note-detail-panel-DhYJigb3.js → note-detail-panel-CqJWQqLq.js} +3 -3
  47. package/dist/gateway/static/root/assets/{notes-page-Bg5NPUdf.js → notes-page-Dx4LmFQv.js} +1 -1
  48. package/dist/gateway/static/root/assets/{page-tabs-DmG_Qjl8.js → page-tabs-3VB72Q2A.js} +1 -1
  49. package/dist/gateway/static/root/assets/{preview-open-alternatives-Y9J1kjKC.js → preview-open-alternatives-C3gIPd87.js} +1 -1
  50. package/dist/gateway/static/root/assets/{proactive-page-Duc_NQ8l.js → proactive-page-BoXPVmE5.js} +1 -1
  51. package/dist/gateway/static/root/assets/{project-detail-page-DVOiucVA.js → project-detail-page-tD7h3hb1.js} +1 -1
  52. package/dist/gateway/static/root/assets/{projects-page-Dr_kDoCJ.js → projects-page-COURhAyP.js} +1 -1
  53. package/dist/gateway/static/root/assets/{remote-access-hub-hyJ2KKKK.js → remote-access-hub-DW0sfbOM.js} +1 -1
  54. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-DB7J9opJ.js → runtime-tools-settings-panel-Clq1U2Bs.js} +1 -1
  55. package/dist/gateway/static/root/assets/{schema-form-CMYuPOlE.js → schema-form-D29HClcq.js} +1 -1
  56. package/dist/gateway/static/root/assets/{sessions-page-DGsnYcoh.js → sessions-page-CN9mE6lf.js} +1 -1
  57. package/dist/gateway/static/root/assets/settings-advanced-gate-BAkTtjLG.js +1 -0
  58. package/dist/gateway/static/root/assets/{settings-form-section-BayJP08a.js → settings-form-section-BLX6yLkO.js} +1 -1
  59. package/dist/gateway/static/root/assets/{settings-page-CWBqZtt6.js → settings-page-BVrp_njx.js} +1 -1
  60. package/dist/gateway/static/root/assets/{setup-status-panel-C97S5g5c.js → setup-status-panel-BT8UzHXg.js} +1 -1
  61. package/dist/gateway/static/root/assets/{share-preview-page-Wn5bQA-5.js → share-preview-page-DSooDmlI.js} +1 -1
  62. package/dist/gateway/static/root/assets/{shares-settings-pfVzP8F7.js → shares-settings-BQvk7HB9.js} +1 -1
  63. package/dist/gateway/static/root/assets/{skill-reload-api-DDJ0ZKx3.js → skill-reload-api-DPhl0o2K.js} +1 -1
  64. package/dist/gateway/static/root/assets/{skills-page-DbDpLjDW.js → skills-page-BTZgqlu5.js} +1 -1
  65. package/dist/gateway/static/root/assets/{skills-page.utils-DCHY_kou.js → skills-page.utils-DUL2MSIF.js} +1 -1
  66. package/dist/gateway/static/root/assets/{system-settings-panel-DhgITgId.js → system-settings-panel-CLQ0kUhx.js} +1 -1
  67. package/dist/gateway/static/root/assets/{task-detail-page-UqwtiHYu.js → task-detail-page-D-mE7_Y9.js} +1 -1
  68. package/dist/gateway/static/root/assets/{tunnel-api-DJ3gz2tM.js → tunnel-api-Ct6uU5aE.js} +1 -1
  69. package/dist/gateway/static/root/assets/{use-autosave-htvgT192.js → use-autosave-BM4VIISj.js} +1 -1
  70. package/dist/gateway/static/root/assets/{user-model-page-xOsXY_2W.js → user-model-page-BeF3xmRU.js} +1 -1
  71. package/dist/gateway/static/root/assets/{voice-api-key-field-BviJF3Oa.js → voice-api-key-field-Di5bEpbR.js} +1 -1
  72. package/dist/gateway/static/root/assets/{work-discovery-overlay-BOBVNEYZ.js → work-discovery-overlay-BvUDSW1e.js} +1 -1
  73. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-D1N9uUyM.js → workflow-run-setup-panel-4_qbvODo.js} +1 -1
  74. package/dist/gateway/static/root/assets/{workflows-page-2ylzlgkG.js → workflows-page-Dn15wZnh.js} +1 -1
  75. package/dist/gateway/static/root/index.html +2 -2
  76. package/dist/package.js +1 -1
  77. package/dist/packages/computer-control-contract/src/index.js +23 -3
  78. package/dist/packages/realtime-client/src/index.js +9 -2
  79. package/dist/src/agent/agent-manager.js +4 -4
  80. package/dist/src/agent/background-review/run-background-review.js +1 -1
  81. package/dist/src/agent/embedded/model-runtime.js +1 -1
  82. package/dist/src/agent/embedded/run-for-session.js +1 -1
  83. package/dist/src/agent/embedded/run-turn.js +3 -3
  84. package/dist/src/agent/image/tool-model-config.js +1 -1
  85. package/dist/src/agent/mcp/oauth/mcp-oauth-store.js +1 -1
  86. package/dist/src/agent/service.js +2 -2
  87. package/dist/src/agent/session/session-inspector.js +1 -1
  88. package/dist/src/agent/skills/hub-lock.js +1 -1
  89. package/dist/src/agent/tasks/task-judge-service.js +3 -3
  90. package/dist/src/agent/tool-manuals/computer.d.ts +1 -1
  91. package/dist/src/agent/tool-manuals/computer.js +5 -3
  92. package/dist/src/agent/tools/computer-use-tool.js +20 -10
  93. package/dist/src/ai-assist/text-assist.js +1 -1
  94. package/dist/src/auth/credentials.js +2 -2
  95. package/dist/src/auth/oauth/xopc-cloud.js +1 -1
  96. package/dist/src/auth/profiles/store.js +1 -1
  97. package/dist/src/auth/sync-provider-auth.js +2 -2
  98. package/dist/src/browser/providers/browser-ext-install.js +1 -1
  99. package/dist/src/chat-commands/agent-edit.js +1 -1
  100. package/dist/src/cli/commands/agent.js +1 -1
  101. package/dist/src/cli/commands/doctor/checks/provider-auth.js +3 -3
  102. package/dist/src/cli/commands/models.js +1 -1
  103. package/dist/src/computer/broker.js +20 -5
  104. package/dist/src/computer/control-guard.d.ts +2 -0
  105. package/dist/src/computer/control-guard.js +9 -1
  106. package/dist/src/computer/errors.d.ts +17 -0
  107. package/dist/src/computer/errors.js +35 -1
  108. package/dist/src/computer/evaluation.d.ts +66 -0
  109. package/dist/src/computer/evaluation.js +84 -0
  110. package/dist/src/computer/model-adapter.d.ts +56 -14
  111. package/dist/src/computer/model-adapter.js +86 -15
  112. package/dist/src/computer/model-policy.d.ts +11 -0
  113. package/dist/src/computer/model-policy.js +11 -1
  114. package/dist/src/computer/runtime.d.ts +51 -2
  115. package/dist/src/computer/runtime.js +219 -89
  116. package/dist/src/computer/task-state.d.ts +35 -0
  117. package/dist/src/computer/task-state.js +68 -0
  118. package/dist/src/config/index.js +4 -4
  119. package/dist/src/config/loader.js +2 -2
  120. package/dist/src/config/models-json.js +2 -2
  121. package/dist/src/endpoint-tools/upload-service.d.ts +3 -0
  122. package/dist/src/endpoint-tools/upload-service.js +29 -11
  123. package/dist/src/extensions/lockfile.js +1 -1
  124. package/dist/src/gateway/agents-admin.js +1 -1
  125. package/dist/src/gateway/file-path-classifier.js +1 -1
  126. package/dist/src/gateway/hono/app.js +4 -1
  127. package/dist/src/gateway/hono/lib/config-payload.js +1 -1
  128. package/dist/src/gateway/hono/routes/endpoint-compatibility.d.ts +2 -0
  129. package/dist/src/gateway/hono/routes/endpoint-compatibility.js +21 -0
  130. package/dist/src/gateway/hono/routes/endpoint-tools.js +37 -14
  131. package/dist/src/gateway/hono/routes/lazy-bundles.js +8 -0
  132. package/dist/src/gateway/hono/routes/models.js +1 -1
  133. package/dist/src/gateway/service/config-coordinator.js +1 -1
  134. package/dist/src/gateway/service.js +5 -5
  135. package/dist/src/providers/auth-runtime/resolve-auth.js +1 -1
  136. package/dist/src/providers/index.js +2 -2
  137. package/dist/src/providers/model-catalog-persistence.js +1 -1
  138. package/dist/src/providers/model-registry.js +1 -1
  139. package/dist/src/providers/register-runtime-providers.js +1 -1
  140. package/dist/src/realtime/runtime.js +9 -0
  141. package/dist/src/tui/backends/embedded-backend.js +1 -1
  142. package/dist/src/tui/tui-commands.js +1 -1
  143. package/dist/src/tui/tui-startup-resources.js +1 -1
  144. package/dist/src/tui/tui.js +2 -2
  145. package/dist/src/work-discovery/service.js +2 -2
  146. package/dist/src/workflows/service/workflow-run-service.js +1 -1
  147. package/package.json +1 -1
  148. package/dist/gateway/static/root/assets/settings-advanced-gate-DuzZqQMn.js +0 -1
@@ -1,16 +1,21 @@
1
+ import { createLogger } from "../utils/logger/index.js";
2
+ import { init_logger } from "../utils/logger.js";
3
+ import { resolveEffectiveAgentConfigForSession } from "../config/agent-profile.js";
1
4
  import { COMPUTER_CONTROL_TOOL, ComputerAppSchema, ComputerObservationSchema, ComputerWindowSchema, init_src } from "../../packages/computer-control-contract/src/index.js";
2
- import { computerModelProfile, init_model_policy } from "./model-policy.js";
5
+ import { ComputerServiceLimitsSchema, computerModelProfile, init_model_policy } from "./model-policy.js";
3
6
  import { getApiKey, init_providers, resolveModel } from "../providers/index.js";
4
- import { resolveEffectiveAgentConfigForSession } from "../config/agent-profile.js";
5
7
  import { enterComputerControl, leaveComputerControl } from "./control-guard.js";
6
8
  import { ComputerModelAdapter, predictComputerStep, readComputerJson } from "./model-adapter.js";
7
- import { computerRecovery } from "./errors.js";
9
+ import { ComputerDiagnosticSchema, ComputerOperationError, computerDiagnostic, computerRecovery } from "./errors.js";
10
+ import { ComputerExpectationSchema, ComputerTaskState, verifyComputerExpectation } from "./task-state.js";
8
11
  import { randomUUID } from "node:crypto";
9
12
  import { z } from "zod";
10
13
  //#region src/computer/runtime.ts
11
14
  init_src();
12
15
  init_providers();
13
16
  init_model_policy();
17
+ init_logger();
18
+ const log = createLogger("ComputerRuntime");
14
19
  const Reply = z.object({
15
20
  status: z.enum([
16
21
  "pending_authorization",
@@ -26,6 +31,7 @@ const Reply = z.object({
26
31
  grantId: z.string().optional(),
27
32
  observation: ComputerObservationSchema.optional(),
28
33
  errorCode: z.string().optional(),
34
+ diagnostic: ComputerDiagnosticSchema.optional(),
29
35
  apps: z.array(ComputerAppSchema).max(100).optional(),
30
36
  windows: z.array(ComputerWindowSchema).max(100).optional(),
31
37
  receipt: z.object({
@@ -64,11 +70,13 @@ const ComputerUseInputSchema = z.discriminatedUnion("op", [
64
70
  }).strict(),
65
71
  z.object({
66
72
  op: z.literal("observe"),
67
- question: z.string().min(1).max(4e3).optional()
73
+ question: z.string().min(1).max(4e3).optional(),
74
+ expect: ComputerExpectationSchema.optional()
68
75
  }).strict(),
69
76
  z.object({
70
77
  op: z.literal("step"),
71
- goal: z.string().min(1).max(4e3)
78
+ goal: z.string().min(1).max(4e3),
79
+ expect: ComputerExpectationSchema.optional()
72
80
  }).strict(),
73
81
  z.object({ op: z.literal("close") }).strict()
74
82
  ]);
@@ -84,11 +92,25 @@ var ComputerRuntime = class {
84
92
  input = ComputerUseInputSchema.parse(input);
85
93
  if (!owner) throw new Error("COMPUTER_CONVERSATION_REQUIRED");
86
94
  if (input.op === "close") {
87
- const sessionId = this.sessions.get(owner)?.id ?? "none";
88
- await this.close(owner);
89
- return {
95
+ const session = this.sessions.get(owner);
96
+ const sessionId = session?.id ?? "none";
97
+ const handoff = { recentActions: (session?.task.history ?? []).map(({ goal, action, dispatch, outcome, verification }) => ({
98
+ goal,
99
+ action,
100
+ dispatch,
101
+ outcome,
102
+ verification
103
+ })) };
104
+ return await this.close(owner) ? {
90
105
  status: "stopped",
91
- sessionId
106
+ sessionId,
107
+ handoff,
108
+ nextAction: "Desktop control is released. Continue with an appropriate authorized tool; this does not permit bypassing a desktop refusal."
109
+ } : {
110
+ status: "stop_unconfirmed",
111
+ sessionId,
112
+ errorCode: "COMPUTER_RELEASE_UNCONFIRMED",
113
+ nextAction: computerRecovery("COMPUTER_RELEASE_UNCONFIRMED")
92
114
  };
93
115
  }
94
116
  if (this.operations.has(owner)) throw new Error("COMPUTER_BUSY");
@@ -137,6 +159,7 @@ var ComputerRuntime = class {
137
159
  });
138
160
  if (!apiKey) throw new Error("COMPUTER_MODEL_KEY_MISSING");
139
161
  let deployment;
162
+ let serviceLimits;
140
163
  if (model.provider === "xopc-cloud") {
141
164
  const response = await fetch(`${model.baseUrl.replace(/\/$/, "")}/models`, {
142
165
  headers: { Authorization: `Bearer ${apiKey}` },
@@ -147,11 +170,15 @@ var ComputerRuntime = class {
147
170
  await response.body?.cancel();
148
171
  throw new Error("COMPUTER_DEPLOYMENT_UNAVAILABLE");
149
172
  }
150
- const body = await readComputerJson(response, 2 * 1024 * 1024);
151
- deployment = z.object({
173
+ const metadata = (await readComputerJson(response, 2 * 1024 * 1024)).data?.find((item) => item.id === model.id)?.xopc;
174
+ const parsedDeployment = z.object({
152
175
  revision: z.string().regex(/^[a-f0-9]{64}$/),
153
176
  origin: z.string().url()
154
- }).parse(body.data?.find((item) => item.id === model.id)?.xopc?.computerDeployment);
177
+ }).safeParse(metadata?.computerDeployment);
178
+ const parsedLimits = ComputerServiceLimitsSchema.optional().safeParse(metadata?.computerLimits);
179
+ if (!parsedDeployment.success || !parsedLimits.success) throw new Error("COMPUTER_DEPLOYMENT_UNAVAILABLE");
180
+ deployment = parsedDeployment.data;
181
+ serviceLimits = parsedLimits.data;
155
182
  }
156
183
  const adapter = new ComputerModelAdapter({
157
184
  modelId: model.id,
@@ -159,7 +186,8 @@ var ComputerRuntime = class {
159
186
  apiKey,
160
187
  profile,
161
188
  headers: model.headers,
162
- deploymentRevision: deployment?.revision
189
+ deploymentRevision: deployment?.revision,
190
+ maxOutputTokens: Math.min(2048, model.maxTokens ?? 2048, serviceLimits?.maxOutputTokens ?? 2048)
163
191
  });
164
192
  signal.throwIfAborted();
165
193
  s = {
@@ -181,10 +209,14 @@ var ComputerRuntime = class {
181
209
  createdAt: Date.now(),
182
210
  actions: 0,
183
211
  modelRequests: 0,
184
- controller: new AbortController()
212
+ controller: new AbortController(),
213
+ task: new ComputerTaskState(),
214
+ serviceLimits
185
215
  };
186
216
  this.sessions.set(owner, s);
187
- enterComputerControl(owner, () => this.close(owner));
217
+ enterComputerControl(owner, async () => {
218
+ await this.close(owner);
219
+ });
188
220
  }
189
221
  if (!s) throw new Error("COMPUTER_OPEN_REQUIRED");
190
222
  signal = signal ? AbortSignal.any([signal, s.controller.signal]) : s.controller.signal;
@@ -192,6 +224,7 @@ var ComputerRuntime = class {
192
224
  await this.close(owner);
193
225
  throw new Error("COMPUTER_SESSION_BUDGET");
194
226
  }
227
+ let phase = "observe";
195
228
  try {
196
229
  if (input.op === "open") {
197
230
  if (input.appRef !== s.appRef || input.windowRef !== s.windowRef || input.mode !== s.mode || input.prepare !== s.prepare) throw new Error("COMPUTER_CLOSE_BEFORE_TARGET_CHANGE");
@@ -205,8 +238,11 @@ var ComputerRuntime = class {
205
238
  ...s.windowRef ? { windowRef: s.windowRef } : {},
206
239
  model: s.binding
207
240
  }, signal);
208
- if (reply.value.status === "stopped") await this.close(owner);
209
- return this.present(reply.value);
241
+ if (reply.value.status === "stopped") this.forget(s);
242
+ return {
243
+ ...this.present(reply.value),
244
+ ...reply.value.status !== "stopped" ? { budget: this.budget(s) } : {}
245
+ };
210
246
  }
211
247
  const status = await this.send(s, {
212
248
  op: "status",
@@ -214,72 +250,118 @@ var ComputerRuntime = class {
214
250
  owner
215
251
  }, signal);
216
252
  if (status.value.status === "stopped") {
217
- this.sessions.delete(owner);
218
- leaveComputerControl(owner);
253
+ this.forget(s);
219
254
  return this.present(status.value);
220
255
  }
221
256
  if (input.op === "step" && s.mode === "observe") throw new Error("COMPUTER_READ_ONLY");
222
257
  if (s.pending) {
223
258
  if (input.op === "observe") return this.present(status.value);
259
+ phase = "dispatch";
224
260
  return await this.dispatchAction(s, s.pending, signal);
225
261
  }
226
262
  if (status.value.status !== "ready") return this.present(status.value);
227
- const observed = await this.send(s, {
228
- op: "observe",
229
- sessionId: s.id,
230
- owner
231
- }, signal);
232
- try {
233
- if (input.op === "observe" && !input.question) return this.present(observed.value);
234
- if (input.op === "step" && s.actions >= config.computer.maxActionsPerSession) throw new Error("COMPUTER_ACTION_BUDGET");
235
- const o = observed.value.observation;
236
- if (!o || !observed.frame || !observed.mimeType) throw new Error("COMPUTER_FRAME_REQUIRED");
237
- const proposal = await predictComputerStep(s.adapter, {
238
- goal: input.op === "observe" ? input.question : input.goal,
239
- readOnly: input.op === "observe",
240
- image: observed.frame,
241
- mimeType: observed.mimeType,
242
- width: o.imageWidth,
243
- height: o.imageHeight,
244
- summary: o.summary
245
- }, () => {
246
- if (++s.modelRequests > config.computer.maxModelRequests) throw new Error("COMPUTER_MODEL_BUDGET");
247
- }, signal);
248
- if (proposal.kind === "answer") return {
249
- ...this.present(observed.value),
250
- summary: proposal.text,
251
- verified: false
252
- };
253
- if (input.op === "observe") throw new Error("COMPUTER_READ_ONLY_MODEL_OUTPUT");
254
- if (proposal.kind === "finished") return {
255
- status: "model_finished",
263
+ for (let observationAttempt = 0; observationAttempt < 2; observationAttempt++) {
264
+ const observed = await this.send(s, {
265
+ op: "observe",
256
266
  sessionId: s.id,
257
- claimedSuccess: proposal.claimedSuccess,
258
- verified: false
259
- };
260
- if (proposal.kind === "takeover") return {
261
- status: "takeover",
262
- sessionId: s.id,
263
- pending: true,
264
- summary: "The GUI model requests user assistance. Inspect the authorized window locally."
265
- };
266
- const e = {
267
- actionId: randomUUID(),
268
- sessionId: s.id,
269
- observationId: o.id,
270
- brokerEpoch: o.brokerEpoch,
271
- generation: o.generation,
272
- grantId: observed.value.grantId,
273
- deadlineAt: Date.now() + 12e4,
274
- action: proposal.action
275
- };
276
- return await this.dispatchAction(s, e, signal);
277
- } finally {
278
- observed.frame?.fill(0);
267
+ owner
268
+ }, signal);
269
+ try {
270
+ const verification = verifyComputerExpectation(input.expect, observed.value.observation);
271
+ if (input.op === "observe" && !input.question) return {
272
+ ...this.present(observed.value),
273
+ verification,
274
+ verified: verification?.status === "satisfied",
275
+ budget: this.budget(s)
276
+ };
277
+ if (input.op === "step" && verification?.status === "satisfied") return {
278
+ status: "condition_satisfied",
279
+ sessionId: s.id,
280
+ verification,
281
+ verified: true,
282
+ budget: this.budget(s),
283
+ nextAction: "Only the supplied condition was verified. No input was dispatched. Check remaining task requirements before reporting completion."
284
+ };
285
+ if (input.op === "step" && s.actions >= config.computer.maxActionsPerSession) throw new Error("COMPUTER_ACTION_BUDGET");
286
+ const o = observed.value.observation;
287
+ if (!o || !observed.frame || !observed.mimeType) throw new Error("COMPUTER_FRAME_REQUIRED");
288
+ phase = "model";
289
+ const proposal = await predictComputerStep(s.adapter, {
290
+ goal: input.op === "observe" ? input.question : input.goal,
291
+ readOnly: input.op === "observe",
292
+ image: observed.frame,
293
+ mimeType: observed.mimeType,
294
+ width: o.imageWidth,
295
+ height: o.imageHeight,
296
+ summary: o.summary,
297
+ history: s.task.history,
298
+ expectation: input.expect
299
+ }, () => {
300
+ if (++s.modelRequests > config.computer.maxModelRequests) throw new Error("COMPUTER_MODEL_BUDGET");
301
+ }, signal);
302
+ if (proposal.kind === "answer") return {
303
+ ...this.present(observed.value),
304
+ summary: proposal.text,
305
+ verified: false,
306
+ verification,
307
+ budget: this.budget(s)
308
+ };
309
+ if (input.op === "observe") throw new Error("COMPUTER_READ_ONLY_MODEL_OUTPUT");
310
+ if (proposal.kind === "finished") return {
311
+ status: "model_finished",
312
+ sessionId: s.id,
313
+ claimedSuccess: proposal.claimedSuccess,
314
+ verified: false,
315
+ verification,
316
+ budget: this.budget(s),
317
+ nextAction: "The model claim is not proof. Check the requested completion condition using native or artifact evidence before reporting success."
318
+ };
319
+ if (proposal.kind === "takeover") return {
320
+ status: "takeover",
321
+ sessionId: s.id,
322
+ pending: true,
323
+ budget: this.budget(s),
324
+ summary: "The GUI model requests user assistance. Inspect the authorized window locally."
325
+ };
326
+ const e = {
327
+ actionId: randomUUID(),
328
+ sessionId: s.id,
329
+ observationId: o.id,
330
+ brokerEpoch: o.brokerEpoch,
331
+ generation: o.generation,
332
+ grantId: observed.value.grantId,
333
+ deadlineAt: Date.now() + 12e4,
334
+ action: proposal.action
335
+ };
336
+ s.task.assertProgress(proposal.action, o);
337
+ s.pendingContext = {
338
+ goal: input.goal,
339
+ before: o,
340
+ expectation: input.expect
341
+ };
342
+ phase = "dispatch";
343
+ const result = await this.dispatchAction(s, e, signal);
344
+ if (result.status !== "ready" || result.receipt || result.errorCode !== "COMPUTER_OBSERVATION_CHANGED") return result;
345
+ phase = "observe";
346
+ } finally {
347
+ observed.frame?.fill(0);
348
+ }
279
349
  }
350
+ throw new Error("COMPUTER_UI_UNSTABLE");
280
351
  } catch (error) {
352
+ const failure = signal.aborted || computerDiagnostic(error) || error instanceof Error && /^COMPUTER_[A-Z_0-9]+$/.test(error.message) ? error : new ComputerOperationError({
353
+ errorCode: `COMPUTER_${phase.toUpperCase()}_FAILED`,
354
+ phase,
355
+ diagnosticId: randomUUID()
356
+ });
357
+ const diagnostic = computerDiagnostic(failure);
358
+ if (diagnostic) log.warn({
359
+ ...diagnostic,
360
+ conversationId: owner,
361
+ sessionId: s.id
362
+ }, `Computer operation failed: ${diagnostic.errorCode}`);
281
363
  await this.close(owner);
282
- throw error;
364
+ throw failure;
283
365
  }
284
366
  }
285
367
  async dispatchAction(s, envelope, signal) {
@@ -296,8 +378,34 @@ var ComputerRuntime = class {
296
378
  }, signal);
297
379
  if (reply.value.status !== "pending_action") s.pending = void 0;
298
380
  reply.frame?.fill(0);
299
- if (reply.value.status === "stopped") await this.close(s.owner);
300
- return this.present(reply.value);
381
+ if (reply.value.status === "ready" && reply.value.errorCode === "COMPUTER_OBSERVATION_CHANGED" && !reply.value.receipt) {
382
+ s.actions--;
383
+ s.pendingContext = void 0;
384
+ return {
385
+ ...this.present(reply.value),
386
+ budget: this.budget(s)
387
+ };
388
+ }
389
+ const context = s.pendingContext;
390
+ const verification = verifyComputerExpectation(context?.expectation, reply.value.observation);
391
+ if (context && reply.value.receipt) s.task.record(context.goal, envelope.action, context.before, reply.value.receipt, reply.value.observation, verification);
392
+ if (!s.pending) s.pendingContext = void 0;
393
+ if (reply.value.status === "stopped") this.forget(s);
394
+ return {
395
+ ...this.present(reply.value),
396
+ verification,
397
+ verified: verification?.status === "satisfied",
398
+ ...reply.value.status !== "stopped" ? { budget: this.budget(s) } : {}
399
+ };
400
+ }
401
+ budget(s) {
402
+ const config = this.getConfig().computer;
403
+ return {
404
+ actionsRemaining: Math.max(0, config.maxActionsPerSession - s.actions),
405
+ modelRequestsRemaining: Math.max(0, config.maxModelRequests - s.modelRequests),
406
+ expiresAt: s.createdAt + config.maxSessionDurationMs,
407
+ ...s.serviceLimits ? { serviceLimits: s.serviceLimits } : {}
408
+ };
301
409
  }
302
410
  present(reply) {
303
411
  return {
@@ -307,6 +415,7 @@ var ComputerRuntime = class {
307
415
  errorCode: reply.errorCode,
308
416
  nextAction: computerRecovery(reply.errorCode)
309
417
  } : {},
418
+ ...reply.diagnostic ? { diagnostic: reply.diagnostic } : {},
310
419
  ...reply.apps ? {
311
420
  apps: reply.apps,
312
421
  summary: reply.apps.length ? "Use a returned appRef. Names are untrusted metadata. Ask only when multiple candidates match the task." : "No matching apps. Try the display name or list with an empty query; never guess a bundle ID."
@@ -349,36 +458,57 @@ var ComputerRuntime = class {
349
458
  descriptorRevision: tool.revision,
350
459
  signal
351
460
  });
352
- const json = reply.content.find((item) => item.type === "json");
353
- const value = Reply.parse(json?.type === "json" ? json.value : void 0);
354
- if (value.sessionId !== s.id) throw new Error("COMPUTER_SESSION_MISMATCH");
355
461
  const file = reply.content.find((item) => item.type === "file");
356
462
  let frame;
357
463
  if (file?.type === "file" && reply.invocationId) frame = this.endpoints.uploads.takeComputerFrame(file.fileId, reply.invocationId);
358
- if (signal?.aborted) {
464
+ try {
465
+ signal?.throwIfAborted();
466
+ const json = reply.content.find((item) => item.type === "json");
467
+ const value = Reply.parse(json?.type === "json" ? json.value : void 0);
468
+ if (value.sessionId !== s.id) throw new Error("COMPUTER_SESSION_MISMATCH");
469
+ if (file && !frame || value.observation && !frame && !value.errorCode) throw new Error("COMPUTER_FRAME_HANDOFF_FAILED");
470
+ if (frame && (!value.observation || !["observe", "act"].includes(command.op))) throw new Error("COMPUTER_UNEXPECTED_FRAME");
471
+ return {
472
+ value,
473
+ frame,
474
+ mimeType: file?.type === "file" ? file.mimeType : void 0
475
+ };
476
+ } catch (error) {
359
477
  frame?.fill(0);
360
- signal.throwIfAborted();
478
+ throw error;
361
479
  }
362
- return {
363
- value,
364
- frame,
365
- mimeType: file?.type === "file" ? file.mimeType : void 0
366
- };
480
+ }
481
+ forget(s) {
482
+ if (this.sessions.get(s.owner) !== s) return;
483
+ this.sessions.delete(s.owner);
484
+ leaveComputerControl(s.owner);
485
+ s.task.clear();
486
+ s.pendingContext = void 0;
487
+ s.controller.abort();
367
488
  }
368
489
  async close(owner) {
369
490
  this.operations.get(owner)?.abort();
370
491
  const s = this.sessions.get(owner);
371
- if (!s) return;
372
- this.sessions.delete(owner);
373
- leaveComputerControl(owner);
492
+ if (!s) return true;
493
+ s.task.clear();
494
+ s.pendingContext = void 0;
374
495
  s.controller.abort();
375
496
  try {
376
- await this.send(s, {
497
+ if ((await this.send(s, {
377
498
  op: "release",
378
499
  sessionId: s.id,
379
500
  owner
380
- });
381
- } catch {}
501
+ }, AbortSignal.timeout(5e3))).value.status === "stopped") {
502
+ this.forget(s);
503
+ return true;
504
+ }
505
+ } catch (error) {
506
+ if (error instanceof Error && error.message === "COMPUTER_SESSION_NOT_FOUND") {
507
+ this.forget(s);
508
+ return true;
509
+ }
510
+ }
511
+ return false;
382
512
  }
383
513
  async shutdown() {
384
514
  await Promise.all([...new Set([...this.sessions.keys(), ...this.operations.keys()])].map((owner) => this.close(owner)));
@@ -0,0 +1,35 @@
1
+ import { z } from 'zod';
2
+ import type { ComputerAction, ComputerObservation, ComputerReceipt } from '@xopcai/computer-control-contract';
3
+ export declare const ComputerExpectationSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
4
+ kind: z.ZodLiteral<"text">;
5
+ text: z.ZodString;
6
+ }, z.core.$strict>, z.ZodObject<{
7
+ kind: z.ZodLiteral<"field">;
8
+ label: z.ZodString;
9
+ value: z.ZodString;
10
+ }, z.core.$strict>], "kind">;
11
+ export type ComputerExpectation = z.infer<typeof ComputerExpectationSchema>;
12
+ export type ComputerVerification = {
13
+ status: 'satisfied' | 'not_met' | 'unavailable';
14
+ source: 'accessibility';
15
+ scope: 'expectation';
16
+ };
17
+ /** Verify only caller-specified conditions against scoped native evidence, never model prose. */
18
+ export declare function verifyComputerExpectation(expectation: ComputerExpectation | undefined, observation?: ComputerObservation): ComputerVerification | undefined;
19
+ export interface ComputerHistoryEntry {
20
+ goal: string;
21
+ action: ComputerAction['kind'];
22
+ actionPreview: string;
23
+ dispatch: ComputerReceipt['dispatch'];
24
+ outcome: ComputerReceipt['outcome'];
25
+ after: string;
26
+ verification?: ComputerVerification;
27
+ }
28
+ /** Session-local bounded text only. Screenshots and provider responses never enter history. */
29
+ export declare class ComputerTaskState {
30
+ readonly history: ComputerHistoryEntry[];
31
+ private repeated?;
32
+ assertProgress(action: ComputerAction, observation: ComputerObservation): void;
33
+ record(goal: string, action: ComputerAction, before: ComputerObservation, receipt: ComputerReceipt, after?: ComputerObservation, verification?: ComputerVerification): void;
34
+ clear(): void;
35
+ }
@@ -0,0 +1,68 @@
1
+ import { z } from "zod";
2
+ //#region src/computer/task-state.ts
3
+ const ComputerExpectationSchema = z.discriminatedUnion("kind", [z.object({
4
+ kind: z.literal("text"),
5
+ text: z.string().min(1).max(1e3)
6
+ }).strict(), z.object({
7
+ kind: z.literal("field"),
8
+ label: z.string().min(1).max(300),
9
+ value: z.string().max(4e3)
10
+ }).strict()]);
11
+ /** Verify only caller-specified conditions against scoped native evidence, never model prose. */
12
+ function verifyComputerExpectation(expectation, observation) {
13
+ if (!expectation) return;
14
+ const result = (status) => ({
15
+ status,
16
+ source: "accessibility",
17
+ scope: "expectation"
18
+ });
19
+ if (!observation) return result("unavailable");
20
+ try {
21
+ const data = JSON.parse(observation.summary);
22
+ if (!Array.isArray(data.elements) || !data.elements.some((e) => e.role === "AXWindow")) return result("unavailable");
23
+ if (expectation.kind === "text") {
24
+ if (typeof data.text !== "string" || !data.text) return result("unavailable");
25
+ return result(data.text.includes(expectation.text) ? "satisfied" : "not_met");
26
+ }
27
+ const fields = data.elements.filter((e) => ["AXTextField", "AXTextArea"].includes(String(e.role)) && e.label === expectation.label);
28
+ if (fields.length !== 1 || typeof fields[0].value !== "string") return result("unavailable");
29
+ return result(fields[0].value === expectation.value ? "satisfied" : "not_met");
30
+ } catch {
31
+ return result("unavailable");
32
+ }
33
+ }
34
+ /** Session-local bounded text only. Screenshots and provider responses never enter history. */
35
+ var ComputerTaskState = class {
36
+ history = [];
37
+ repeated;
38
+ assertProgress(action, observation) {
39
+ if (action.kind === "wait") return;
40
+ const key = JSON.stringify([action, observation.stateDigest]);
41
+ if (this.repeated?.key === key && this.repeated.count >= 2) throw new Error("COMPUTER_NO_PROGRESS");
42
+ }
43
+ record(goal, action, before, receipt, after, verification) {
44
+ if (receipt.dispatch !== "completed") return;
45
+ const key = JSON.stringify([action, before.stateDigest]);
46
+ if (action.kind !== "wait" && after?.stateDigest === before.stateDigest) this.repeated = {
47
+ key,
48
+ count: this.repeated?.key === key ? this.repeated.count + 1 : 1
49
+ };
50
+ else this.repeated = void 0;
51
+ this.history.push({
52
+ goal: goal.slice(0, 1e3),
53
+ action: action.kind,
54
+ actionPreview: JSON.stringify(action).slice(0, 1e3),
55
+ dispatch: receipt.dispatch,
56
+ outcome: receipt.outcome,
57
+ after: (after?.summary ?? "").slice(0, 2e3),
58
+ verification
59
+ });
60
+ if (this.history.length > 6) this.history.shift();
61
+ }
62
+ clear() {
63
+ this.history.length = 0;
64
+ this.repeated = void 0;
65
+ }
66
+ };
67
+ //#endregion
68
+ export { ComputerExpectationSchema, ComputerTaskState, verifyComputerExpectation };
@@ -2,15 +2,15 @@ import { ENV_VARS, XOPC_DB_FILENAME, resolveHomeDir, resolveStateDir, resolveXop
2
2
  import { TelegramAccountConfigSchema, TelegramConfigSchema, TelegramGroupConfigSchema, TelegramTopicConfigSchema } from "../../extensions/telegram/src/config-schema.js";
3
3
  import { WeixinAccountConfigSchema, WeixinConfigSchema } from "../../extensions/weixin/src/config-schema.js";
4
4
  import { AgentImageGenerationModelSchema, AgentModelRefSchema, AgentModelsSchema, AgentsConfigSchema, BindingMatchSchema, BindingRuleSchema, BindingsConfigSchema, BrowserConfigSchema, ChannelsConfigSchema, CommandsConfigSchema, ConfigSchema, ConnectorsConfigSchema, ExperimentalConfigSchema, ExtensionSecurityConfigSchema, ExtensionSlotsConfigSchema, ExtensionsConfigSchema, GatewayAuthRateLimitSchema, GatewayAuthSchema, GatewayBindModeSchema, GatewayChannelConnectDeferModeSchema, GatewayConfigSchema, GatewayModeSchema, GatewayRemoteSchema, GatewaySecuritySchema, GatewayTailscaleConsentSchema, GatewayTailscaleSchema, GatewayTlsSchema, GatewayTrustedProxySchema, GatewayWebchatConfigSchema, HeartbeatConfigSchema, McpConfigSchema, McpOAuthConfigSchema, McpServerSchema, MediaUnderstandingCapabilitiesSchema, MediaUnderstandingModelSchema, MessagesConfigSchema, ModelCatalogConfigSchema, ModelsDevConfigSchema, ProviderAuthConfigSchema, ProviderAzureConfigSchema, ProviderRequestOverridesSchema, ProvidersConfigSchema, RuntimeToolsConfigSchema, STTConfigSchema, STTFallbackConfigSchema, STTProviderConfigSchema, SearchProviderEntrySchema, SessionConfigSchema, SessionDmScopeSchema, SessionResetByTypeSchema, SessionResetConfigSchema, SessionResetModeSchema, SessionScopeSchema, SessionStorageConfigSchema, TTSConfigSchema, TTSEdgeConfigSchema, TTSFallbackConfigSchema, TTSModelOverridesConfigSchema, TTSProviderConfigSchema, TTSSummarizationConfigSchema, ToolsConfigSchema, ToolsMediaAudioConfigSchema, ToolsMediaConfigSchema, TuiConfigSchema, TunnelConfigSchema, TunnelConsentSchema, UpdateAutoConfigSchema, UpdateConfigSchema, VoiceConfigSchema, VoiceRefinementConfigSchema, WebSearchConfigSchema, WebToolsConfigSchema, WebsiteBlocklistSchema, WorkspaceConfigSchema, WorkspaceImportConfigSchema, getAgentDefaultImageGenerationModelConfig, getAgentDefaultImageModelConfig, getAgentDefaultModelRef, init_schema, parseModelRef } from "./schema.js";
5
- import { clearConfigValueCache, getAllowedCommands, getCacheStats, init_resolve_config_value, resolveConfigValue, resolveHeaders, testApiKeyResolution } from "./resolve-config-value.js";
5
+ import { applyConfigOverrides, getConfigOverrides, resetConfigOverrides, setConfigOverride, unsetConfigOverride } from "./runtime-overrides.js";
6
6
  import { expandWorkspacePathString, init_workspace_path, normalizeWorkspaceDir, resolveWorkspaceRoot } from "./workspace-path.js";
7
7
  import { resolveDefaultAgentWorkspaceDir } from "./workspace-defaults.js";
8
8
  import { resolveAgentDir as resolveAgentDir$1, resolveAgentHomeDir as resolveAgentHomeDir$1, resolveAgentWorkspaceDir } from "../agent/agent-scope.js";
9
+ import { extractProfileAgentId, resolveEffectiveAgentConfigForAgent, resolveEffectiveAgentConfigForSession, resolveEffectiveAgentProfile, resolveEffectiveAgentProfileForSession } from "./agent-profile.js";
9
10
  import { FILENAMES, WORKSPACE_FILES, existsSync, hasBundledExtensionManifest, init_paths, resolveAgentAuthProfilesPath, resolveAgentDir, resolveAgentHomeDir, resolveAgentProfileDir, resolveAgentProfileMarkdownPath, resolveAuthProfilesPath, resolveBinDir, resolveBundledExtensionsDir, resolveBundledSkillsDir, resolveConfigPath, resolveCredentialsDir, resolveExtensionSdkPath, resolveExtensionsDir, resolveExtensionsLockPath, resolveInboxDir, resolveInboxMessagePath, resolveInboxPendingDir, resolveInboxProcessedDir, resolveLogPath, resolveLogsDir, resolveMcpOAuthPath, resolveModelsJsonPath, resolveNodeBinDir, resolveNodeBinPath, resolveNodeToolsDir, resolveNpmBinPath, resolveOAuthPath, resolvePidPath, resolveSkillPath, resolveSkillsCachePath, resolveSkillsDir, resolveSkillsLockPath, resolveSocketPath, resolveStatusPath, resolveToolsDir, resolveWorkspaceExtensionsDir, resolveWorkspaceFile, resolveWorkspaceStateDir, resolveWorkspaceStatePath, resolveXopcBinPath } from "./paths.js";
10
- import { CustomModelSchema, ImageGenerationCapabilitiesSchema, ImageGenerationModelSchema, ImageGenerationProviderSchema, ModelOverrideSchema, ModelsJsonSchema, OpenAICompatSchema, OpenAICompletionsCompatSchema, OpenAIResponsesCompatSchema, OpenRouterRoutingSchema, ProviderConfigSchema, VercelGatewayRoutingSchema, getDefaultModelValues, init_models_json, loadModelsJson, modelsJsonExists, saveModelsJson, validateModelsConfig } from "./models-json.js";
11
11
  import { init_loader, loadConfig, saveConfig } from "./loader.js";
12
- import { applyConfigOverrides, getConfigOverrides, resetConfigOverrides, setConfigOverride, unsetConfigOverride } from "./runtime-overrides.js";
13
- import { extractProfileAgentId, resolveEffectiveAgentConfigForAgent, resolveEffectiveAgentConfigForSession, resolveEffectiveAgentProfile, resolveEffectiveAgentProfileForSession } from "./agent-profile.js";
12
+ import { clearConfigValueCache, getAllowedCommands, getCacheStats, init_resolve_config_value, resolveConfigValue, resolveHeaders, testApiKeyResolution } from "./resolve-config-value.js";
13
+ import { CustomModelSchema, ImageGenerationCapabilitiesSchema, ImageGenerationModelSchema, ImageGenerationProviderSchema, ModelOverrideSchema, ModelsJsonSchema, OpenAICompatSchema, OpenAICompletionsCompatSchema, OpenAIResponsesCompatSchema, OpenRouterRoutingSchema, ProviderConfigSchema, VercelGatewayRoutingSchema, getDefaultModelValues, init_models_json, loadModelsJson, modelsJsonExists, saveModelsJson, validateModelsConfig } from "./models-json.js";
14
14
  import { canonicalizeConfiguredMcpServer, isKnownCliMcpTypeAlias, normalizeConfiguredMcpServers, resolveXopcMcpTransportAlias } from "./mcp-config-normalize.js";
15
15
  import { formatThinkingLevels, listThinkingLevels, normalizeElevatedMode, normalizeReasoningLevel, normalizeThinkLevel, normalizeVerboseLevel, thinkLevelToNumber } from "../agent/transcript/thinking-types.js";
16
16
  import { getWorkspacePath } from "./workspace-path-helpers.js";
@@ -2,10 +2,10 @@ import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
2
2
  import { createLogger } from "../utils/logger/index.js";
3
3
  import { init_logger } from "../utils/logger.js";
4
4
  import { ConfigSchema, init_schema } from "./schema.js";
5
- import { init_write_file_atomic, writeTextAtomic } from "../infra/write-file-atomic.js";
6
5
  import { init_paths, resolveConfigPath } from "./paths.js";
7
- import { init_resolution, setActivePlatformDiscovery } from "../platform/resolution.js";
6
+ import { init_write_file_atomic, writeTextAtomic } from "../infra/write-file-atomic.js";
8
7
  import { assertChannelPluginConfigs, init_validate_channel_configs } from "./validate-channel-configs.js";
8
+ import { init_resolution, setActivePlatformDiscovery } from "../platform/resolution.js";
9
9
  import { dirname } from "path";
10
10
  import { existsSync, mkdirSync, promises, readFileSync } from "fs";
11
11
  import { config } from "dotenv";
@@ -1,7 +1,7 @@
1
1
  import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
2
- import { ComputerProfileSchema, init_src } from "../../packages/computer-control-contract/src/index.js";
3
- import { init_write_file_atomic, writeTextAtomicSync } from "../infra/write-file-atomic.js";
4
2
  import { init_paths, resolveModelsJsonPath } from "./paths.js";
3
+ import { init_write_file_atomic, writeTextAtomicSync } from "../infra/write-file-atomic.js";
4
+ import { ComputerProfileSchema, init_src } from "../../packages/computer-control-contract/src/index.js";
5
5
  import { init_model_policy, isComputerModel } from "../computer/model-policy.js";
6
6
  import { existsSync, readFileSync } from "fs";
7
7
  import { z } from "zod";
@@ -17,6 +17,8 @@ export interface EndpointUploadGrant {
17
17
  expiresAt: number;
18
18
  }
19
19
  export declare class EndpointUploadError extends Error {
20
+ readonly code: 'INVALID_UPLOAD_GRANT' | 'UPLOAD_TOO_LARGE' | 'INVALID_COMPUTER_FRAME' | 'UPLOAD_BUSY';
21
+ constructor(message: string, code?: 'INVALID_UPLOAD_GRANT' | 'UPLOAD_TOO_LARGE' | 'INVALID_COMPUTER_FRAME' | 'UPLOAD_BUSY');
20
22
  }
21
23
  export declare class EndpointUploadService {
22
24
  private readonly rootDir;
@@ -24,6 +26,7 @@ export declare class EndpointUploadService {
24
26
  private readonly files;
25
27
  private readonly frames;
26
28
  private readonly pruneTimer;
29
+ private readonly validatingFrames;
27
30
  constructor(rootDir: string);
28
31
  createGrant(invocationId: string, endpointId: string, now?: number, profile?: 'durable' | 'computer-frame'): EndpointUploadGrant;
29
32
  upload(params: {