@xopcai/xopc 0.0.244 → 0.0.246

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 (209) 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/{activity-store-CAah-_8h.js → activity-store-BlxqErph.js} +1 -1
  4. package/dist/gateway/static/root/assets/{agent-avatar-dicebear-BhXGsupm.js → agent-avatar-dicebear-CJJzpYYS.js} +1 -1
  5. package/dist/gateway/static/root/assets/{agent-defaults-settings-panel-Blzn2H6t.js → agent-defaults-settings-panel-0dRjnL2s.js} +1 -1
  6. package/dist/gateway/static/root/assets/{agents-Cmp-z8Y_.js → agents-je3sRGmk.js} +1 -1
  7. package/dist/gateway/static/root/assets/{api-B2tKxbcz.js → api-BbXzyQMj.js} +1 -1
  8. package/dist/gateway/static/root/assets/{app-management-settings-panel-CezjAP1K.js → app-management-settings-panel-Cnn3i00c.js} +1 -1
  9. package/dist/gateway/static/root/assets/{appearance-settings-C-CfS05x.js → appearance-settings-BToQaw_v.js} +1 -1
  10. package/dist/gateway/static/root/assets/{apps-page-7Y13_bqZ.js → apps-page-EpUZsl4h.js} +1 -1
  11. package/dist/gateway/static/root/assets/{archive-plugin-BmSx7wzY.js → archive-plugin-DD2SweEH.js} +1 -1
  12. package/dist/gateway/static/root/assets/{attachment-load-DI4CoIga.js → attachment-load-BFtcib5t.js} +1 -1
  13. package/dist/gateway/static/root/assets/{automations-page-D04Xceck.js → automations-page-XS8wIl5o.js} +1 -1
  14. package/dist/gateway/static/root/assets/{automations-workspace-wEO1OWk0.js → automations-workspace-BGQdHrip.js} +1 -1
  15. package/dist/gateway/static/root/assets/{binary-plugins-BJQe8TRu.js → binary-plugins-Xs7pLHxR.js} +1 -1
  16. package/dist/gateway/static/root/assets/{block-editor-BSzGjJC6.js → block-editor-BPdSzceB.js} +1 -1
  17. package/dist/gateway/static/root/assets/{browser-settings-page-DjAZ_LF2.js → browser-settings-page-DJGcm7rH.js} +1 -1
  18. package/dist/gateway/static/root/assets/{browser-workflow-inputs-CRnkgZHI.js → browser-workflow-inputs-BAAc151l.js} +1 -1
  19. package/dist/gateway/static/root/assets/{browser-workflows-page-CwbxA3B7.js → browser-workflows-page-DUPPvE30.js} +1 -1
  20. package/dist/gateway/static/root/assets/{capabilities-settings-panel-jt9bqUMK.js → capabilities-settings-panel-cl9kYilL.js} +1 -1
  21. package/dist/gateway/static/root/assets/{channels-settings-Cz_TWY3a.js → channels-settings-BcIr-_GM.js} +1 -1
  22. package/dist/gateway/static/root/assets/{channels-status-swr-DuY4MGxe.js → channels-status-swr-CCBCtLDg.js} +1 -1
  23. package/dist/gateway/static/root/assets/{chat-terminal-dock-D3gj2D3U.js → chat-terminal-dock-DKW1M6aJ.js} +1 -1
  24. package/dist/gateway/static/root/assets/{connectors-page-Shs5vbzx.js → connectors-page-DNHqaZfX.js} +1 -1
  25. package/dist/gateway/static/root/assets/{cron-expression-DgWHw0jX.js → cron-expression-Bijb0ZQu.js} +1 -1
  26. package/dist/gateway/static/root/assets/{date-picker-CKg-RPbs.js → date-picker-BZuHw-SY.js} +1 -1
  27. package/dist/gateway/static/root/assets/{dependency-picker-CVYkw-NN.js → dependency-picker-BsBD2JFY.js} +1 -1
  28. package/dist/gateway/static/root/assets/{desktop-pet-Bf46oXTY.js → desktop-pet-Ceuw3QKb.js} +1 -1
  29. package/dist/gateway/static/root/assets/{desktop-pet-settings-BJO_klc7.js → desktop-pet-settings-DctOXexM.js} +1 -1
  30. package/dist/gateway/static/root/assets/{extension-debug-page-T2PmFFOW.js → extension-debug-page-BNlMPATK.js} +1 -1
  31. package/dist/gateway/static/root/assets/{extension-page-2wAE2RCe.js → extension-page-CK4Uvzge.js} +1 -1
  32. package/dist/gateway/static/root/assets/{extension-settings-page-Y9ZiCJ21.js → extension-settings-page-CpnXXemw.js} +1 -1
  33. package/dist/gateway/static/root/assets/{gateway-config-api-DaYY1Gkn.js → gateway-config-api-C_mlpe-r.js} +1 -1
  34. package/dist/gateway/static/root/assets/{gateway-config-swr-BC3pgb_P.js → gateway-config-swr-826dipyU.js} +1 -1
  35. package/dist/gateway/static/root/assets/{gateway-settings-eO3IzW_J.js → gateway-settings-DSSW17ed.js} +1 -1
  36. package/dist/gateway/static/root/assets/{gateway-startup-retry-uMcSfLru.js → gateway-startup-retry-DyvcAIMm.js} +1 -1
  37. package/dist/gateway/static/root/assets/{heartbeat-settings-BAgrkyHc.js → heartbeat-settings-hbmIZTpg.js} +1 -1
  38. package/dist/gateway/static/root/assets/{home-page-GTjKH7LK.js → home-page-CaVvW77l.js} +1 -1
  39. package/dist/gateway/static/root/assets/{image-generation-api-D1qlQA-A.js → image-generation-api-D7cyfks6.js} +1 -1
  40. package/dist/gateway/static/root/assets/{index-DUz0O54y.js → index-eZjksPvq.js} +10 -10
  41. package/dist/gateway/static/root/assets/{keyboard-shortcuts-settings-CWGqL6o5.js → keyboard-shortcuts-settings-BQrDwwgi.js} +1 -1
  42. package/dist/gateway/static/root/assets/{local-app-workbench-page-DKJ-rks0.js → local-app-workbench-page-D3K1XmOM.js} +1 -1
  43. package/dist/gateway/static/root/assets/{local-apps-page-Bfidv29d.js → local-apps-page-D-YWD6LS.js} +1 -1
  44. package/dist/gateway/static/root/assets/{locale-store-CMZljTJx.js → locale-store-CBoCuIMx.js} +1 -1
  45. package/dist/gateway/static/root/assets/{logs-page-DwAHrPbF.js → logs-page-DvLc9l59.js} +1 -1
  46. package/dist/gateway/static/root/assets/{management-settings-BG7j1I9f.js → management-settings-DsULLUUv.js} +1 -1
  47. package/dist/gateway/static/root/assets/{markdown-split-AnmmpLs6.js → markdown-split-CjqlP6IB.js} +1 -1
  48. package/dist/gateway/static/root/assets/{markdown-view-PPCLt7fu.js → markdown-view-BXsHghJd.js} +1 -1
  49. package/dist/gateway/static/root/assets/{media-plugins-CGS-05cE.js → media-plugins-DQL029DU.js} +1 -1
  50. package/dist/gateway/static/root/assets/messages-BbdwoxVo.js +3 -0
  51. package/dist/gateway/static/root/assets/{mobile-pairing-wizard-DoKK5GfV.js → mobile-pairing-wizard-gauprAae.js} +1 -1
  52. package/dist/gateway/static/root/assets/models-hub-cache-88f4fzYS.js +1 -0
  53. package/dist/gateway/static/root/assets/{notes-page-Lr8rsFAR.js → notes-page-AsEfLZt9.js} +1 -1
  54. package/dist/gateway/static/root/assets/{notes-workbench-ISWnKLxO.js → notes-workbench-CI30cDh3.js} +2 -2
  55. package/dist/gateway/static/root/assets/{oauth-api-4VeMbkTJ.js → oauth-api-BjSUDIgq.js} +1 -1
  56. package/dist/gateway/static/root/assets/{product-open-page-BU0HiZtv.js → product-open-page-CAJeUXeU.js} +1 -1
  57. package/dist/gateway/static/root/assets/{project-detail-page-BZqr4yam.js → project-detail-page-jO_4I5zN.js} +1 -1
  58. package/dist/gateway/static/root/assets/{projects-page-Dau8733A.js → projects-page-BrTGFME0.js} +1 -1
  59. package/dist/gateway/static/root/assets/{registry-api-CWOtPFrE.js → registry-api-BhGKnvLP.js} +1 -1
  60. package/dist/gateway/static/root/assets/{remote-access-hub-DdChlvGP.js → remote-access-hub-CH70D5SH.js} +1 -1
  61. package/dist/gateway/static/root/assets/{runtime-tools-settings-panel-CmZTNv1W.js → runtime-tools-settings-panel-DH6EilMV.js} +1 -1
  62. package/dist/gateway/static/root/assets/{schema-form-XlVPyiVQ.js → schema-form-DYHmEZeZ.js} +1 -1
  63. package/dist/gateway/static/root/assets/{sessions-page-C3kADsd4.js → sessions-page-hbfUNtNs.js} +1 -1
  64. package/dist/gateway/static/root/assets/settings-advanced-gate-Vg3_jua6.js +1 -0
  65. package/dist/gateway/static/root/assets/{settings-page-DblUeM3V.js → settings-page-BHwPd_M3.js} +1 -1
  66. package/dist/gateway/static/root/assets/{setup-status-panel-bDfRfSnq.js → setup-status-panel-DkcpWSss.js} +1 -1
  67. package/dist/gateway/static/root/assets/{share-preview-page-DBMWFMN-.js → share-preview-page-BjwrS03F.js} +1 -1
  68. package/dist/gateway/static/root/assets/{shares-settings-Bu6lIStj.js → shares-settings-BL4DEt6p.js} +1 -1
  69. package/dist/gateway/static/root/assets/skill-reload-api-CafhNktn.js +1 -0
  70. package/dist/gateway/static/root/assets/{skills-page-CSOseeQe.js → skills-page-OHyK25op.js} +1 -1
  71. package/dist/gateway/static/root/assets/{skills-page.utils-CniRGhkJ.js → skills-page.utils-DQx9ulmg.js} +1 -1
  72. package/dist/gateway/static/root/assets/{system-settings-panel-D0GqNpKy.js → system-settings-panel-wO7DWv4C.js} +1 -1
  73. package/dist/gateway/static/root/assets/{task-detail-page-BRCq-nR7.js → task-detail-page-anyomXsu.js} +1 -1
  74. package/dist/gateway/static/root/assets/{theme-store-uxUwr10D.js → theme-store-hybK3oC9.js} +1 -1
  75. package/dist/gateway/static/root/assets/{tunnel-api-BtjS2nrM.js → tunnel-api-CVC8BHZu.js} +1 -1
  76. package/dist/gateway/static/root/assets/{use-autosave-TwuAycG8.js → use-autosave-DMvRu2XZ.js} +1 -1
  77. package/dist/gateway/static/root/assets/{user-context-page-CbqPu8xZ.js → user-context-page-BBk9YdBn.js} +1 -1
  78. package/dist/gateway/static/root/assets/{voice-api-key-field-CzwG5plu.js → voice-api-key-field-DuBK2NDG.js} +1 -1
  79. package/dist/gateway/static/root/assets/{voice-config-api-MqyI6cgq.js → voice-config-api-CBbiF1T3.js} +1 -1
  80. package/dist/gateway/static/root/assets/{work-discovery-overlay-DS15FzQA.js → work-discovery-overlay-B7VXWpDr.js} +1 -1
  81. package/dist/gateway/static/root/assets/{workflow-run-setup-panel-C_boCemi.js → workflow-run-setup-panel-BokVAsWN.js} +1 -1
  82. package/dist/gateway/static/root/assets/{workflows-page-CaI2ruyy.js → workflows-page-RUTv0yvR.js} +1 -1
  83. package/dist/gateway/static/root/index.html +11 -11
  84. package/dist/package.js +1 -1
  85. package/dist/packages/gateway-contract/src/turn-outcome.js +3 -1
  86. package/dist/src/agent/agent-instance-gateway.d.ts +3 -1
  87. package/dist/src/agent/agent-manager.d.ts +2 -4
  88. package/dist/src/agent/agent-manager.js +24 -28
  89. package/dist/src/agent/background-review/coordinator.js +1 -1
  90. package/dist/src/agent/background-review/run-background-review.js +1 -1
  91. package/dist/src/agent/child-agent-factory.d.ts +10 -7
  92. package/dist/src/agent/child-agent-factory.js +112 -158
  93. package/dist/src/agent/coding/index.d.ts +1 -1
  94. package/dist/src/agent/coding/index.js +2 -2
  95. package/dist/src/agent/coding/repository-instructions.d.ts +12 -0
  96. package/dist/src/agent/coding/repository-instructions.js +76 -0
  97. package/dist/src/agent/coding/run-verification.d.ts +34 -0
  98. package/dist/src/agent/coding/run-verification.js +134 -0
  99. package/dist/src/agent/coding/verification-command.d.ts +3 -0
  100. package/dist/src/agent/coding/verification-command.js +50 -0
  101. package/dist/src/agent/coding/workspace-revision.d.ts +2 -0
  102. package/dist/src/agent/coding/workspace-revision.js +77 -0
  103. package/dist/src/agent/commands/command-isolation.d.ts +21 -0
  104. package/dist/src/agent/commands/command-isolation.js +71 -0
  105. package/dist/src/agent/commands/command-registry.d.ts +56 -0
  106. package/dist/src/agent/commands/command-registry.js +259 -0
  107. package/dist/src/agent/embedded/index.js +1 -1
  108. package/dist/src/agent/embedded/run-for-session.js +2 -1
  109. package/dist/src/agent/embedded/run-turn.js +88 -25
  110. package/dist/src/agent/embedded/session-tool-result-guard.js +2 -2
  111. package/dist/src/agent/embedded/subscribe-session.d.ts +2 -1
  112. package/dist/src/agent/embedded/subscribe-session.js +2 -1
  113. package/dist/src/agent/embedded/types.d.ts +3 -1
  114. package/dist/src/agent/embedded/xopc-tools-bridge.js +4 -1
  115. package/dist/src/agent/image/index.js +1 -1
  116. package/dist/src/agent/index.js +3 -3
  117. package/dist/src/agent/memory/user-context-coordinator.js +1 -1
  118. package/dist/src/agent/middleware/index.d.ts +0 -5
  119. package/dist/src/agent/middleware/index.js +1 -2
  120. package/dist/src/agent/orchestration/agent-event-handler.d.ts +0 -5
  121. package/dist/src/agent/orchestration/agent-event-handler.js +1 -96
  122. package/dist/src/agent/orchestration/agent-orchestrator.js +1 -1
  123. package/dist/src/agent/orchestration/agent-turn-policy.js +5 -5
  124. package/dist/src/agent/orchestration/index.d.ts +1 -1
  125. package/dist/src/agent/orchestration/index.js +2 -2
  126. package/dist/src/agent/orchestration/loop-guard.d.ts +4 -31
  127. package/dist/src/agent/orchestration/loop-guard.js +14 -99
  128. package/dist/src/agent/prompt/sections/tooling.js +2 -4
  129. package/dist/src/agent/sandbox/types.d.ts +2 -2
  130. package/dist/src/agent/sandbox/types.js +1 -1
  131. package/dist/src/agent/service/direct-turn-helpers.js +1 -1
  132. package/dist/src/agent/service/process-direct-streaming.js +1 -1
  133. package/dist/src/agent/service.d.ts +0 -2
  134. package/dist/src/agent/service.js +6 -23
  135. package/dist/src/agent/tasks/task-judge-service.d.ts +7 -0
  136. package/dist/src/agent/tasks/task-judge-service.js +24 -2
  137. package/dist/src/agent/tools/delegate-tool.d.ts +2 -1
  138. package/dist/src/agent/tools/delegate-tool.js +102 -124
  139. package/dist/src/agent/tools/exec-command.d.ts +8 -1
  140. package/dist/src/agent/tools/exec-command.js +77 -169
  141. package/dist/src/agent/tools/executor.js +9 -2
  142. package/dist/src/agent/tools/factory.js +50 -5
  143. package/dist/src/agent/tools/find.d.ts +10 -13
  144. package/dist/src/agent/tools/find.js +33 -80
  145. package/dist/src/agent/tools/grep.d.ts +14 -18
  146. package/dist/src/agent/tools/grep.js +56 -144
  147. package/dist/src/agent/tools/index.d.ts +0 -1
  148. package/dist/src/agent/tools/index.js +2 -3
  149. package/dist/src/agent/tools/language-diagnostics.d.ts +11 -0
  150. package/dist/src/agent/tools/language-diagnostics.js +62 -0
  151. package/dist/src/agent/tools/managed-job-tool.d.ts +2 -1
  152. package/dist/src/agent/tools/managed-job-tool.js +58 -118
  153. package/dist/src/agent/tools/read.js +24 -7
  154. package/dist/src/agent/tools/repository-search.d.ts +5 -0
  155. package/dist/src/agent/tools/repository-search.js +56 -0
  156. package/dist/src/agent/tools/review-workspace.d.ts +2 -0
  157. package/dist/src/agent/tools/review-workspace.js +103 -0
  158. package/dist/src/agent/tools/write.js +4 -4
  159. package/dist/src/agent/transcript/index.js +2 -2
  160. package/dist/src/agent/transcript/transcript-hygiene.js +2 -2
  161. package/dist/src/agent/workflow/subagent-runner.d.ts +0 -2
  162. package/dist/src/agent/workflow/subagent-runner.js +12 -31
  163. package/dist/src/agent-config/schema.d.ts +42 -0
  164. package/dist/src/agent-config/schema.js +5 -0
  165. package/dist/src/cli/commands/agent.js +2 -2
  166. package/dist/src/cli/commands/gateway/lifecycle.js +1 -1
  167. package/dist/src/cli/commands/models.js +1 -1
  168. package/dist/src/cli/commands/onboard.js +1 -1
  169. package/dist/src/cli/commands/profile.js +1 -1
  170. package/dist/src/cli/commands/tunnel.js +1 -1
  171. package/dist/src/cli/commands/update.js +1 -1
  172. package/dist/src/cli/extension-cli-register.js +1 -1
  173. package/dist/src/config/index.js +1 -1
  174. package/dist/src/config/schema.d.ts +28 -0
  175. package/dist/src/execution-environments/local-worktree-manager.d.ts +3 -1
  176. package/dist/src/execution-environments/local-worktree-manager.js +8 -3
  177. package/dist/src/execution-environments/session-environment-service.js +5 -3
  178. package/dist/src/gateway/hono/lib/config-payload.d.ts +7 -0
  179. package/dist/src/gateway/hono/routes/sessions.js +1 -1
  180. package/dist/src/gateway/media-access.js +1 -1
  181. package/dist/src/gateway/run-loop.js +1 -1
  182. package/dist/src/gateway/service/run-gateway-agent.js +4 -1
  183. package/dist/src/gateway/service.js +3 -3
  184. package/dist/src/gateway/session-reset-service.js +1 -1
  185. package/dist/src/gateway/workspace-ripgrep.d.ts +0 -6
  186. package/dist/src/gateway/workspace-ripgrep.js +2 -40
  187. package/dist/src/infra/ripgrep.d.ts +13 -0
  188. package/dist/src/infra/ripgrep.js +46 -0
  189. package/dist/src/proactive/execution/agent-executor.js +1 -1
  190. package/dist/src/session/store.js +1 -1
  191. package/dist/src/session/turn-outcome-projector.js +26 -6
  192. package/dist/src/tasks/task-run-coordinator.d.ts +2 -2
  193. package/dist/src/tasks/task-run-coordinator.js +14 -12
  194. package/dist/src/tui/backends/embedded-backend.js +1 -1
  195. package/dist/src/voice/realtime/agentEngine.d.ts +1 -1
  196. package/dist/src/voice/realtime/runtime.d.ts +3 -68
  197. package/dist/src/voice/realtime/runtime.types.d.ts +69 -0
  198. package/dist/src/voice/realtime/runtime.types.js +1 -0
  199. package/package.json +3 -3
  200. package/dist/gateway/static/root/assets/messages-CTSgFlE4.js +0 -3
  201. package/dist/gateway/static/root/assets/models-hub-cache-ZrbGRiGY.js +0 -1
  202. package/dist/gateway/static/root/assets/settings-advanced-gate-CSYy6SUa.js +0 -1
  203. package/dist/gateway/static/root/assets/skill-reload-api-BNMc4l04.js +0 -1
  204. package/dist/src/agent/coding/turn-diff-tracker.d.ts +0 -67
  205. package/dist/src/agent/coding/turn-diff-tracker.js +0 -231
  206. package/dist/src/agent/middleware/self-verify.d.ts +0 -136
  207. package/dist/src/agent/middleware/self-verify.js +0 -380
  208. package/dist/src/agent/tools/execute-code-tool.d.ts +0 -11
  209. package/dist/src/agent/tools/execute-code-tool.js +0 -208
