mixdog 1.2.6 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (294) hide show
  1. package/LICENSES/simple-icons-CC0-1.0.txt +30 -0
  2. package/NOTICE.md +71 -9
  3. package/package.json +4 -1
  4. package/scripts/check-model-recommendations.mjs +89 -0
  5. package/scripts/gate-local.mjs +7 -0
  6. package/scripts/lib/isolated-test-env.mjs +16 -0
  7. package/src/agents/reviewer/AGENT.md +4 -2
  8. package/src/agents/reviewer/agent.json +1 -1
  9. package/src/defaults/shipped-history.json +10 -0
  10. package/src/defaults/skills/browser-use/SKILL.md +5 -0
  11. package/src/defaults/skills/memory-management/SKILL.md +4 -1
  12. package/src/defaults/skills/setup/references/actions.md +14 -4
  13. package/src/defaults/skills/setup-guide/SKILL.md +178 -0
  14. package/src/defaults/skills/setup-guide/model-recommendations.json +333 -0
  15. package/src/lib/rules-builder.cjs +55 -6
  16. package/src/output-styles/common.md +13 -8
  17. package/src/rules/agent/AGENT.md +4 -0
  18. package/src/rules/agent-mode/AGENT_MODE.md +24 -0
  19. package/src/rules/agent-mode/MIXY.md +28 -0
  20. package/src/rules/agent-mode/ROUTINE.md +6 -0
  21. package/src/rules/lead/LEAD.md +7 -3
  22. package/src/rules/shared/70-delivery.md +3 -0
  23. package/src/runtime/agent/orchestrator/agent-runtime/room-supervisor-completion.mjs +86 -0
  24. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +77 -14
  25. package/src/runtime/agent/orchestrator/context/role-instructions.mjs +241 -14
  26. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +4 -2
  27. package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +216 -0
  28. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +5 -4
  29. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +10 -1
  30. package/src/runtime/agent/orchestrator/mcp/client.mjs +115 -11
  31. package/src/runtime/agent/orchestrator/mcp/oauth-account.mjs +97 -0
  32. package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +49 -0
  33. package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +59 -9
  34. package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +32 -7
  35. package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +45 -6
  36. package/src/runtime/agent/orchestrator/mcp/oauth.mjs +195 -6
  37. package/src/runtime/agent/orchestrator/mcp/server-connectors.mjs +17 -0
  38. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  39. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +1 -0
  40. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +7 -2
  41. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +10 -3
  42. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +4 -0
  43. package/src/runtime/agent/orchestrator/providers/auto-effort.mjs +7 -8
  44. package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
  45. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +3 -1
  46. package/src/runtime/agent/orchestrator/providers/lib/tool-call-wire-ids.mjs +65 -0
  47. package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +8 -2
  48. package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +9 -2
  49. package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +17 -12
  50. package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +10 -0
  51. package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +3 -1
  52. package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +14 -2
  53. package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +17 -0
  54. package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +96 -1
  55. package/src/runtime/agent/orchestrator/runtime-core/context-status-shape.mjs +4 -0
  56. package/src/runtime/agent/orchestrator/runtime-core/extension-scopes.mjs +6 -4
  57. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +14 -0
  58. package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +1 -0
  59. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +12 -6
  60. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +32 -5
  61. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +21 -5
  62. package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +40 -7
  63. package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +52 -20
  64. package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +2 -0
  65. package/src/runtime/agent/orchestrator/session/agent-home.d.mts +4 -0
  66. package/src/runtime/agent/orchestrator/session/agent-home.mjs +33 -0
  67. package/src/runtime/agent/orchestrator/session/agent-mode.mjs +62 -0
  68. package/src/runtime/agent/orchestrator/session/agent-room-supervisor.d.mts +31 -0
  69. package/src/runtime/agent/orchestrator/session/agent-room-supervisor.mjs +241 -0
  70. package/src/runtime/agent/orchestrator/session/agent-room.d.mts +166 -0
  71. package/src/runtime/agent/orchestrator/session/agent-room.mjs +650 -0
  72. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +7 -1
  73. package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +2 -0
  74. package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +6 -2
  75. package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +192 -0
  76. package/src/runtime/agent/orchestrator/session/human-gate/held-message.mjs +95 -0
  77. package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +221 -0
  78. package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +195 -0
  79. package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +167 -0
  80. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +3 -1
  81. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +9 -0
  82. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +10 -0
  83. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +108 -6
  84. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +10 -1
  85. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +74 -15
  86. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +9 -1
  87. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +5 -4
  88. package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +13 -3
  89. package/src/runtime/agent/orchestrator/session/loop/usage.mjs +49 -0
  90. package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +18 -8
  91. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +1 -0
  92. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +3 -1
  93. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +6 -0
  94. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +2 -0
  95. package/src/runtime/agent/orchestrator/session/manager/pending-lifecycle-epoch.mjs +0 -8
  96. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +44 -16
  97. package/src/runtime/agent/orchestrator/session/manager/provider-replay.mjs +50 -0
  98. package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +22 -5
  99. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +39 -4
  100. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +33 -24
  101. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +58 -8
  102. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +16 -0
  103. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +3 -2
  104. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +7 -1
  105. package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +6 -0
  106. package/src/runtime/agent/orchestrator/session/manager/workflow-switch-notice.mjs +58 -0
  107. package/src/runtime/agent/orchestrator/session/mixy-name.mjs +27 -0
  108. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +32 -5
  109. package/src/runtime/agent/orchestrator/session/routine-result.d.mts +86 -0
  110. package/src/runtime/agent/orchestrator/session/routine-result.mjs +329 -0
  111. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +8 -0
  112. package/src/runtime/agent/orchestrator/session/store-record-strict-scan.mjs +28 -9
  113. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +16 -2
  114. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +44 -12
  115. package/src/runtime/agent/orchestrator/session/store-summary-last-message.mjs +46 -0
  116. package/src/runtime/agent/orchestrator/session/store-summary-visibility.mjs +0 -4
  117. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +58 -10
  118. package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +92 -15
  119. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +12 -0
  120. package/src/runtime/agent/orchestrator/tools/builtin/native-search-client.mjs +113 -5
  121. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +4 -0
  122. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +25 -1
  123. package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +8 -0
  124. package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +6 -0
  125. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +3 -0
  126. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +75 -57
  127. package/src/runtime/attachments/store.mjs +6 -0
  128. package/src/runtime/browser-bridge/client.mjs +24 -0
  129. package/src/runtime/channels/lib/scheduler.mjs +40 -12
  130. package/src/runtime/channels/lib/schedules-db.mjs +71 -12
  131. package/src/runtime/channels/lib/webhook/session-dispatch.mjs +36 -16
  132. package/src/runtime/channels/lib/webhook.mjs +0 -1
  133. package/src/runtime/channels/lib/webhooks-db.mjs +100 -10
  134. package/src/runtime/channels/lib/worker-main.mjs +17 -20
  135. package/src/runtime/computer-bridge/client.mjs +28 -1
  136. package/src/runtime/connectors/gmail-app-password.mjs +690 -0
  137. package/src/runtime/connectors/google-mcp.mjs +446 -0
  138. package/src/runtime/effort-judge/judge-client.mjs +1 -1
  139. package/src/runtime/effort-judge/model-manifest.json +7 -7
  140. package/src/runtime/memory/lib/core-memory-access.mjs +69 -0
  141. package/src/runtime/memory/lib/core-memory-file.mjs +16 -8
  142. package/src/runtime/memory/lib/core-memory-index.mjs +15 -9
  143. package/src/runtime/memory/lib/core-memory-management.mjs +10 -4
  144. package/src/runtime/memory/lib/core-memory-store.mjs +53 -30
  145. package/src/runtime/memory/lib/core-memory-uniqueness.mjs +10 -6
  146. package/src/runtime/memory/lib/http-router/session-routes.mjs +3 -2
  147. package/src/runtime/memory/lib/memory-action-handlers/core-actions.mjs +44 -14
  148. package/src/runtime/memory/lib/memory-schema/core-and-meta.mjs +11 -0
  149. package/src/runtime/memory/lib/memory.mjs +7 -1
  150. package/src/runtime/memory/lib/query-core-recall.mjs +9 -1
  151. package/src/runtime/memory/lib/query-hybrid-search.mjs +2 -0
  152. package/src/runtime/memory/lib/tool-call-handler.mjs +2 -0
  153. package/src/runtime/memory/tool-defs.mjs +5 -0
  154. package/src/runtime/shared/agent-avatar-sprites.mjs +445 -0
  155. package/src/runtime/shared/agent-avatar.d.mts +64 -0
  156. package/src/runtime/shared/agent-avatar.mjs +320 -0
  157. package/src/runtime/shared/agent-kind.mjs +152 -0
  158. package/src/runtime/shared/agent-route-config.d.mts +4 -0
  159. package/src/runtime/shared/agent-route-config.mjs +30 -0
  160. package/src/runtime/shared/agent-store.mjs +132 -0
  161. package/src/runtime/shared/atomic-file.mjs +14 -1
  162. package/src/runtime/shared/bot-split-migration.mjs +457 -0
  163. package/src/runtime/shared/config-patch.mjs +20 -1
  164. package/src/runtime/shared/config.mjs +8 -1
  165. package/src/runtime/shared/connector-accounts.mjs +15 -0
  166. package/src/runtime/shared/connector-catalog.d.mts +51 -0
  167. package/src/runtime/shared/connector-catalog.mjs +228 -0
  168. package/src/runtime/shared/connector-triggers.d.mts +3 -0
  169. package/src/runtime/shared/connector-triggers.mjs +45 -0
  170. package/src/runtime/shared/err-text.mjs +3 -1
  171. package/src/runtime/shared/error-presentation.mjs +91 -6
  172. package/src/runtime/shared/google-oauth-client.mjs +24 -0
  173. package/src/runtime/shared/handoff-artifacts.d.mts +20 -0
  174. package/src/runtime/shared/handoff-artifacts.mjs +61 -0
  175. package/src/runtime/shared/held-request-host.d.mts +12 -0
  176. package/src/runtime/shared/held-request-host.mjs +71 -0
  177. package/src/runtime/shared/llm/provider-model-identities.mjs +6 -1
  178. package/src/runtime/shared/llm/usage-accounting.mjs +7 -1
  179. package/src/runtime/shared/model-route-fallback.mjs +79 -7
  180. package/src/runtime/shared/plain-preview.d.mts +1 -0
  181. package/src/runtime/shared/plain-preview.mjs +33 -0
  182. package/src/runtime/shared/routine-limits.d.mts +11 -0
  183. package/src/runtime/shared/routine-limits.mjs +21 -0
  184. package/src/runtime/shared/routine-trigger.d.mts +10 -0
  185. package/src/runtime/shared/routine-trigger.mjs +44 -0
  186. package/src/runtime/shared/schedule-model-ref.mjs +9 -10
  187. package/src/runtime/shared/sensitive-path-rules.d.mts +15 -0
  188. package/src/runtime/shared/sensitive-path-rules.mjs +256 -0
  189. package/src/runtime/shared/slow-span.mjs +4 -12
  190. package/src/runtime/shared/statusline/statusline-segments.mjs +13 -1
  191. package/src/runtime/shared/transcript-metadata.mjs +10 -0
  192. package/src/runtime/shared/turn-changes.mjs +0 -8
  193. package/src/runtime/shared/usage-readout-totals.mjs +58 -0
  194. package/src/runtime/shared/user-data-guard.mjs +119 -38
  195. package/src/session-runtime/agent-home-delivery.mjs +826 -0
  196. package/src/session-runtime/agent-profile-changes.mjs +21 -0
  197. package/src/session-runtime/agent-room-delivery.mjs +133 -0
  198. package/src/session-runtime/agent-task-sessions.mjs +460 -0
  199. package/src/session-runtime/boot/apis.mjs +63 -18
  200. package/src/session-runtime/boot/facade.mjs +5 -8
  201. package/src/session-runtime/boot/infrastructure.mjs +28 -17
  202. package/src/session-runtime/boot/providers.mjs +14 -4
  203. package/src/session-runtime/boot/tools.mjs +3 -0
  204. package/src/session-runtime/channel-config-api.mjs +53 -5
  205. package/src/session-runtime/config-lifecycle.mjs +43 -2
  206. package/src/session-runtime/cwd-plugins/core-memory-context.mjs +36 -20
  207. package/src/session-runtime/cwd-plugins/plugin-status.mjs +6 -1
  208. package/src/session-runtime/handoff-attachments.mjs +593 -0
  209. package/src/session-runtime/held-requests.mjs +228 -0
  210. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +121 -0
  211. package/src/session-runtime/internal-tool-executor/feature-tools.mjs +5 -1
  212. package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +31 -2
  213. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +56 -3
  214. package/src/session-runtime/internal-tool-executor.mjs +2 -0
  215. package/src/session-runtime/lifecycle/session-catalog.mjs +9 -0
  216. package/src/session-runtime/lifecycle/session-switch/resume.mjs +4 -0
  217. package/src/session-runtime/lifecycle/shared.mjs +6 -0
  218. package/src/session-runtime/mcp-glue/server-catalog.mjs +8 -0
  219. package/src/session-runtime/mcp-glue/server-input.mjs +3 -0
  220. package/src/session-runtime/mcp-oauth-login.mjs +112 -15
  221. package/src/session-runtime/model-route/route-persist.mjs +2 -2
  222. package/src/session-runtime/model-route/route-tuning.mjs +7 -1
  223. package/src/session-runtime/model-route/set-route.mjs +35 -4
  224. package/src/session-runtime/native-web-search.mjs +2 -2
  225. package/src/session-runtime/new-session-config.mjs +6 -1
  226. package/src/session-runtime/owned-automation-run.mjs +229 -0
  227. package/src/session-runtime/resource-api.mjs +5 -0
  228. package/src/session-runtime/resource-mcp-api.mjs +107 -13
  229. package/src/session-runtime/resource-skills-api.mjs +12 -0
  230. package/src/session-runtime/room-member-gate.mjs +48 -0
  231. package/src/session-runtime/route-resolution.mjs +5 -11
  232. package/src/session-runtime/routine-home-turn.mjs +156 -0
  233. package/src/session-runtime/routine-owner.mjs +48 -0
  234. package/src/session-runtime/schedule-session-run.mjs +30 -64
  235. package/src/session-runtime/services/agent-tool/helpers.mjs +30 -1
  236. package/src/session-runtime/services/agent-tool/send-flow.mjs +11 -3
  237. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +19 -4
  238. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +2 -0
  239. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +4 -1
  240. package/src/session-runtime/services/agent-tool/spawn-preset.mjs +5 -8
  241. package/src/session-runtime/services/agent-tool/tool-def.mjs +7 -0
  242. package/src/session-runtime/services/channel-admin.mjs +93 -24
  243. package/src/session-runtime/services/memory-access.mjs +37 -0
  244. package/src/session-runtime/services/provider-admin.mjs +74 -39
  245. package/src/session-runtime/services/schedule-access.mjs +91 -0
  246. package/src/session-runtime/session-create/session-options.mjs +34 -7
  247. package/src/session-runtime/session-hooks.mjs +16 -8
  248. package/src/session-runtime/setup-tool/executor.mjs +79 -6
  249. package/src/session-runtime/setup-tool/extended-actions.mjs +90 -20
  250. package/src/session-runtime/setup-tool/settings-contract.mjs +14 -6
  251. package/src/session-runtime/setup-tool/tool-defs.mjs +8 -0
  252. package/src/session-runtime/skills-api.mjs +16 -1
  253. package/src/session-runtime/tool-policy-refresh.mjs +249 -29
  254. package/src/session-runtime/turn/session-ops.mjs +8 -1
  255. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +10 -2
  256. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +14 -0
  257. package/src/session-runtime/webhook-session-run.mjs +49 -67
  258. package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +239 -0
  259. package/src/session-runtime/workflow-agents-api/agent-editor.mjs +650 -25
  260. package/src/session-runtime/workflow-agents-api/agent-route.mjs +67 -7
  261. package/src/session-runtime/workflow-agents-api/onboarding.mjs +11 -4
  262. package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +11 -1
  263. package/src/session-runtime/workflow-agents-api.mjs +4 -1
  264. package/src/standalone/daemon-agent-control.mjs +1 -8
  265. package/src/standalone/daemon-session-control.mjs +21 -4
  266. package/src/standalone/daemon.mjs +31 -5
  267. package/src/standalone/session-protocol.mjs +27 -0
  268. package/src/standalone/session-service/agent-tree/agent-turns.mjs +46 -3
  269. package/src/standalone/session-service/agent-tree.mjs +4 -3
  270. package/src/standalone/session-service/session-calls/session-turns.mjs +28 -0
  271. package/src/standalone/session-service.mjs +19 -0
  272. package/src/tui/app/slash-commands.mjs +20 -0
  273. package/src/tui/dist/index.mjs +234 -95
  274. package/src/tui/session/context-state.mjs +6 -1
  275. package/src/tui/session/notice-surface.mjs +34 -4
  276. package/src/tui/session/queue-helpers.mjs +2 -1
  277. package/src/tui/session/session-api/extensions.mjs +4 -0
  278. package/src/tui/session/session-api/intake/submission.mjs +5 -0
  279. package/src/tui/session/session-api/integrations.mjs +8 -0
  280. package/src/tui/session/session-api/lifecycle/session-reset.mjs +13 -3
  281. package/src/tui/session/session-api/lifecycle.mjs +17 -1
  282. package/src/tui/session/session-api/routes.mjs +61 -5
  283. package/src/tui/session/session-flow/drain.mjs +12 -3
  284. package/src/tui/session/session-flow/queue/entry-shape.mjs +2 -1
  285. package/src/tui/session/session-flow/queue/take-entries.mjs +3 -2
  286. package/src/tui/session/session-flow/steering.mjs +58 -24
  287. package/src/tui/session/tool-approval.mjs +26 -5
  288. package/src/tui/session/transcript-intake.mjs +8 -2
  289. package/src/tui/session/transcript-spill.mjs +5 -1
  290. package/src/tui/session/tui-steering-persist.mjs +65 -42
  291. package/src/tui/session/turn-live-call.mjs +64 -0
  292. package/src/tui/session/turn.mjs +34 -8
  293. package/src/session-runtime/automation-agents.mjs +0 -94
  294. package/src/session-runtime/automation-workflow.mjs +0 -59