@@ -1,380 +0,0 @@
1
- import { createLogger } from "../../utils/logger/index.js";
2
- import { init_logger } from "../../utils/logger.js";
3
- //#region src/agent/middleware/self-verify.ts
4
- init_logger();
5
- const log = createLogger("SelfVerifyMiddleware");
6
- const DEFAULT_CONFIG = {
7
- maxEditsPerFile: 5,
8
- enablePreCompletionCheck: true,
9
- minTurnsForVerification: 3,
10
- resetOnVerification: true
11
- };
12
- function createTrackerState() {
13
- return {
14
- fileEdits: /* @__PURE__ */ new Map(),
15
- turnCount: 0,
16
- verificationRequested: false,
17
- hasUnverifiedEdits: false,
18
- diffReviewed: false,
19
- lastVerification: void 0,
20
- lastMutationTool: void 0
21
- };
22
- }
23
- /**
24
- * Tracks file modifications and provides verification guidance
25
- */
26
- var SelfVerifyMiddleware = class {
27
- states = /* @__PURE__ */ new Map();
28
- config;
29
- constructor(config = {}) {
30
- this.config = {
31
- ...DEFAULT_CONFIG,
32
- ...config
33
- };
34
- }
35
- getState(sessionKey) {
36
- const key = sessionKey ?? "default";
37
- let state = this.states.get(key);
38
- if (!state) {
39
- state = createTrackerState();
40
- this.states.set(key, state);
41
- }
42
- return state;
43
- }
44
- /**
45
- * Record a file edit operation
46
- */
47
- recordEdit(filePath, operation, sessionKey) {
48
- const state = this.getState(sessionKey);
49
- const now = Date.now();
50
- const existing = state.fileEdits.get(filePath);
51
- if (existing) {
52
- existing.editCount++;
53
- existing.lastEditTime = now;
54
- if (!existing.operations.includes(operation)) existing.operations.push(operation);
55
- } else state.fileEdits.set(filePath, {
56
- path: filePath,
57
- editCount: 1,
58
- lastEditTime: now,
59
- operations: [operation]
60
- });
61
- state.hasUnverifiedEdits = true;
62
- state.diffReviewed = false;
63
- state.lastMutationTool = operation;
64
- log.debug({
65
- filePath,
66
- editCount: this.getEditCount(filePath, sessionKey),
67
- operation
68
- }, "File edit recorded");
69
- }
70
- recordVerification(toolName, args, task, sessionKey) {
71
- const state = this.getState(sessionKey);
72
- const name = toolName.toLowerCase();
73
- if (name === "exec_command") {
74
- const command = this.extractExecCommand(args, task?.result);
75
- const success = this.isSuccessfulExecVerification(task);
76
- const details = this.extractResultDetails(task?.result);
77
- if (success && this.isDiffReviewCommand(command)) {
78
- state.diffReviewed = true;
79
- return;
80
- }
81
- if (!this.isVerificationCommand(command)) return;
82
- const rawExitCode = details?.exitCode;
83
- let exitCode;
84
- if (typeof rawExitCode === "number") exitCode = rawExitCode;
85
- else if (rawExitCode === null) exitCode = null;
86
- state.lastVerification = {
87
- toolName,
88
- command,
89
- success,
90
- exitCode,
91
- status: typeof details?.status === "string" ? details.status : void 0,
92
- timedOut: details?.timedOut === true
93
- };
94
- if (success) state.hasUnverifiedEdits = false;
95
- return;
96
- }
97
- if (name.includes("test") || name.includes("verify") || name.includes("lint")) {
98
- state.hasUnverifiedEdits = false;
99
- state.lastVerification = {
100
- toolName,
101
- success: true
102
- };
103
- }
104
- }
105
- getVerificationState(sessionKey) {
106
- const state = this.getState(sessionKey);
107
- const changedFiles = Array.from(state.fileEdits.keys()).sort();
108
- const lastVerification = state.lastVerification ? { ...state.lastVerification } : void 0;
109
- return {
110
- hasUnverifiedEdits: state.hasUnverifiedEdits,
111
- changedFiles,
112
- diffReviewed: state.diffReviewed,
113
- verificationAttempted: Boolean(lastVerification),
114
- lastVerificationFailed: Boolean(lastVerification && !lastVerification.success),
115
- lastVerification,
116
- lastMutationTool: state.lastMutationTool
117
- };
118
- }
119
- getPendingVerificationContext(sessionKey, agentId) {
120
- const state = this.getState(sessionKey);
121
- if (!this.config.enablePreCompletionCheck || !state.hasUnverifiedEdits) return "";
122
- return this.buildPendingVerificationReminder(sessionKey, agentId);
123
- }
124
- extractExecCommand(args, result) {
125
- if (args && typeof args === "object") {
126
- const rec = args;
127
- if (typeof rec.cmd === "string") return rec.cmd.toLowerCase();
128
- if (typeof rec.command === "string") return rec.command.toLowerCase();
129
- }
130
- const details = this.extractResultDetails(result);
131
- if (details) {
132
- const command = details.command;
133
- if (typeof command === "string") return command.toLowerCase();
134
- }
135
- return "";
136
- }
137
- extractResultDetails(result) {
138
- if (!result || typeof result !== "object") return null;
139
- const details = result.details;
140
- return details && typeof details === "object" ? details : null;
141
- }
142
- isSuccessfulExecVerification(task) {
143
- if (!task || task.isError) return false;
144
- const details = this.extractResultDetails(task.result);
145
- if (!details) return false;
146
- if (details.timedOut === true) return false;
147
- if (details.status === "success") return true;
148
- return details.exitCode === 0;
149
- }
150
- isVerificationCommand(command) {
151
- return /\b(test|vitest|jest|mocha|ava|playwright|typecheck|type-check|tsc|build|lint)\b/.test(command);
152
- }
153
- isDiffReviewCommand(command) {
154
- return /\bgit\s+(diff|status)\b/.test(command);
155
- }
156
- /**
157
- * Get edit count for a specific file
158
- */
159
- getEditCount(filePath, sessionKey) {
160
- return this.getState(sessionKey).fileEdits.get(filePath)?.editCount || 0;
161
- }
162
- /**
163
- * Check if any file has excessive edits (potential doom loop)
164
- */
165
- hasExcessiveEdits(sessionKey) {
166
- for (const [path, record] of this.getState(sessionKey).fileEdits.entries()) if (record.editCount >= this.config.maxEditsPerFile) return {
167
- file: path,
168
- count: record.editCount
169
- };
170
- return null;
171
- }
172
- /**
173
- * Increment turn counter
174
- */
175
- onTurnStart(sessionKey) {
176
- const state = this.getState(sessionKey);
177
- state.turnCount++;
178
- state.verificationRequested = false;
179
- }
180
- /**
181
- * Reset all tracking (e.g., after successful task completion)
182
- */
183
- reset(sessionKey) {
184
- if (sessionKey) this.states.set(sessionKey, createTrackerState());
185
- else this.states.clear();
186
- log.debug("Self-verify middleware reset");
187
- }
188
- consumePostEditReminder(sessionKey) {
189
- const state = this.getState(sessionKey);
190
- if (!this.config.enablePreCompletionCheck || !state.hasUnverifiedEdits) return "";
191
- if (state.verificationRequested) return "";
192
- state.verificationRequested = true;
193
- return this.buildPendingVerificationReminder(sessionKey);
194
- }
195
- /**
196
- * Get context injection for system prompt
197
- * Adds verification guidance based on current state
198
- */
199
- getContextInjection(sessionKey, agentId) {
200
- const sections = [];
201
- sections.push(this.buildWorkflowGuidance());
202
- const excessive = this.hasExcessiveEdits(sessionKey);
203
- if (excessive) sections.push(this.buildExcessiveEditWarning(excessive.file, excessive.count));
204
- if (this.shouldPromptForVerification(sessionKey)) sections.push(this.buildPreCompletionReminder(sessionKey));
205
- const pending = this.getPendingVerificationContext(sessionKey, agentId);
206
- if (pending) sections.push(pending);
207
- return sections.filter(Boolean).join("\n\n");
208
- }
209
- /**
210
- * Check if we should inject verification reminder
211
- */
212
- shouldPromptForVerification(sessionKey) {
213
- const state = this.getState(sessionKey);
214
- if (!this.config.enablePreCompletionCheck) return false;
215
- if (state.turnCount < this.config.minTurnsForVerification) return false;
216
- if (state.verificationRequested) return false;
217
- return true;
218
- }
219
- /**
220
- * Mark verification as requested (to avoid spam)
221
- */
222
- markVerificationRequested(sessionKey) {
223
- this.getState(sessionKey).verificationRequested = true;
224
- }
225
- /**
226
- * Build workflow guidance section
227
- */
228
- buildWorkflowGuidance() {
229
- return `## Problem Solving Workflow
230
-
231
- Follow this iterative process for all tasks:
232
-
233
- 1. **Plan**: Understand the task, read relevant files, and create a plan
234
- 2. **Build**: Implement your solution with verification in mind
235
- 3. **Verify**: Test your work, run checks, compare against requirements
236
- 4. **Fix**: If issues found, analyze and fix them
237
-
238
- **Important**: Before declaring a task complete:
239
- - Re-read the original requirements
240
- - Verify your solution meets ALL requirements
241
- - Run any available tests or validation
242
- - Check for edge cases
243
-
244
- Do not skip verification. Incomplete verification leads to incorrect solutions.`;
245
- }
246
- classifyAgent(agentId) {
247
- const id = agentId?.trim().toLowerCase() ?? "";
248
- if (!id) return "generic";
249
- if (id.includes("coder") || id.includes("code") || id.includes("developer")) return "coder";
250
- if (id.includes("data") || id.includes("analyst") || id.includes("analysis")) return "data";
251
- if (id.includes("writer") || id.includes("writing")) return "writer";
252
- if (id.includes("research")) return "researcher";
253
- if (id.includes("creative") || id.includes("design")) return "creative";
254
- return "generic";
255
- }
256
- buildPendingVerificationReminder(sessionKey, agentId) {
257
- const state = this.getVerificationState(sessionKey);
258
- const kind = this.classifyAgent(agentId);
259
- const files = state.changedFiles.length > 0 ? state.changedFiles.slice(0, 12).join(", ") : "(unknown files)";
260
- const extraFiles = state.changedFiles.length > 12 ? `, and ${state.changedFiles.length - 12} more` : "";
261
- const profile = this.verificationProfile(kind);
262
- const lines = [
263
- `## ${profile.title}`,
264
- profile.checkLine,
265
- `${profile.changedLabel}: ${files}${extraFiles}.`,
266
- state.diffReviewed ? "Diff review: completed with git diff/status." : "Diff review: not recorded yet."
267
- ];
268
- if (state.lastVerification) {
269
- const command = state.lastVerification.command ? ` (${state.lastVerification.command})` : "";
270
- lines.push(state.lastVerification.success ? `Last verification: passed${command}.` : `Last verification: failed${command}.`);
271
- } else lines.push("Last verification: none recorded.");
272
- lines.push(profile.finalGuidance);
273
- return lines.join("\n");
274
- }
275
- verificationProfile(kind) {
276
- switch (kind) {
277
- case "coder": return {
278
- title: "Coder Verification State",
279
- checkLine: "Coder check: source files changed.",
280
- changedLabel: "Changed source files",
281
- finalGuidance: "Before final response, inspect the diff and run the smallest meaningful code verification, such as a targeted test, typecheck, lint, or build. If verification cannot run, final response must state why and name the remaining risk."
282
- };
283
- case "data": return {
284
- title: "Data Verification State",
285
- checkLine: "Data check: analysis files or outputs changed.",
286
- changedLabel: "Changed files or artifacts",
287
- finalGuidance: "Before final response, inspect the diff or generated outputs and run the smallest meaningful data validation, such as rerunning the analysis, checking row counts, schemas, filters, joins, units, or output files. If validation cannot run, final response must state why and name the remaining risk."
288
- };
289
- case "writer": return {
290
- title: "Writing Review State",
291
- checkLine: "Writing check: draft or document files changed.",
292
- changedLabel: "Changed files or artifacts",
293
- finalGuidance: "Before final response, inspect the changed artifact for requested content, structure, formatting, placeholders, and obvious inconsistencies. If a review cannot be completed, final response must state why and name the remaining risk."
294
- };
295
- case "researcher": return {
296
- title: "Research Review State",
297
- checkLine: "Research check: research notes or report files changed.",
298
- changedLabel: "Changed files or artifacts",
299
- finalGuidance: "Before final response, inspect the changed artifact and verify citations, source-backed claims, unresolved uncertainty, and formatting. If source or artifact review cannot be completed, final response must state why and name the remaining risk."
300
- };
301
- case "creative": return {
302
- title: "Creative Review State",
303
- checkLine: "Creative check: creative artifact files changed.",
304
- changedLabel: "Changed files or artifacts",
305
- finalGuidance: "Before final response, inspect the changed artifact against the brief, requested format, visual/text quality, and any saved outputs. If review cannot be completed, final response must state why and name the remaining risk."
306
- };
307
- default: return {
308
- title: "Workspace Verification State",
309
- checkLine: "Workspace check: files changed.",
310
- changedLabel: "Changed files or artifacts",
311
- finalGuidance: "Before final response, inspect the changed files and run the smallest meaningful verification for this task. If verification cannot run, final response must state why and name the remaining risk."
312
- };
313
- }
314
- }
315
- /**
316
- * Build warning for excessive file edits (doom loop detection)
317
- */
318
- buildExcessiveEditWarning(filePath, count) {
319
- return `⚠️ **Pattern Alert**: You have edited "${filePath}" ${count} times.
320
-
321
- This may indicate:
322
- - You're fixing symptoms rather than root causes
323
- - The approach needs reconsideration
324
- - Requirements may be unclear
325
-
326
- **Recommendation**:
327
- - Step back and re-read the original task
328
- - Consider if there's a better approach
329
- - Verify you understand the requirements correctly`;
330
- }
331
- /**
332
- * Build pre-completion verification reminder
333
- */
334
- buildPreCompletionReminder(sessionKey) {
335
- const state = this.getState(sessionKey);
336
- this.markVerificationRequested(sessionKey);
337
- return `⏳ **Verification Check**: You've made ${state.turnCount} turns on this task.
338
-
339
- Before completing:
340
- 1. ✅ Verify your solution matches the original requirements
341
- 2. ✅ Run tests or validation if available
342
- 3. ✅ Check edge cases and error handling
343
- 4. ✅ Review your changes one final time
344
-
345
- If you're confident, proceed. If unsure, continue refining.`;
346
- }
347
- /**
348
- * Get summary of file edits for debugging
349
- */
350
- getEditSummary(sessionKey) {
351
- const entries = Array.from(this.getState(sessionKey).fileEdits.entries());
352
- const totalEdits = entries.reduce((sum, [, record]) => sum + record.editCount, 0);
353
- const topFiles = entries.sort((a, b) => b[1].editCount - a[1].editCount).slice(0, 5).map(([path, record]) => ({
354
- path,
355
- count: record.editCount
356
- }));
357
- return {
358
- totalFiles: entries.length,
359
- totalEdits,
360
- topFiles
361
- };
362
- }
363
- /**
364
- * Update configuration
365
- */
366
- setConfig(config) {
367
- this.config = {
368
- ...this.config,
369
- ...config
370
- };
371
- }
372
- /**
373
- * Get current configuration
374
- */
375
- getConfig() {
376
- return { ...this.config };
377
- }
378
- };
379
- //#endregion
380
- export { SelfVerifyMiddleware };
@@ -1,11 +0,0 @@
1
- /**
2
- * Programmatic tool calling (PTC): run sandboxed JS that invokes a subset of agent tools.
3
- * vm is not a strong security boundary; only trusted models should use this tool.
4
- */
5
- import type { AgentTool } from '@earendil-works/pi-agent-core';
6
- export declare const SANDBOX_ALLOWED_TOOLS: Set<string>;
7
- export declare function buildSandboxToolMap(tools: AgentTool<any, any>[]): Map<string, AgentTool<any, any>>;
8
- export interface ExecuteCodeToolDeps {
9
- getSandboxToolMap: () => Map<string, AgentTool<any, any>>;
10
- }
11
- export declare function createExecuteCodeTool(deps: ExecuteCodeToolDeps): AgentTool;
@@ -1,208 +0,0 @@
1
- import { Type } from "@sinclair/typebox";
2
- import { Script, createContext } from "node:vm";
3
- //#region src/agent/tools/execute-code-tool.ts
4
- /**
5
- * Programmatic tool calling (PTC): run sandboxed JS that invokes a subset of agent tools.
6
- * vm is not a strong security boundary; only trusted models should use this tool.
7
- */
8
- /** Default script wall time when `timeout` omitted (30 minutes). */
9
- const DEFAULT_TIMEOUT_SEC = 1800;
10
- /** Hard cap for `timeout` parameter (4 hours). */
11
- const MAX_TIMEOUT_SEC = 14400;
12
- const ExecuteCodeSchema = Type.Object({
13
- code: Type.String({ description: "JavaScript to run. Exposed as `tools` (async functions) and `console`:\n await tools.web_search(query, count?)\n await tools.web_fetch(url, maxChars?)\n await tools.read_file(path, limit?)\n await tools.write_file(path, content)\n await tools.grep(pattern, { path?, glob?, ignoreCase?, literal?, context?, limit? })\n await tools.find(pattern, { path?, limit? })\n await tools.exec_command(cmd, cwd?)\n\nUse console.log() for output; combined stdout/stderr is returned." }),
14
- timeout: Type.Optional(Type.Number({
15
- description: "Execution timeout in seconds (default: 1800 = 30m, max: 14400 = 4h)",
16
- default: DEFAULT_TIMEOUT_SEC
17
- }))
18
- });
19
- const SANDBOX_ALLOWED_TOOLS = new Set([
20
- "web_search",
21
- "web_fetch",
22
- "read_file",
23
- "write_file",
24
- "grep",
25
- "find",
26
- "exec_command",
27
- "skills_list",
28
- "skill_view"
29
- ]);
30
- const MAX_TIMEOUT_MS = MAX_TIMEOUT_SEC * 1e3;
31
- const MAX_TOOL_CALLS = 50;
32
- const MAX_STDOUT_CHARS = 5e4;
33
- const MAX_STDERR_CHARS = 1e4;
34
- function stringifyArg(a) {
35
- if (typeof a === "string") return a;
36
- try {
37
- return JSON.stringify(a);
38
- } catch {
39
- return String(a);
40
- }
41
- }
42
- function extractTextFromResult(result) {
43
- return result.content.filter((c) => c.type === "text").map((c) => c.text).join("");
44
- }
45
- function buildSandboxToolMap(tools) {
46
- const m = /* @__PURE__ */ new Map();
47
- for (const t of tools) if (SANDBOX_ALLOWED_TOOLS.has(t.name)) m.set(t.name, t);
48
- return m;
49
- }
50
- function createToolsApi(getMap, signal) {
51
- let seq = 0;
52
- let calls = 0;
53
- const bump = () => {
54
- calls += 1;
55
- if (calls > MAX_TOOL_CALLS) throw new Error(`Exceeded max sandbox tool calls (${MAX_TOOL_CALLS})`);
56
- };
57
- const run = async (name, params) => {
58
- if (signal?.aborted) throw new Error("aborted");
59
- bump();
60
- const tool = getMap().get(name);
61
- if (!tool) throw new Error(`Tool not available in sandbox: ${name}`);
62
- const id = `ptc-${Date.now()}-${seq++}`;
63
- return extractTextFromResult(await tool.execute(id, params, signal));
64
- };
65
- return {
66
- web_search: async (query, count) => run("web_search", {
67
- query: String(query ?? ""),
68
- ...typeof count === "number" && Number.isFinite(count) ? { count } : {}
69
- }),
70
- web_fetch: async (url, maxChars) => run("web_fetch", {
71
- url: String(url ?? ""),
72
- ...typeof maxChars === "number" && Number.isFinite(maxChars) ? { maxChars } : {}
73
- }),
74
- read_file: async (path, limit) => run("read_file", {
75
- path: String(path ?? ""),
76
- ...typeof limit === "number" && Number.isFinite(limit) ? { limit } : {}
77
- }),
78
- write_file: async (path, content) => run("write_file", {
79
- path: String(path ?? ""),
80
- content: String(content ?? "")
81
- }),
82
- grep: async (pattern, opts) => {
83
- const o = opts && typeof opts === "object" && opts !== null ? opts : {};
84
- return run("grep", {
85
- pattern: String(pattern ?? ""),
86
- ...typeof o.path === "string" ? { path: o.path } : {},
87
- ...typeof o.glob === "string" ? { glob: o.glob } : {},
88
- ...typeof o.ignoreCase === "boolean" ? { ignoreCase: o.ignoreCase } : {},
89
- ...typeof o.literal === "boolean" ? { literal: o.literal } : {},
90
- ...typeof o.context === "number" && Number.isFinite(o.context) ? { context: o.context } : {},
91
- ...typeof o.limit === "number" && Number.isFinite(o.limit) ? { limit: o.limit } : {}
92
- });
93
- },
94
- find: async (pattern, opts) => {
95
- const o = opts && typeof opts === "object" && opts !== null ? opts : {};
96
- return run("find", {
97
- pattern: String(pattern ?? ""),
98
- ...typeof o.path === "string" ? { path: o.path } : {},
99
- ...typeof o.limit === "number" && Number.isFinite(o.limit) ? { limit: o.limit } : {}
100
- });
101
- },
102
- exec_command: async (cmd, cwd) => run("exec_command", {
103
- cmd: String(cmd ?? ""),
104
- ...typeof cwd === "string" && cwd.trim() ? { cwd } : {}
105
- })
106
- };
107
- }
108
- async function runSandboxedScript(code, sandbox, timeoutMs, signal) {
109
- const context = createContext(sandbox, { name: "execute_code" });
110
- const runPromise = new Script(`(async () => {\n${code}\n})()`, { filename: "execute_code.vm" }).runInContext(context);
111
- let timeoutId;
112
- const timeoutPromise = new Promise((_, rej) => {
113
- timeoutId = setTimeout(() => rej(/* @__PURE__ */ new Error(`Script timed out after ${Math.round(timeoutMs / 1e3)}s`)), timeoutMs);
114
- });
115
- const abortPromise = signal && new Promise((_, rej) => {
116
- if (signal.aborted) {
117
- rej(/* @__PURE__ */ new Error("aborted"));
118
- return;
119
- }
120
- signal.addEventListener("abort", () => rej(/* @__PURE__ */ new Error("aborted")), { once: true });
121
- });
122
- const racers = [runPromise, timeoutPromise];
123
- if (abortPromise) racers.push(abortPromise);
124
- try {
125
- await Promise.race(racers);
126
- } finally {
127
- if (timeoutId !== void 0) clearTimeout(timeoutId);
128
- }
129
- }
130
- function createExecuteCodeTool(deps) {
131
- return {
132
- name: "execute_code",
133
- label: "⚡ Execute Code",
134
- description: "Run sandboxed JavaScript that calls a subset of tools via `tools.*` (batch work in one step).\n\nOnly stdout/stderr from `console` plus tool return text (as strings) are visible — not full tool JSON.\n\nWHEN TO USE: loops over files/URLs, simple branching between tool calls.\nWHEN NOT TO USE: single tool calls; tasks needing full tool schemas or disallowed tools.\n\nAPI: `await tools.web_search(q, count?)`, `web_fetch(url, maxChars?)`, `read_file(path, limit?)`, `write_file(path, content)`, `grep(pattern, opts?)`, `find(glob, opts?)`, `exec_command(cmd, cwd?)`. Use `console.log` for output.",
135
- parameters: ExecuteCodeSchema,
136
- async execute(_toolCallId, params, signal) {
137
- const p = params;
138
- const sec = p.timeout ?? DEFAULT_TIMEOUT_SEC;
139
- const timeoutMs = Math.min(Math.max(1, Number.isFinite(sec) ? sec : DEFAULT_TIMEOUT_SEC) * 1e3, MAX_TIMEOUT_MS);
140
- const stdout = [];
141
- const stderr = [];
142
- const sandbox = {
143
- tools: createToolsApi(deps.getSandboxToolMap, signal),
144
- Promise,
145
- JSON,
146
- Math,
147
- Date,
148
- Array,
149
- Object,
150
- String,
151
- Number,
152
- Boolean,
153
- RegExp,
154
- Map,
155
- Set,
156
- Error,
157
- TypeError,
158
- RangeError,
159
- parseInt,
160
- parseFloat,
161
- isNaN,
162
- isFinite,
163
- console: {
164
- log: (...args) => {
165
- stdout.push(args.map(stringifyArg).join(" "));
166
- },
167
- error: (...args) => {
168
- stderr.push(args.map(stringifyArg).join(" "));
169
- },
170
- warn: (...args) => {
171
- stderr.push(args.map(stringifyArg).join(" "));
172
- }
173
- },
174
- setTimeout,
175
- clearTimeout
176
- };
177
- try {
178
- await runSandboxedScript(p.code, sandbox, timeoutMs, signal);
179
- let out = stdout.join("\n");
180
- if (out.length > MAX_STDOUT_CHARS) out = `${out.slice(0, MAX_STDOUT_CHARS)}\n...(truncated)`;
181
- const parts = [];
182
- if (out.length > 0) parts.push(out);
183
- if (stderr.length > 0) {
184
- let err = stderr.join("\n");
185
- if (err.length > MAX_STDERR_CHARS) err = `${err.slice(0, MAX_STDERR_CHARS)}\n...(truncated)`;
186
- parts.push(`\nSTDERR:\n${err}`);
187
- }
188
- return {
189
- content: [{
190
- type: "text",
191
- text: parts.join("") || "(no output)"
192
- }],
193
- details: { exitCode: 0 }
194
- };
195
- } catch (error) {
196
- return {
197
- content: [{
198
- type: "text",
199
- text: `Execution failed: ${error instanceof Error ? error.message : String(error)}`
200
- }],
201
- details: { exitCode: 1 }
202
- };
203
- }
204
- }
205
- };
206
- }
207
- //#endregion
208
- export { SANDBOX_ALLOWED_TOOLS, buildSandboxToolMap, createExecuteCodeTool };