@@ -17,6 +17,7 @@
17
17
  import { ensurePgInstance, withSchemaBootstrapLock } from '../../memory/lib/pg/adapter.mjs';
18
18
  import { createPgSchemaDb } from '../../shared/pg-schema-db.mjs';
19
19
  import { resolvePluginData } from '../../shared/plugin-paths.mjs';
20
+ import { ROUTINE_LIMITS } from '../../shared/routine-limits.mjs';
20
21
 
21
22
  const SCHEMA = 'webhooks';
22
23
 
@@ -40,6 +41,23 @@ ALTER TABLE webhooks.endpoints ADD COLUMN IF NOT EXISTS workflow text;
40
41
  ALTER TABLE webhooks.endpoints ADD COLUMN IF NOT EXISTS attachments jsonb;
41
42
  ALTER TABLE webhooks.endpoints ADD COLUMN IF NOT EXISTS delivery text;
42
43
  ALTER TABLE webhooks.endpoints ALTER COLUMN role SET DEFAULT '';
44
+ -- Agent ownership: each endpoint's results post into its owner's home
45
+ -- thread; endpoints from before ownership become Mixy's ('lead').
46
+ ALTER TABLE webhooks.endpoints ADD COLUMN IF NOT EXISTS owner_agent_id text NOT NULL DEFAULT 'lead';
47
+ -- Legacy columns model, workflow and run_as_agent are no longer read or written (kept, not dropped, to avoid a risky migration).
48
+ ALTER TABLE webhooks.endpoints ADD COLUMN IF NOT EXISTS run_as_agent boolean NOT NULL DEFAULT false;
49
+ -- The latest received event (its payload kept for a manual re-run) and the
50
+ -- outcome stamps of the runs it started.
51
+ ALTER TABLE webhooks.endpoints ADD COLUMN IF NOT EXISTS last_event_at timestamptz;
52
+ ALTER TABLE webhooks.endpoints ADD COLUMN IF NOT EXISTS last_payload jsonb;
53
+ ALTER TABLE webhooks.endpoints ADD COLUMN IF NOT EXISTS last_success_at timestamptz;
54
+ ALTER TABLE webhooks.endpoints ADD COLUMN IF NOT EXISTS last_failed_at timestamptz;
55
+ ALTER TABLE webhooks.endpoints ADD COLUMN IF NOT EXISTS last_skipped_at timestamptz;
56
+ -- Failed runs in a row (schedules parity): a success, an edit or switching it
57
+ -- back on resets it; at ROUTINE_LIMITS.pauseAfterFailures it switches off.
58
+ ALTER TABLE webhooks.endpoints ADD COLUMN IF NOT EXISTS consecutive_failures integer NOT NULL DEFAULT 0;
59
+ -- Results of finished runs not yet queued for the owner's home thread, by run id.
60
+ ALTER TABLE webhooks.endpoints ADD COLUMN IF NOT EXISTS result_delivery jsonb;
43
61
  CREATE TABLE IF NOT EXISTS webhooks.deliveries (
44
62
  endpoint text NOT NULL,
45
63
  delivery_id text NOT NULL,
@@ -66,8 +84,10 @@ const getDb = createPgSchemaDb({
66
84
  // Row <-> def mapping
67
85
  // ---------------------------------------------------------------------------
68
86
 
87
+ // The stored payload itself is never projected here (readEndpointLastPayload
88
+ // is its only read path); rows carry a presence flag.
69
89
  const ENDPOINT_COLS =
70
- 'name, description, channel_id, model, parser, secret, cwd, workflow, attachments, delivery, instructions, enabled, created_at, updated_at';
90
+ 'name, description, channel_id, parser, secret, cwd, attachments, delivery, instructions, enabled, owner_agent_id, last_event_at, last_success_at, last_failed_at, last_skipped_at, consecutive_failures, result_delivery, (last_payload IS NOT NULL) AS has_last_payload, created_at, updated_at';
71
91
 
72
92
  function rowToEndpoint(row) {
73
93
  if (!row) return null;
@@ -75,10 +95,8 @@ function rowToEndpoint(row) {
75
95
  name: row.name,
76
96
  description: row.description,
77
97
  channelId: row.channel_id,
78
- model: row.model,
79
98
  parser: row.parser,
80
99
  cwd: row.cwd,
81
- workflow: row.workflow,
82
100
  attachments: row.attachments || null,
83
101
  delivery: row.delivery || null,
84
102
  // Never project the plaintext secret through list/load config paths;
@@ -87,6 +105,14 @@ function rowToEndpoint(row) {
87
105
  secretSet: Boolean(row.secret && String(row.secret).trim()),
88
106
  instructions: row.instructions,
89
107
  enabled: row.enabled,
108
+ ownerAgentId: row.owner_agent_id || 'lead',
109
+ lastEventAt: row.last_event_at || null,
110
+ lastSuccessAt: row.last_success_at || null,
111
+ lastFailedAt: row.last_failed_at || null,
112
+ lastSkippedAt: row.last_skipped_at || null,
113
+ consecutiveFailures: Number(row.consecutive_failures) || 0,
114
+ resultDelivery: row.result_delivery || null,
115
+ hasLastPayload: row.has_last_payload === true,
90
116
  createdAt: row.created_at,
91
117
  updatedAt: row.updated_at,
92
118
  };
@@ -156,33 +182,34 @@ export async function upsertEndpoint(def, { dataDir } = {}) {
156
182
  def.description ?? '',
157
183
  def.channelId ?? null,
158
184
  '',
159
- def.model ?? null,
160
185
  def.parser ?? null,
161
186
  def.secret ?? null,
162
187
  def.cwd ?? null,
163
- def.workflow ?? null,
164
188
  def.attachments ? JSON.stringify(def.attachments) : null,
165
189
  def.delivery ?? null,
166
190
  def.instructions ?? '',
167
191
  def.enabled ?? true,
192
+ def.ownerAgentId || 'lead',
168
193
  ];
194
+ // The last event and run stamps survive an edit: they describe deliveries,
195
+ // not the definition.
169
196
  const { rows } = await db.query(
170
197
  `INSERT INTO webhooks.endpoints
171
- (name, description, channel_id, role, model, parser, secret, cwd, workflow, attachments, delivery, instructions, enabled)
172
- VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13)
198
+ (name, description, channel_id, role, parser, secret, cwd, attachments, delivery, instructions, enabled, owner_agent_id)
199
+ VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12)
173
200
  ON CONFLICT (name) DO UPDATE SET
201
+ owner_agent_id = EXCLUDED.owner_agent_id,
174
202
  description = EXCLUDED.description,
175
203
  channel_id = EXCLUDED.channel_id,
176
204
  role = EXCLUDED.role,
177
- model = EXCLUDED.model,
178
205
  parser = EXCLUDED.parser,
179
206
  secret = EXCLUDED.secret,
180
207
  cwd = EXCLUDED.cwd,
181
- workflow = EXCLUDED.workflow,
182
208
  attachments = EXCLUDED.attachments,
183
209
  delivery = EXCLUDED.delivery,
184
210
  instructions = EXCLUDED.instructions,
185
211
  enabled = EXCLUDED.enabled,
212
+ consecutive_failures = 0,
186
213
  updated_at = now()
187
214
  RETURNING ${ENDPOINT_COLS}`,
188
215
  params
@@ -190,15 +217,78 @@ export async function upsertEndpoint(def, { dataDir } = {}) {
190
217
  return rowToEndpoint(rows[0]);
191
218
  }
192
219
 
220
+ /** Switching an endpoint back on clears its failure streak. */
193
221
  export async function setEndpointEnabled(name, enabled, { dataDir } = {}) {
194
222
  const db = await getDb(dataDir);
195
223
  const { rows } = await db.query(
196
- `UPDATE webhooks.endpoints SET enabled = $2, updated_at = now() WHERE name = $1 RETURNING ${ENDPOINT_COLS}`,
224
+ `UPDATE webhooks.endpoints
225
+ SET enabled = $2, consecutive_failures = CASE WHEN $2 THEN 0 ELSE consecutive_failures END, updated_at = now()
226
+ WHERE name = $1 RETURNING ${ENDPOINT_COLS}`,
197
227
  [name, !!enabled]
198
228
  );
199
229
  return rowToEndpoint(rows[0]);
200
230
  }
201
231
 
232
+ /** Record a received event: its time and payload (`{ body, headers }`), kept
233
+ * so the app can re-run the endpoint on it. */
234
+ export async function recordEndpointEvent(name, payload, at = new Date(), { dataDir } = {}) {
235
+ const db = await getDb(dataDir);
236
+ await db.query(
237
+ 'UPDATE webhooks.endpoints SET last_event_at = $2, last_payload = $3, updated_at = now() WHERE name = $1',
238
+ [name, at, JSON.stringify(payload ?? null)]
239
+ );
240
+ }
241
+
242
+ /** The payload of the latest received event, or null before the first. */
243
+ export async function readEndpointLastPayload(name, { dataDir } = {}) {
244
+ if (!name) return null;
245
+ const db = await getDb(dataDir);
246
+ const { rows } = await db.query('SELECT last_payload FROM webhooks.endpoints WHERE name = $1', [name]);
247
+ return rows[0]?.last_payload ?? null;
248
+ }
249
+
250
+ const RUN_STAMPS = Object.freeze({
251
+ success: 'last_success_at',
252
+ failed: 'last_failed_at',
253
+ skipped: 'last_skipped_at',
254
+ });
255
+
256
+ /** Stamp a run outcome ('success' | 'failed' | 'skipped') on the endpoint. A
257
+ * success clears the failure streak; the failure reaching the pause limit
258
+ * switches the endpoint off (the receiver refuses a disabled endpoint). */
259
+ export async function markEndpointRun(name, outcome, at = new Date(), { dataDir } = {}) {
260
+ const column = RUN_STAMPS[outcome];
261
+ if (!column) throw new Error(`markEndpointRun: unknown outcome "${outcome}"`);
262
+ const db = await getDb(dataDir);
263
+ if (outcome === 'failed') {
264
+ await db.query(
265
+ `UPDATE webhooks.endpoints
266
+ SET last_failed_at = $2, consecutive_failures = consecutive_failures + 1,
267
+ enabled = enabled AND consecutive_failures + 1 < $3
268
+ WHERE name = $1`,
269
+ [name, at, ROUTINE_LIMITS.pauseAfterFailures]
270
+ );
271
+ return;
272
+ }
273
+ const streak = outcome === 'success' ? ', consecutive_failures = 0' : '';
274
+ await db.query(`UPDATE webhooks.endpoints SET ${column} = $2${streak} WHERE name = $1`, [name, at]);
275
+ }
276
+
277
+ /** Set (`entry`) or clear (null) the undelivered result of run `runId`. */
278
+ export async function recordEndpointDelivery(name, runId, entry, { dataDir } = {}) {
279
+ const db = await getDb(dataDir);
280
+ await db.query(
281
+ entry
282
+ ? `UPDATE webhooks.endpoints
283
+ SET result_delivery = COALESCE(result_delivery, '{}'::jsonb) || jsonb_build_object($2::text, $3::jsonb)
284
+ WHERE name = $1`
285
+ : `UPDATE webhooks.endpoints
286
+ SET result_delivery = NULLIF(COALESCE(result_delivery, '{}'::jsonb) - $2::text, '{}'::jsonb)
287
+ WHERE name = $1`,
288
+ entry ? [name, runId, JSON.stringify(entry)] : [name, runId]
289
+ );
290
+ }
291
+
202
292
  export async function deleteEndpoint(name, { dataDir } = {}) {
203
293
  const db = await getDb(dataDir);
204
294
  // Atomically drop the endpoint AND its delivery log in one statement: a
@@ -128,7 +128,7 @@ const STATUS_FILE = getStatusPath(INSTANCE_ID);
128
128
  const statusState = new JsonStateFile(STATUS_FILE, {});
129
129
  statusState.ensure();
130
130
  const scheduler = new Scheduler(config.nonInteractive ?? [], config.interactive ?? []);
131
- // Schedules fire as visible sessions; the session runner belongs to the
131
+ // A schedule fire is a turn in its owner bot's chat; the runner belongs to the
132
132
  // session-runtime layer, so this worker entry injects it (lazy, like webhooks).
133
133
  scheduler.setScheduleRunner(async (schedule, opts) => {
134
134
  const { runScheduleSession } = await import('../../../session-runtime/schedule-session-run.mjs');
@@ -216,25 +216,22 @@ scheduler.setInjectReadyCheck(() => bridgeRuntimeConnected && currentOwnerState(
216
216
  function wireWebhookHandlers() {
217
217
  if (!webhookServer) return;
218
218
  webhookServer.setEventPipeline(eventPipeline);
219
- // Webhook fires run as sessions (schedules parity); the Automations
220
- // session row is the only surface (channel relay retired).
221
- webhookServer.setBridgeDispatch(
222
- async ({ prompt, skillSelection, model, cwd, workflow, attachments, context, signal }) => {
223
- const { runWebhookSession } = await import('../../../session-runtime/webhook-session-run.mjs');
224
- const run = await runWebhookSession({
225
- name: context?.endpoint || 'webhook',
226
- model: model || null,
227
- cwd: cwd || null,
228
- workflow: workflow || null,
229
- attachments: attachments || null,
230
- // Dispatch-timeout cancellation only works if the signal reaches the run.
231
- signal: signal || null,
232
- prompt,
233
- skillSelection,
234
- });
235
- return run;
236
- }
237
- );
219
+ // A webhook fire is a turn in its owner bot's chat (webhook-session-run.mjs).
220
+ webhookServer.setBridgeDispatch(async ({ prompt, skillSelection, cwd, attachments, context, signal }) => {
221
+ const { runWebhookSession } = await import('../../../session-runtime/webhook-session-run.mjs');
222
+ const run = await runWebhookSession({
223
+ name: context?.endpoint || 'webhook',
224
+ ownerAgentId: context?.owner || null,
225
+ cwd: cwd || null,
226
+ attachments: attachments || null,
227
+ event: context?.event || '',
228
+ // Dispatch-timeout cancellation only works if the signal reaches the run.
229
+ signal: signal || null,
230
+ prompt,
231
+ skillSelection,
232
+ });
233
+ return run;
234
+ });
238
235
  }
239
236
  function wireEventQueueHandlers(eventQueue) {
240
237
  if (!eventQueue) return;
@@ -249,7 +249,9 @@ export async function executeComputerTool(rawArgs, context = {}) {
249
249
  const note = { text: '' };
250
250
  const result = await executeComputerToolInner(rawArgs, context, note);
251
251
  // The fallback note rides as its own block so the JSON result text stays intact.
252
- return note.text && !result.isError ? { ...result, content: [...result.content, { type: 'text', text: note.text }] } : result;
252
+ return note.text && !result.isError
253
+ ? { ...result, content: [...result.content, { type: 'text', text: note.text }] }
254
+ : result;
253
255
  }
254
256
 
255
257
  async function executeComputerToolInner(rawArgs, context, note) {
@@ -379,6 +381,31 @@ async function sendComputerSessionControl(sessionId, action, timeoutMs) {
379
381
  }
380
382
  }
381
383
 
384
+ /** Runtime-only: type the secret the user handed the desktop for `requestId`
385
+ * into the focused field (or `ref`) once. The value never passes through
386
+ * here; the host answers only whether it was typed. */
387
+ export async function computerSecretInput(sessionId, requestId, { ref = '', windowId = '', signal } = {}) {
388
+ const discovery = readBridgeDiscovery(DISCOVERY_FILE);
389
+ if (!discovery || !sessionId || !requestId) return 'skipped';
390
+ try {
391
+ const response = await postComputerCommand(
392
+ discovery,
393
+ {
394
+ action: 'secret_input',
395
+ session_id: String(sessionId),
396
+ request_id: String(requestId),
397
+ ...(ref ? { ref: String(ref) } : {}),
398
+ ...(windowId ? { window_id: String(windowId) } : {}),
399
+ },
400
+ { signal }
401
+ );
402
+ const body = await readComputerBridgeJson(response);
403
+ return response.ok && body?.ok === true && body.value?.text === 'provided' ? 'provided' : 'skipped';
404
+ } catch {
405
+ return 'skipped';
406
+ }
407
+ }
408
+
382
409
  async function abortComputerSession(sessionId) {
383
410
  const id = String(sessionId || '').trim();
384
411
  if (!id) return false;