@intentic/sandbox-contract 1.232.0 → 1.234.0
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.
- package/README.md +11 -5
- package/dist/agent-catalog.d.ts +4 -2
- package/dist/agent-catalog.d.ts.map +1 -1
- package/dist/agent-catalog.js +20 -14
- package/dist/agent-catalog.js.map +1 -1
- package/dist/chores/chores.d.ts +1 -1
- package/dist/chores/chores.d.ts.map +1 -1
- package/dist/chores/chores.js +36 -1
- package/dist/chores/chores.js.map +1 -1
- package/dist/chores/probes.d.ts +1 -1
- package/dist/chores/probes.d.ts.map +1 -1
- package/dist/chores/probes.js +70 -0
- package/dist/chores/probes.js.map +1 -1
- package/dist/chores/stack.d.ts.map +1 -1
- package/dist/chores/stack.js +2 -1
- package/dist/chores/stack.js.map +1 -1
- package/dist/chores/verdict.d.ts +1 -1
- package/dist/chores/verdict.d.ts.map +1 -1
- package/dist/command-classes.d.ts +17 -0
- package/dist/command-classes.d.ts.map +1 -0
- package/dist/command-classes.js +189 -0
- package/dist/command-classes.js.map +1 -0
- package/dist/contracts/activity.contract.js +1 -1
- package/dist/contracts/activity.contract.js.map +1 -1
- package/dist/contracts/agent.contract.d.ts +40 -2
- package/dist/contracts/agent.contract.d.ts.map +1 -1
- package/dist/contracts/agent.contract.js +4 -1
- package/dist/contracts/agent.contract.js.map +1 -1
- package/dist/contracts/agents.contract.d.ts +24 -0
- package/dist/contracts/agents.contract.d.ts.map +1 -1
- package/dist/contracts/agents.contract.js +5 -1
- package/dist/contracts/agents.contract.js.map +1 -1
- package/dist/contracts/automations.contract.d.ts +30 -0
- package/dist/contracts/automations.contract.d.ts.map +1 -1
- package/dist/contracts/automations.contract.js +2 -1
- package/dist/contracts/automations.contract.js.map +1 -1
- package/dist/contracts/capabilities.contract.d.ts +63 -0
- package/dist/contracts/capabilities.contract.d.ts.map +1 -1
- package/dist/contracts/capabilities.contract.js +3 -1
- package/dist/contracts/capabilities.contract.js.map +1 -1
- package/dist/contracts/chores.contract.d.ts +17 -0
- package/dist/contracts/chores.contract.d.ts.map +1 -1
- package/dist/contracts/chores.contract.js +2 -1
- package/dist/contracts/chores.contract.js.map +1 -1
- package/dist/contracts/ci.contract.js +2 -1
- package/dist/contracts/ci.contract.js.map +1 -1
- package/dist/contracts/claude.contract.js +2 -1
- package/dist/contracts/claude.contract.js.map +1 -1
- package/dist/contracts/cursor.contract.js +2 -1
- package/dist/contracts/cursor.contract.js.map +1 -1
- package/dist/contracts/drafts.contract.d.ts.map +1 -1
- package/dist/contracts/drafts.contract.js +2 -1
- package/dist/contracts/drafts.contract.js.map +1 -1
- package/dist/contracts/endpoints.contract.d.ts.map +1 -1
- package/dist/contracts/endpoints.contract.js +2 -1
- package/dist/contracts/endpoints.contract.js.map +1 -1
- package/dist/contracts/exit.contract.d.ts.map +1 -1
- package/dist/contracts/exit.contract.js +2 -1
- package/dist/contracts/exit.contract.js.map +1 -1
- package/dist/contracts/extensions.contract.d.ts +44 -0
- package/dist/contracts/extensions.contract.d.ts.map +1 -1
- package/dist/contracts/extensions.contract.js +4 -1
- package/dist/contracts/extensions.contract.js.map +1 -1
- package/dist/contracts/git.contract.d.ts.map +1 -1
- package/dist/contracts/git.contract.js +4 -1
- package/dist/contracts/git.contract.js.map +1 -1
- package/dist/contracts/grok.contract.d.ts.map +1 -1
- package/dist/contracts/grok.contract.js +2 -1
- package/dist/contracts/grok.contract.js.map +1 -1
- package/dist/contracts/history.contract.d.ts.map +1 -1
- package/dist/contracts/history.contract.js +2 -1
- package/dist/contracts/history.contract.js.map +1 -1
- package/dist/contracts/host.contract.d.ts +7 -0
- package/dist/contracts/host.contract.d.ts.map +1 -1
- package/dist/contracts/host.contract.js +4 -1
- package/dist/contracts/host.contract.js.map +1 -1
- package/dist/contracts/intentic.contract.d.ts.map +1 -1
- package/dist/contracts/intentic.contract.js +2 -1
- package/dist/contracts/intentic.contract.js.map +1 -1
- package/dist/contracts/inventory.contract.js +1 -1
- package/dist/contracts/inventory.contract.js.map +1 -1
- package/dist/contracts/issues.contract.d.ts +89 -0
- package/dist/contracts/issues.contract.d.ts.map +1 -0
- package/dist/contracts/issues.contract.js +50 -0
- package/dist/contracts/issues.contract.js.map +1 -0
- package/dist/contracts/logs.contract.d.ts.map +1 -1
- package/dist/contracts/logs.contract.js +1 -1
- package/dist/contracts/logs.contract.js.map +1 -1
- package/dist/contracts/loops.contract.js +2 -1
- package/dist/contracts/loops.contract.js.map +1 -1
- package/dist/contracts/panels.contract.d.ts.map +1 -1
- package/dist/contracts/panels.contract.js +2 -1
- package/dist/contracts/panels.contract.js.map +1 -1
- package/dist/contracts/personas.contract.js +2 -1
- package/dist/contracts/personas.contract.js.map +1 -1
- package/dist/contracts/ports.contract.d.ts.map +1 -1
- package/dist/contracts/ports.contract.js +2 -1
- package/dist/contracts/ports.contract.js.map +1 -1
- package/dist/contracts/prepush.contract.d.ts.map +1 -1
- package/dist/contracts/prepush.contract.js +2 -1
- package/dist/contracts/prepush.contract.js.map +1 -1
- package/dist/contracts/providers.contract.d.ts.map +1 -1
- package/dist/contracts/providers.contract.js +2 -1
- package/dist/contracts/providers.contract.js.map +1 -1
- package/dist/contracts/public.contract.d.ts.map +1 -1
- package/dist/contracts/public.contract.js +2 -1
- package/dist/contracts/public.contract.js.map +1 -1
- package/dist/contracts/push.contract.d.ts.map +1 -1
- package/dist/contracts/push.contract.js +2 -1
- package/dist/contracts/push.contract.js.map +1 -1
- package/dist/contracts/runner.contract.d.ts +127 -84
- package/dist/contracts/runner.contract.d.ts.map +1 -1
- package/dist/contracts/runner.contract.js +10 -2
- package/dist/contracts/runner.contract.js.map +1 -1
- package/dist/contracts/secrets.contract.d.ts.map +1 -1
- package/dist/contracts/secrets.contract.js +2 -1
- package/dist/contracts/secrets.contract.js.map +1 -1
- package/dist/contracts/sessions.contract.js +1 -1
- package/dist/contracts/sessions.contract.js.map +1 -1
- package/dist/contracts/settings.contract.d.ts +32 -0
- package/dist/contracts/settings.contract.d.ts.map +1 -1
- package/dist/contracts/settings.contract.js +3 -1
- package/dist/contracts/settings.contract.js.map +1 -1
- package/dist/contracts/share.contract.d.ts.map +1 -1
- package/dist/contracts/share.contract.js +2 -1
- package/dist/contracts/share.contract.js.map +1 -1
- package/dist/contracts/skills.contract.d.ts.map +1 -1
- package/dist/contracts/skills.contract.js +2 -1
- package/dist/contracts/skills.contract.js.map +1 -1
- package/dist/contracts/system.contract.d.ts +31 -16
- package/dist/contracts/system.contract.d.ts.map +1 -1
- package/dist/contracts/system.contract.js +6 -1
- package/dist/contracts/system.contract.js.map +1 -1
- package/dist/contracts/translator.contract.d.ts.map +1 -1
- package/dist/contracts/translator.contract.js +4 -1
- package/dist/contracts/translator.contract.js.map +1 -1
- package/dist/contracts/usage.contract.js +1 -1
- package/dist/contracts/usage.contract.js.map +1 -1
- package/dist/contracts/vpn.contract.d.ts.map +1 -1
- package/dist/contracts/vpn.contract.js +2 -1
- package/dist/contracts/vpn.contract.js.map +1 -1
- package/dist/contracts/webext.contract.d.ts +45 -0
- package/dist/contracts/webext.contract.d.ts.map +1 -0
- package/dist/contracts/webext.contract.js +12 -0
- package/dist/contracts/webext.contract.js.map +1 -0
- package/dist/contracts/workflows.contract.js +2 -1
- package/dist/contracts/workflows.contract.js.map +1 -1
- package/dist/contracts/workspace.contract.d.ts +2 -2
- package/dist/contracts/workspace.contract.d.ts.map +1 -1
- package/dist/contracts/workspace.contract.js +7 -1
- package/dist/contracts/workspace.contract.js.map +1 -1
- package/dist/credential-material.d.ts +2 -0
- package/dist/credential-material.d.ts.map +1 -0
- package/dist/credential-material.js +36 -0
- package/dist/credential-material.js.map +1 -0
- package/dist/definition-action.d.ts +7 -0
- package/dist/definition-action.d.ts.map +1 -0
- package/dist/definition-action.js +3 -0
- package/dist/definition-action.js.map +1 -0
- package/dist/definition.d.ts +132 -21
- package/dist/definition.d.ts.map +1 -1
- package/dist/definition.js +29 -7
- package/dist/definition.js.map +1 -1
- package/dist/events.d.ts +101 -0
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +25 -1
- package/dist/events.js.map +1 -1
- package/dist/fast-tier.d.ts +1 -1
- package/dist/fast-tier.d.ts.map +1 -1
- package/dist/history-state.d.ts.map +1 -1
- package/dist/history-state.js +2 -0
- package/dist/history-state.js.map +1 -1
- package/dist/hostnames.d.ts +2 -0
- package/dist/hostnames.d.ts.map +1 -1
- package/dist/hostnames.js +3 -1
- package/dist/hostnames.js.map +1 -1
- package/dist/index.d.ts +411 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +56 -1
- package/dist/index.js.map +1 -1
- package/dist/listener-protocol.js +1 -1
- package/dist/listener-protocol.js.map +1 -1
- package/dist/quick-model.d.ts +1 -1
- package/dist/quick-model.d.ts.map +1 -1
- package/dist/runner-protocol.d.ts +18 -0
- package/dist/runner-protocol.d.ts.map +1 -1
- package/dist/runner-protocol.js +8 -4
- package/dist/runner-protocol.js.map +1 -1
- package/dist/runtime-state.d.ts +9 -0
- package/dist/runtime-state.d.ts.map +1 -1
- package/dist/runtime-state.js +3 -0
- package/dist/runtime-state.js.map +1 -1
- package/dist/schemas/activity.d.ts +112 -0
- package/dist/schemas/activity.d.ts.map +1 -0
- package/dist/schemas/activity.js +70 -0
- package/dist/schemas/activity.js.map +1 -0
- package/dist/schemas/agent.d.ts +195 -0
- package/dist/schemas/agent.d.ts.map +1 -0
- package/dist/schemas/agent.js +171 -0
- package/dist/schemas/agent.js.map +1 -0
- package/dist/schemas/agents.d.ts +690 -0
- package/dist/schemas/agents.d.ts.map +1 -0
- package/dist/schemas/agents.js +314 -0
- package/dist/schemas/agents.js.map +1 -0
- package/dist/schemas/automations.d.ts +781 -0
- package/dist/schemas/automations.d.ts.map +1 -0
- package/dist/schemas/automations.js +223 -0
- package/dist/schemas/automations.js.map +1 -0
- package/dist/schemas/capabilities.d.ts +753 -0
- package/dist/schemas/capabilities.d.ts.map +1 -0
- package/dist/schemas/capabilities.js +269 -0
- package/dist/schemas/capabilities.js.map +1 -0
- package/dist/schemas/ci.d.ts +179 -0
- package/dist/schemas/ci.d.ts.map +1 -0
- package/dist/schemas/ci.js +99 -0
- package/dist/schemas/ci.js.map +1 -0
- package/dist/schemas/claude-gate.d.ts +13 -0
- package/dist/schemas/claude-gate.d.ts.map +1 -0
- package/dist/schemas/claude-gate.js +8 -0
- package/dist/schemas/claude-gate.js.map +1 -0
- package/dist/schemas/codebase-health.d.ts +56 -0
- package/dist/schemas/codebase-health.d.ts.map +1 -0
- package/dist/schemas/codebase-health.js +43 -0
- package/dist/schemas/codebase-health.js.map +1 -0
- package/dist/schemas/computers.d.ts +386 -0
- package/dist/schemas/computers.d.ts.map +1 -0
- package/dist/schemas/computers.js +107 -0
- package/dist/schemas/computers.js.map +1 -0
- package/dist/schemas/drafts.d.ts +84 -0
- package/dist/schemas/drafts.d.ts.map +1 -0
- package/dist/schemas/drafts.js +44 -0
- package/dist/schemas/drafts.js.map +1 -0
- package/dist/schemas/environment.d.ts +349 -0
- package/dist/schemas/environment.d.ts.map +1 -0
- package/dist/schemas/environment.js +111 -0
- package/dist/schemas/environment.js.map +1 -0
- package/dist/schemas/exit.d.ts +151 -0
- package/dist/schemas/exit.d.ts.map +1 -0
- package/dist/schemas/exit.js +115 -0
- package/dist/schemas/exit.js.map +1 -0
- package/dist/schemas/extension-updates.d.ts +1016 -0
- package/dist/schemas/extension-updates.d.ts.map +1 -0
- package/dist/schemas/extension-updates.js +199 -0
- package/dist/schemas/extension-updates.js.map +1 -0
- package/dist/schemas/fast-mode.d.ts +8 -0
- package/dist/schemas/fast-mode.d.ts.map +1 -0
- package/dist/schemas/fast-mode.js +3 -0
- package/dist/schemas/fast-mode.js.map +1 -0
- package/dist/schemas/git-history.d.ts +238 -0
- package/dist/schemas/git-history.d.ts.map +1 -0
- package/dist/schemas/git-history.js +152 -0
- package/dist/schemas/git-history.js.map +1 -0
- package/dist/schemas/git.d.ts +471 -0
- package/dist/schemas/git.d.ts.map +1 -0
- package/dist/schemas/git.js +204 -0
- package/dist/schemas/git.js.map +1 -0
- package/dist/schemas/history.d.ts +100 -0
- package/dist/schemas/history.d.ts.map +1 -0
- package/dist/schemas/history.js +54 -0
- package/dist/schemas/history.js.map +1 -0
- package/dist/schemas/hosts.d.ts +41 -0
- package/dist/schemas/hosts.d.ts.map +1 -0
- package/dist/schemas/hosts.js +18 -0
- package/dist/schemas/hosts.js.map +1 -0
- package/dist/schemas/intentic.d.ts +5 -0
- package/dist/schemas/intentic.d.ts.map +1 -0
- package/dist/schemas/intentic.js +3 -0
- package/dist/schemas/intentic.js.map +1 -0
- package/dist/schemas/internal.d.ts +8 -0
- package/dist/schemas/internal.d.ts.map +1 -0
- package/dist/schemas/internal.js +12 -0
- package/dist/schemas/internal.js.map +1 -0
- package/dist/schemas/inventory.d.ts +171 -0
- package/dist/schemas/inventory.d.ts.map +1 -0
- package/dist/schemas/inventory.js +51 -0
- package/dist/schemas/inventory.js.map +1 -0
- package/dist/schemas/issues.d.ts +324 -0
- package/dist/schemas/issues.d.ts.map +1 -0
- package/dist/schemas/issues.js +107 -0
- package/dist/schemas/issues.js.map +1 -0
- package/dist/schemas/logs.d.ts +67 -0
- package/dist/schemas/logs.d.ts.map +1 -0
- package/dist/schemas/logs.js +54 -0
- package/dist/schemas/logs.js.map +1 -0
- package/dist/schemas/loops.d.ts +415 -0
- package/dist/schemas/loops.d.ts.map +1 -0
- package/dist/schemas/loops.js +188 -0
- package/dist/schemas/loops.js.map +1 -0
- package/dist/schemas/maintenance.d.ts +618 -0
- package/dist/schemas/maintenance.d.ts.map +1 -0
- package/dist/schemas/maintenance.js +222 -0
- package/dist/schemas/maintenance.js.map +1 -0
- package/dist/schemas/marketplace.d.ts +64 -0
- package/dist/schemas/marketplace.d.ts.map +1 -0
- package/dist/schemas/marketplace.js +17 -0
- package/dist/schemas/marketplace.js.map +1 -0
- package/dist/schemas/panels.d.ts +61 -0
- package/dist/schemas/panels.d.ts.map +1 -0
- package/dist/schemas/panels.js +51 -0
- package/dist/schemas/panels.js.map +1 -0
- package/dist/schemas/personas.d.ts +122 -0
- package/dist/schemas/personas.d.ts.map +1 -0
- package/dist/schemas/personas.js +102 -0
- package/dist/schemas/personas.js.map +1 -0
- package/dist/schemas/plan-limits.d.ts +172 -0
- package/dist/schemas/plan-limits.d.ts.map +1 -0
- package/dist/schemas/plan-limits.js +126 -0
- package/dist/schemas/plan-limits.js.map +1 -0
- package/dist/schemas/ports.d.ts +71 -0
- package/dist/schemas/ports.d.ts.map +1 -0
- package/dist/schemas/ports.js +42 -0
- package/dist/schemas/ports.js.map +1 -0
- package/dist/schemas/provider-oauth.d.ts +128 -0
- package/dist/schemas/provider-oauth.d.ts.map +1 -0
- package/dist/schemas/provider-oauth.js +91 -0
- package/dist/schemas/provider-oauth.js.map +1 -0
- package/dist/schemas/provider-subscriptions.d.ts +9 -0
- package/dist/schemas/provider-subscriptions.d.ts.map +1 -0
- package/dist/schemas/provider-subscriptions.js +3 -0
- package/dist/schemas/provider-subscriptions.js.map +1 -0
- package/dist/schemas/public.d.ts +32 -0
- package/dist/schemas/public.d.ts.map +1 -0
- package/dist/schemas/public.js +29 -0
- package/dist/schemas/public.js.map +1 -0
- package/dist/schemas/push.d.ts +55 -0
- package/dist/schemas/push.d.ts.map +1 -0
- package/dist/schemas/push.js +60 -0
- package/dist/schemas/push.js.map +1 -0
- package/dist/schemas/secrets.d.ts +86 -0
- package/dist/schemas/secrets.d.ts.map +1 -0
- package/dist/schemas/secrets.js +51 -0
- package/dist/schemas/secrets.js.map +1 -0
- package/dist/schemas/sessions.d.ts +32 -0
- package/dist/schemas/sessions.d.ts.map +1 -0
- package/dist/schemas/sessions.js +11 -0
- package/dist/schemas/sessions.js.map +1 -0
- package/dist/schemas/settings.d.ts +554 -0
- package/dist/schemas/settings.d.ts.map +1 -0
- package/dist/schemas/settings.js +263 -0
- package/dist/schemas/settings.js.map +1 -0
- package/dist/schemas/share.d.ts +49 -0
- package/dist/schemas/share.d.ts.map +1 -0
- package/dist/schemas/share.js +26 -0
- package/dist/schemas/share.js.map +1 -0
- package/dist/schemas/shared.d.ts +22 -0
- package/dist/schemas/shared.d.ts.map +1 -0
- package/dist/schemas/shared.js +16 -0
- package/dist/schemas/shared.js.map +1 -0
- package/dist/schemas/system.d.ts +86 -0
- package/dist/schemas/system.d.ts.map +1 -0
- package/dist/schemas/system.js +64 -0
- package/dist/schemas/system.js.map +1 -0
- package/dist/schemas/terminal.d.ts +230 -0
- package/dist/schemas/terminal.d.ts.map +1 -0
- package/dist/schemas/terminal.js +133 -0
- package/dist/schemas/terminal.js.map +1 -0
- package/dist/schemas/usage.d.ts +113 -0
- package/dist/schemas/usage.d.ts.map +1 -0
- package/dist/schemas/usage.js +91 -0
- package/dist/schemas/usage.js.map +1 -0
- package/dist/schemas/vpn.d.ts +229 -0
- package/dist/schemas/vpn.d.ts.map +1 -0
- package/dist/schemas/vpn.js +115 -0
- package/dist/schemas/vpn.js.map +1 -0
- package/dist/schemas/webext.d.ts +122 -0
- package/dist/schemas/webext.d.ts.map +1 -0
- package/dist/schemas/webext.js +45 -0
- package/dist/schemas/webext.js.map +1 -0
- package/dist/schemas/workflows.d.ts +881 -0
- package/dist/schemas/workflows.d.ts.map +1 -0
- package/dist/schemas/workflows.js +164 -0
- package/dist/schemas/workflows.js.map +1 -0
- package/dist/schemas/workspace-repos.d.ts +143 -0
- package/dist/schemas/workspace-repos.d.ts.map +1 -0
- package/dist/schemas/workspace-repos.js +87 -0
- package/dist/schemas/workspace-repos.js.map +1 -0
- package/dist/schemas/workspace-search.d.ts +170 -0
- package/dist/schemas/workspace-search.d.ts.map +1 -0
- package/dist/schemas/workspace-search.js +85 -0
- package/dist/schemas/workspace-search.js.map +1 -0
- package/dist/schemas/workspace-setup.d.ts +48 -0
- package/dist/schemas/workspace-setup.d.ts.map +1 -0
- package/dist/schemas/workspace-setup.js +26 -0
- package/dist/schemas/workspace-setup.js.map +1 -0
- package/dist/schemas/workspace-tree.d.ts +120 -0
- package/dist/schemas/workspace-tree.d.ts.map +1 -0
- package/dist/schemas/workspace-tree.js +111 -0
- package/dist/schemas/workspace-tree.js.map +1 -0
- package/dist/webext-links.d.ts +14 -0
- package/dist/webext-links.d.ts.map +1 -0
- package/dist/webext-links.js +25 -0
- package/dist/webext-links.js.map +1 -0
- package/dist/webext-protocol.d.ts +8 -0
- package/dist/webext-protocol.d.ts.map +1 -0
- package/dist/webext-protocol.js +7 -0
- package/dist/webext-protocol.js.map +1 -0
- package/dist/workflow-faults.d.ts +1 -1
- package/dist/workflow-faults.d.ts.map +1 -1
- package/dist/workspace-state.d.ts +12 -8
- package/dist/workspace-state.d.ts.map +1 -1
- package/dist/workspace-state.js +15 -10
- package/dist/workspace-state.js.map +1 -1
- package/package.json +19 -8
- package/src/agent-catalog.test.ts +56 -55
- package/src/agent-catalog.ts +33 -33
- package/src/capability-ledger.test.ts +11 -2
- package/src/chores/chores.test.ts +1 -1
- package/src/chores/chores.ts +67 -2
- package/src/chores/probes.test.ts +65 -0
- package/src/chores/probes.ts +133 -1
- package/src/chores/stack.test.ts +19 -0
- package/src/chores/stack.ts +19 -3
- package/src/chores/verdict.test.ts +40 -20
- package/src/chores/verdict.ts +1 -1
- package/src/command-classes.test.ts +445 -0
- package/src/command-classes.ts +468 -0
- package/src/contracts/activity.contract.ts +1 -1
- package/src/contracts/agent.contract.ts +4 -13
- package/src/contracts/agents.contract.ts +6 -6
- package/src/contracts/automations.contract.ts +2 -2
- package/src/contracts/capabilities.contract.ts +3 -4
- package/src/contracts/chores.contract.ts +2 -1
- package/src/contracts/ci.contract.ts +2 -2
- package/src/contracts/claude.contract.ts +2 -2
- package/src/contracts/cursor.contract.ts +2 -2
- package/src/contracts/drafts.contract.ts +2 -1
- package/src/contracts/endpoints.contract.ts +2 -1
- package/src/contracts/exit.contract.ts +2 -1
- package/src/contracts/extensions.contract.ts +8 -7
- package/src/contracts/git.contract.ts +19 -18
- package/src/contracts/grok.contract.ts +2 -1
- package/src/contracts/history.contract.ts +2 -1
- package/src/contracts/host.contract.ts +4 -1
- package/src/contracts/intentic.contract.ts +2 -1
- package/src/contracts/inventory.contract.ts +1 -1
- package/src/contracts/issues.contract.ts +60 -0
- package/src/contracts/logs.contract.ts +7 -1
- package/src/contracts/loops.contract.ts +2 -2
- package/src/contracts/panels.contract.ts +2 -1
- package/src/contracts/personas.contract.ts +3 -3
- package/src/contracts/ports.contract.ts +3 -2
- package/src/contracts/prepush.contract.ts +2 -1
- package/src/contracts/providers.contract.ts +2 -1
- package/src/contracts/public.contract.ts +3 -2
- package/src/contracts/push.contract.ts +2 -1
- package/src/contracts/runner.contract.ts +18 -2
- package/src/contracts/secrets.contract.ts +2 -1
- package/src/contracts/sessions.contract.ts +1 -1
- package/src/contracts/settings.contract.ts +3 -9
- package/src/contracts/share.contract.ts +3 -2
- package/src/contracts/skills.contract.ts +2 -1
- package/src/contracts/system.contract.ts +6 -9
- package/src/contracts/translator.contract.ts +4 -1
- package/src/contracts/usage.contract.ts +1 -1
- package/src/contracts/vpn.contract.ts +2 -8
- package/src/contracts/webext.contract.ts +37 -0
- package/src/contracts/workflows.contract.ts +2 -2
- package/src/contracts/workspace.contract.ts +10 -12
- package/src/conversation-ids.test.ts +1 -1
- package/src/credential-material.test.ts +120 -0
- package/src/credential-material.ts +100 -0
- package/src/definition-action.ts +8 -0
- package/src/definition.ts +74 -10
- package/src/events.ts +84 -22
- package/src/fast-tier.ts +1 -1
- package/src/history-state.ts +17 -0
- package/src/host-protocol.ts +1 -1
- package/src/hostnames.test.ts +2 -2
- package/src/hostnames.ts +18 -2
- package/src/index.ts +65 -1
- package/src/listener-protocol.ts +1 -1
- package/src/quick-model.ts +1 -1
- package/src/routes.test.ts +4 -2
- package/src/runner-protocol.ts +35 -5
- package/src/runtime-state.ts +16 -0
- package/src/schemas/activity.ts +123 -0
- package/src/schemas/agent.ts +422 -0
- package/src/schemas/agents.ts +802 -0
- package/src/schemas/automations.ts +522 -0
- package/src/schemas/capabilities.ts +729 -0
- package/src/schemas/ci.ts +235 -0
- package/src/schemas/claude-gate.ts +13 -0
- package/src/schemas/codebase-health.ts +64 -0
- package/src/schemas/computers.ts +287 -0
- package/src/schemas/drafts.ts +108 -0
- package/src/schemas/environment.ts +276 -0
- package/src/schemas/exit.ts +222 -0
- package/src/schemas/extension-updates.ts +324 -0
- package/src/schemas/fast-mode.ts +8 -0
- package/src/schemas/git-history.ts +265 -0
- package/src/schemas/git.ts +430 -0
- package/src/schemas/history.ts +112 -0
- package/src/schemas/hosts.ts +37 -0
- package/src/schemas/intentic.ts +2 -0
- package/src/schemas/internal.ts +17 -0
- package/src/schemas/inventory.ts +68 -0
- package/src/schemas/issues.ts +279 -0
- package/src/schemas/logs.ts +96 -0
- package/src/schemas/loops.ts +401 -0
- package/src/schemas/maintenance.ts +471 -0
- package/src/schemas/marketplace.ts +23 -0
- package/src/schemas/panels.ts +99 -0
- package/src/schemas/personas.ts +281 -0
- package/src/schemas/plan-limits.ts +255 -0
- package/src/schemas/ports.ts +84 -0
- package/src/schemas/provider-oauth.ts +191 -0
- package/src/schemas/provider-subscriptions.ts +11 -0
- package/src/schemas/public.ts +52 -0
- package/src/schemas/push.ts +112 -0
- package/src/schemas/secrets.ts +68 -0
- package/src/schemas/sessions.ts +16 -0
- package/src/schemas/settings.ts +964 -0
- package/src/schemas/share.ts +71 -0
- package/src/schemas/shared.ts +32 -0
- package/src/schemas/system.ts +156 -0
- package/src/schemas/terminal.ts +288 -0
- package/src/schemas/usage.ts +303 -0
- package/src/{schemas.test.ts → schemas/version-seam.test.ts} +4 -2
- package/src/schemas/vpn.ts +215 -0
- package/src/schemas/webext.ts +108 -0
- package/src/schemas/workflows.ts +413 -0
- package/src/schemas/workspace-repos.ts +123 -0
- package/src/schemas/workspace-search.ts +141 -0
- package/src/schemas/workspace-setup.ts +43 -0
- package/src/schemas/workspace-tree.ts +234 -0
- package/src/title.test.ts +1 -1
- package/src/tunnel-ids.test.ts +3 -1
- package/src/webext-links.ts +90 -0
- package/src/webext-protocol.ts +27 -0
- package/src/workflow-faults.test.ts +1 -1
- package/src/workflow-faults.ts +1 -1
- package/src/workspace-state.test.ts +6 -4
- package/src/workspace-state.ts +35 -50
- package/dist/schemas.d.ts +0 -9909
- package/dist/schemas.d.ts.map +0 -1
- package/dist/schemas.js +0 -4288
- package/dist/schemas.js.map +0 -1
- package/src/schemas.ts +0 -10090
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
// loops: run a conversation again, and again, until a goal is met
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { STATE_DIR } from "@intentic/constants";
|
|
4
|
+
import { OutputFieldsSchema } from "../output-fields.js";
|
|
5
|
+
import { AgentHarnessSchema, AgentProviderSchema, ConversationIdSchema, RepoBaseSchema } from "./agent.js";
|
|
6
|
+
import { entryId } from "./internal.js";
|
|
7
|
+
/* THE RALPH LOOP. An automation answers "run this at 3am"; a loop answers "run this until it is actually done".
|
|
8
|
+
* The two are the opposite question and neither substitutes for the other: a schedule repeats on CADENCE and
|
|
9
|
+
* never converges, a loop repeats on CONVERGENCE and stops the moment its goal is met.
|
|
10
|
+
*
|
|
11
|
+
* A loop is an ATTRIBUTE OF A CONVERSATION, not a new kind of object. It drives ordinary turns on an ordinary
|
|
12
|
+
* fleet agent, which is what makes the worktree, the cost ledger, the transcript, the /agents card and the Stop
|
|
13
|
+
* button work on it without a line of new code, the same bet the acceptance extension makes when it derives
|
|
14
|
+
* conversation ids instead of owning session machinery.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
// How the next iteration meets its context, and the single most consequential field here.
|
|
18
|
+
//
|
|
19
|
+
// `fresh` is the canonical Ralph and the default: each iteration is a NEW provider session against the SAME
|
|
20
|
+
// worktree, so the filesystem, not the transcript, is the memory. Immune to context rot, so iteration 20 reads
|
|
21
|
+
// the tree as clearly as iteration 1, and it costs a re-read each time. The loop keeps a progress file for it
|
|
22
|
+
// (see LOOP_DIR) precisely because nothing else carries forward.
|
|
23
|
+
//
|
|
24
|
+
// `continue` resumes the provider session, so an iteration is a follow-up prompt. Cheaper (the prefix caches)
|
|
25
|
+
// and it keeps the reasoning, which is what a short refine-this loop wants. It degrades on long runs, and it
|
|
26
|
+
// degrades in the direction that matters: a session that has spent eleven turns arguing for its own approach is
|
|
27
|
+
// the worst available judge of whether that approach is finished.
|
|
28
|
+
export const LoopContextSchema = z.enum(["fresh", "continue"]);
|
|
29
|
+
export type LoopContext = z.infer<typeof LoopContextSchema>;
|
|
30
|
+
/* WHAT THE LOOP PRODUCES, asked separately from what ends it, because they are separate questions and
|
|
31
|
+
* conflating them is what makes a chain of sessions impossible to build.
|
|
32
|
+
*
|
|
33
|
+
* `none`, the loop produces nothing but its work. The classic "make the suite green": what it leaves behind
|
|
34
|
+
* is a green suite, and asking it to also file a report is asking it to spend a turn on paperwork.
|
|
35
|
+
* `claim`, the iteration writes `{done, reason, evidence?}`. Prose, but STRUCTURED prose: `done` is a boolean
|
|
36
|
+
* the daemon reads rather than a sentence it has to interpret. Self-assessment, so advisory by construction,
|
|
37
|
+
* it exists because plenty of goals have no command that can check them ("the README explains the auth
|
|
38
|
+
* flow"), not because a model's word for it is worth much.
|
|
39
|
+
* `json`, the iteration writes `{done, reason, data}` where `data` matches a declared field list. This is the
|
|
40
|
+
* one that makes a step's output usable as the next step's input: a paragraph mentioning three files cannot
|
|
41
|
+
* be fed to anything, `{files: [...]}` can.
|
|
42
|
+
*
|
|
43
|
+
* All three land in ONE file per iteration, with one shape, differing only in strictness. See LoopDocumentSchema.
|
|
44
|
+
*/
|
|
45
|
+
export const LoopOutputSchema = z.discriminatedUnion("kind", [
|
|
46
|
+
z.object({
|
|
47
|
+
kind: z
|
|
48
|
+
.literal("none")
|
|
49
|
+
.describe(
|
|
50
|
+
"It produces nothing but its work. The classic make the suite pass: what it leaves behind is a passing suite, and asking it to also file a report is asking it to spend a round on paperwork.",
|
|
51
|
+
),
|
|
52
|
+
}),
|
|
53
|
+
z.object({
|
|
54
|
+
kind: z
|
|
55
|
+
.literal("claim")
|
|
56
|
+
.describe(
|
|
57
|
+
"Each round says whether it is done and why. Structured prose: done is a value read rather than a sentence interpreted. Self-assessment, so advisory by construction; it exists because plenty of goals have no command that could check them.",
|
|
58
|
+
),
|
|
59
|
+
}),
|
|
60
|
+
z.object({
|
|
61
|
+
kind: z
|
|
62
|
+
.literal("json")
|
|
63
|
+
.describe(
|
|
64
|
+
"Each round writes a real answer in a shape you declared. This is the one that makes a step's output usable as the next step's input: a paragraph mentioning three files cannot be fed to anything, a list of three files can.",
|
|
65
|
+
),
|
|
66
|
+
fields: OutputFieldsSchema.describe("The shape that answer has to match."),
|
|
67
|
+
}),
|
|
68
|
+
]);
|
|
69
|
+
export type LoopOutput = z.infer<typeof LoopOutputSchema>;
|
|
70
|
+
/* WHAT ELSE HAS TO BE TRUE, checks that are not the worker's own word, ANDed with the output above.
|
|
71
|
+
*
|
|
72
|
+
* `command` is a shell one-liner run in the conversation's tree; exit 0 ⇒ satisfied. Deterministic, free, and
|
|
73
|
+
* the only signal here whose answer does not come from a model. It is the automation `guard` with the sign
|
|
74
|
+
* flipped, and it runs through the same runner. `pnpm test` passing beats any amount of self-report.
|
|
75
|
+
*
|
|
76
|
+
* `judge` puts a SEPARATE, tool-less call on the question: it reads the iteration's own report and rules
|
|
77
|
+
* against a rubric, having done none of the work and nothing invested in it being finished.
|
|
78
|
+
*
|
|
79
|
+
* The rule both encode, and the reason they are kept apart from the output: the check must be a DIFFERENT CALL
|
|
80
|
+
* from the work, or it is not a check. An output is what the worker says; a check is what someone else says.
|
|
81
|
+
*/
|
|
82
|
+
export const LoopCheckSchema = z.discriminatedUnion("kind", [
|
|
83
|
+
z.object({
|
|
84
|
+
kind: z
|
|
85
|
+
.literal("command")
|
|
86
|
+
.describe(
|
|
87
|
+
"Run something and see if it passes. Deterministic, free, and the only signal here whose answer does not come from a model. A passing test suite beats any amount of self-report.",
|
|
88
|
+
),
|
|
89
|
+
command: z.string().min(1).describe("The command to run in the conversation's own tree. Exiting cleanly means satisfied."),
|
|
90
|
+
}),
|
|
91
|
+
// The rubric is what the judge is asked; absent `model` runs it on the quick rung the other helpers use.
|
|
92
|
+
z.object({
|
|
93
|
+
kind: z
|
|
94
|
+
.literal("judge")
|
|
95
|
+
.describe(
|
|
96
|
+
"Put the question to a separate model with no tools, which reads the round's own report and rules on it, having done none of the work and nothing invested in its being finished.",
|
|
97
|
+
),
|
|
98
|
+
rubric: z.string().min(1).describe("What that judge is asked."),
|
|
99
|
+
model: z.string().optional().describe("Which model judges. Leave it out for the cheap one the other small jobs use."),
|
|
100
|
+
}),
|
|
101
|
+
]);
|
|
102
|
+
export type LoopCheck = z.infer<typeof LoopCheckSchema>;
|
|
103
|
+
/* THE VERDICT FILE an iteration writes, one shape for all three output kinds, because the loop reads it the
|
|
104
|
+
* same way whatever was declared and only the validation of `data` differs.
|
|
105
|
+
*
|
|
106
|
+
* It is a FILE rather than a sentence in the reply for the reason every structured output in this codebase is
|
|
107
|
+
* a file: a reply has to be parsed out of prose the model is simultaneously using to talk to a person, and the
|
|
108
|
+
* two demands pull against each other until neither is served. A file has one job.
|
|
109
|
+
*/
|
|
110
|
+
export const LoopDocumentSchema = z.object({
|
|
111
|
+
// Whether the goal is met NOW. The loop's own reading of this is the whole point of the file.
|
|
112
|
+
done: z.boolean().describe("Whether the goal is met. Reading this is the whole point of the file."),
|
|
113
|
+
// One line: why it is or is not met. The single most-read string in the feature, it is what the next
|
|
114
|
+
// iteration reads first and what the history row shows.
|
|
115
|
+
reason: z.string().describe("Why, in one line. The most-read sentence in the feature: the next round reads it first and the history shows it."),
|
|
116
|
+
// What the iteration checked to know that. Optional because a model with nothing to point at should say so
|
|
117
|
+
// by omitting it rather than by inventing a sentence.
|
|
118
|
+
evidence: z
|
|
119
|
+
.string()
|
|
120
|
+
.optional()
|
|
121
|
+
.describe(
|
|
122
|
+
"What was checked to know that. Optional, so a round with nothing to point at says so by leaving it out rather than by inventing a sentence.",
|
|
123
|
+
),
|
|
124
|
+
// The declared fields, present only for a `json` output and validated against them there.
|
|
125
|
+
data: z
|
|
126
|
+
.record(z.string(), z.unknown())
|
|
127
|
+
.optional()
|
|
128
|
+
.describe("The declared answer, for a loop that asked for one, checked against the shape it declared."),
|
|
129
|
+
});
|
|
130
|
+
export type LoopDocument = z.infer<typeof LoopDocumentSchema>;
|
|
131
|
+
// Enough iterations for a real convergence, few enough that a misconfigured loop is a bounded mistake. A loop
|
|
132
|
+
// that has not converged in 50 turns is not one iteration short of it.
|
|
133
|
+
const LOOP_ITERATIONS_MAX = 50;
|
|
134
|
+
export const LoopSchema = z.object({
|
|
135
|
+
// The conversation the loop drives, its fleet card, its worktree, its transcript.
|
|
136
|
+
conversationId: ConversationIdSchema.describe(
|
|
137
|
+
"The conversation to loop. It need not exist yet: naming a fresh one opens it, which is what lets run this until it passes be the first thing you ever say.",
|
|
138
|
+
),
|
|
139
|
+
// What "done" means, in the user's words. Rides into every iteration's prompt (and into the judge's
|
|
140
|
+
// question) so the model is told the goal it is being measured against rather than left to infer it.
|
|
141
|
+
goal: z
|
|
142
|
+
.string()
|
|
143
|
+
.min(1)
|
|
144
|
+
.describe(
|
|
145
|
+
"What done means, in your words. It goes into every round's instructions and into the judge's question, so the model is told the bar rather than left to infer it.",
|
|
146
|
+
),
|
|
147
|
+
// What each iteration is asked to DO. Separate from `goal` because they are different sentences: "make the
|
|
148
|
+
// suite green" is the goal, "run the tests, pick the top failure, fix it" is the instruction.
|
|
149
|
+
prompt: z
|
|
150
|
+
.string()
|
|
151
|
+
.min(1)
|
|
152
|
+
.describe("What each round is asked to do. The suite passes is the goal; run the tests, take the top failure, fix it is the instruction."),
|
|
153
|
+
context: LoopContextSchema.describe(
|
|
154
|
+
"How each round meets the last. Starting fresh makes the files the memory rather than the conversation, so the twentieth round reads the tree as clearly as the first, and costs a re-read each time. Carrying on is cheaper and keeps the reasoning, which suits a short polish-this loop and degrades on long ones: a session that has spent eleven rounds arguing for its own approach is the worst available judge of whether that approach is finished.",
|
|
155
|
+
),
|
|
156
|
+
output: LoopOutputSchema,
|
|
157
|
+
/* Everything besides the worker's own word that has to hold before the loop may end. Ordinarily one or
|
|
158
|
+
* none; a list because "the suite is green AND the report is written" is a real completion bar and
|
|
159
|
+
* expressing it as two loops would run the work twice. */
|
|
160
|
+
checks: z
|
|
161
|
+
.array(LoopCheckSchema)
|
|
162
|
+
.describe(
|
|
163
|
+
"What else has to be true, all of them together. A list because the suite passes and the report is written is a real bar, and running it as two loops would do the work twice.",
|
|
164
|
+
),
|
|
165
|
+
maxIterations: z
|
|
166
|
+
.number()
|
|
167
|
+
.int()
|
|
168
|
+
.min(1)
|
|
169
|
+
.max(LOOP_ITERATIONS_MAX)
|
|
170
|
+
.describe("How many rounds before it gives up. A loop that has not got there in fifty is not one round short of it."),
|
|
171
|
+
// The spend ceiling in USD across the whole loop, summed from the turns' own usage frames. Optional because
|
|
172
|
+
// a 3-iteration loop does not need one; strongly wanted on anything unattended, since this is the first
|
|
173
|
+
// feature in the sandbox that can spend without a person pressing anything between turns.
|
|
174
|
+
maxSpendUsd: z
|
|
175
|
+
.number()
|
|
176
|
+
.positive()
|
|
177
|
+
.optional()
|
|
178
|
+
.describe(
|
|
179
|
+
"A ceiling on what the whole loop may spend, in dollars. Optional for a short loop somebody is watching, and strongly wanted otherwise: this is the first thing here that can keep spending with nobody pressing anything between rounds.",
|
|
180
|
+
),
|
|
181
|
+
/* Stop after this many CONSECUTIVE iterations that changed nothing in the tree.
|
|
182
|
+
*
|
|
183
|
+
* The guard that matters most in practice, and the one whose absence is expensive. The failure mode of a
|
|
184
|
+
* loop is not runaway success, it is an agent that re-reads the same three files, restates the same plan,
|
|
185
|
+
* declares more work remains, and does that eleven times. Nothing about that is an error, every turn
|
|
186
|
+
* succeeds, so only "the tree did not move" catches it. */
|
|
187
|
+
stallLimit: z
|
|
188
|
+
.number()
|
|
189
|
+
.int()
|
|
190
|
+
.min(1)
|
|
191
|
+
.describe(
|
|
192
|
+
"Stop after this many rounds in a row that changed nothing on disk. The guard that matters most: a loop's failure is not runaway success, it is an agent re-reading the same three files, restating the same plan and declaring more work remains, eleven times. Every one of those rounds succeeds, so only the tree not moving catches it.",
|
|
193
|
+
),
|
|
194
|
+
// Whether the iterations run in the conversation's own worktree or on the shared tree. Recorded on the loop
|
|
195
|
+
// rather than read off the conversation because a loop can OPEN one, and because it decides where the stop
|
|
196
|
+
// command runs: a check against /work would be testing code an isolated loop has not landed yet.
|
|
197
|
+
isolated: z
|
|
198
|
+
.boolean()
|
|
199
|
+
.describe(
|
|
200
|
+
"Whether it works in the conversation's own private copy or in the shared tree. It also decides where a check runs: testing the shared tree would be testing code this loop has not merged yet.",
|
|
201
|
+
),
|
|
202
|
+
// Which provider / harness / model the iterations run on; absent ⇒ the conversation's own last choice, then
|
|
203
|
+
// the provider default. The same three passthroughs an automation carries, for the same reason: a headless
|
|
204
|
+
// driver has no composer to read them from.
|
|
205
|
+
agent: AgentProviderSchema.optional().describe("Which provider the rounds run on. Absent falls back to the conversation's own last choice."),
|
|
206
|
+
harness: AgentHarnessSchema.optional().describe("Which agentic loop they run on."),
|
|
207
|
+
account: z.string().optional().describe("Which account pays."),
|
|
208
|
+
model: z.string().optional().describe("Which model."),
|
|
209
|
+
// Which persona the iterations act as (AgentTurnSchema.actsAs, read its note for why this is not spelled
|
|
210
|
+
// `account`). The fourth passthrough an automation carries, and it matters here for the automation's
|
|
211
|
+
// reason: every iteration is unattended, and an unattended turn with no persona reaches no logged-in
|
|
212
|
+
// account at all, pinning a card is the one way a loop gets hands.
|
|
213
|
+
actsAs: entryId
|
|
214
|
+
.optional()
|
|
215
|
+
.describe(
|
|
216
|
+
"Which persona the rounds act as. It matters here: every round is unwatched, and an unwatched turn naming no persona reaches no signed-in account at all, so pinning one is how a loop gets hands.",
|
|
217
|
+
),
|
|
218
|
+
// A workflow persists these on its underlying loop so restart recovery cannot silently change the checkout
|
|
219
|
+
// or let a candidate inherit the sandbox's global auto-land posture on a later iteration.
|
|
220
|
+
worktreeBase: z
|
|
221
|
+
.array(RepoBaseSchema)
|
|
222
|
+
.min(1)
|
|
223
|
+
.max(50)
|
|
224
|
+
.optional()
|
|
225
|
+
.describe("Pin the private copy to these exact commits, so a restart cannot quietly change what the loop is working on."),
|
|
226
|
+
autoLand: z.boolean().optional().describe("Whether the work merges as it goes."),
|
|
227
|
+
});
|
|
228
|
+
export type Loop = z.infer<typeof LoopSchema>;
|
|
229
|
+
// Can this loop ever end on its own terms? A loop with nothing to produce and nothing to check runs to its
|
|
230
|
+
// iteration ceiling and reports `exhausted`, having been unable to succeed from the moment it was configured.
|
|
231
|
+
// A predicate rather than a schema refinement because two routes want it as one, at different moments: `start`
|
|
232
|
+
// refuses an ad-hoc loop, and `saveDesign` refuses a SAVED one, which is the more valuable of the two, since a
|
|
233
|
+
// saved loop that cannot converge is a trap everyone who picks it afterwards pays a full run to discover.
|
|
234
|
+
export const loopCanConverge = (loop: Pick<Loop, "output" | "checks">): boolean => loop.output.kind !== "none" || loop.checks.length > 0;
|
|
235
|
+
/* Where a loop keeps what it must not lose between iterations: <workspace>/.intentic/records/artifacts/loops/<conversationId>/.
|
|
236
|
+
*
|
|
237
|
+
* Under `.intentic` for the reason the acceptance runs are, it is outside every repo and bound back SHARED
|
|
238
|
+
* into an isolated turn's worktree, so the agent writes and the browser reads the same tree, with nothing to
|
|
239
|
+
* land and no git noise. `progress.md` is the loop's memory in `fresh` mode and its audit trail in `continue`
|
|
240
|
+
* mode; `iteration-<n>.json` is the verdict a `claim` stop reads. */
|
|
241
|
+
export const LOOP_DIR = `${STATE_DIR}/records/artifacts/loops`;
|
|
242
|
+
// Why an iteration ended, which is not the same question as how the LOOP ended. `continue` is the ordinary
|
|
243
|
+
// "not done yet"; `error` is a turn that surfaced an error frame, which does NOT end the loop by itself, a
|
|
244
|
+
// failing turn is often exactly what the next iteration is supposed to fix.
|
|
245
|
+
export const LoopIterationSchema = z.object({
|
|
246
|
+
n: z.number().int().min(1).describe("Which round this was."),
|
|
247
|
+
at: z.number().describe("When it ran, in milliseconds."),
|
|
248
|
+
outcome: z
|
|
249
|
+
.enum(["continue", "done", "error"])
|
|
250
|
+
.describe(
|
|
251
|
+
"How the round ended, which is not the same question as how the loop did. A round that errored does not end the loop by itself: a failing turn is often exactly what the next round is meant to fix.",
|
|
252
|
+
),
|
|
253
|
+
// The stop check's own words, the guard's output tail, the claim's reason, the judge's verdict. What the
|
|
254
|
+
// run history is actually read for: "why did it keep going" and "why did it stop".
|
|
255
|
+
detail: z
|
|
256
|
+
.string()
|
|
257
|
+
.optional()
|
|
258
|
+
.describe("What the check said, in its own words. What a run history is actually read for: why it kept going, and why it stopped."),
|
|
259
|
+
costUsd: z.number().optional().describe("What the round cost, in dollars."),
|
|
260
|
+
// Whether the tree moved this iteration. Feeds the stall detector, and is worth showing per row: three
|
|
261
|
+
// unchanged iterations in a history is the shape of a loop that is not working.
|
|
262
|
+
changed: z.boolean().describe("Whether anything on disk moved. Three unchanged rounds in a row is the shape of a loop that is not working."),
|
|
263
|
+
// The provider session this iteration ran on, the door from a history row to a readable transcript.
|
|
264
|
+
sessionId: z.string().optional().describe("The session it ran on, and the way from a history row to a readable record."),
|
|
265
|
+
});
|
|
266
|
+
export type LoopIteration = z.infer<typeof LoopIterationSchema>;
|
|
267
|
+
/* How a loop ended, and every one of these is a distinct thing to tell the user.
|
|
268
|
+
*
|
|
269
|
+
* `done`, the stop condition was met. The only success.
|
|
270
|
+
* `exhausted`, maxIterations ran out with the goal unmet.
|
|
271
|
+
* `stalled`, stallLimit consecutive iterations changed nothing. Reported apart from `exhausted` because the
|
|
272
|
+
* remedy is different: exhausted says "give it more room", stalled says "it is not making progress and more
|
|
273
|
+
* room will not help".
|
|
274
|
+
* `overspent`, maxSpendUsd was reached.
|
|
275
|
+
* `stopped`, the user pressed Stop.
|
|
276
|
+
* `error`, the loop itself failed (not a turn inside it; see LoopIteration.outcome).
|
|
277
|
+
*/
|
|
278
|
+
export const LoopStateSchema = z.enum(["running", "done", "exhausted", "stalled", "overspent", "stopped", "error"]);
|
|
279
|
+
export type LoopState = z.infer<typeof LoopStateSchema>;
|
|
280
|
+
export const LoopRecordSchema = LoopSchema.extend({
|
|
281
|
+
state: LoopStateSchema.describe(
|
|
282
|
+
"How it ended, and each of these is a different thing to be told. Out of rounds says give it more room; stalled says it is not making progress and more room will not help. Overspent, stopped by a person, and the loop itself failing are all their own answers.",
|
|
283
|
+
),
|
|
284
|
+
startedAt: z.number().describe("When it began, in milliseconds."),
|
|
285
|
+
endedAt: z.number().optional().describe("When it ended, in milliseconds."),
|
|
286
|
+
/* How many times a daemon BOOT has picked this loop back up. The record is its own journal: a loop still
|
|
287
|
+
* marked `running` at boot is exactly one the daemon died under, which is the same trick turn-journal.ts
|
|
288
|
+
* plays with its files and needs no second store to play it.
|
|
289
|
+
*
|
|
290
|
+
* Counted, not just flagged, for the reason the turn journal counts its attempts, a loop whose iteration
|
|
291
|
+
* reliably kills the daemon (an OOM in a test it keeps running) would otherwise be resurrected on every
|
|
292
|
+
* boot forever, and the container is recreated on every sandbox update. */
|
|
293
|
+
resumed: z
|
|
294
|
+
.number()
|
|
295
|
+
.int()
|
|
296
|
+
.min(0)
|
|
297
|
+
.describe(
|
|
298
|
+
"How many times the sandbox restarted under it and picked it back up. Counted rather than flagged, so a loop whose round reliably kills the sandbox is not resurrected on every boot for ever.",
|
|
299
|
+
),
|
|
300
|
+
// Why the loop ended, for the states whose reason isn't in their name (`error`, and a `done` whose stop
|
|
301
|
+
// check said something worth keeping).
|
|
302
|
+
detail: z.string().optional().describe("Why it ended, for the endings whose reason is not in their name."),
|
|
303
|
+
iterations: z
|
|
304
|
+
.array(LoopIterationSchema)
|
|
305
|
+
.describe("Every round, in order. Why it stopped at the fourth is the question a loop gets read for, and this is the answer."),
|
|
306
|
+
});
|
|
307
|
+
export type LoopRecord = z.infer<typeof LoopRecordSchema>;
|
|
308
|
+
export const LoopsListSchema = z.object({
|
|
309
|
+
loops: z.array(LoopRecordSchema).describe("Every loop this workspace has run, newest first, kept after they end."),
|
|
310
|
+
});
|
|
311
|
+
export const LoopIdParamSchema = z.object({ conversationId: ConversationIdSchema.describe("Which conversation's loop.") });
|
|
312
|
+
/* ---- saved loops: the machinery, kept; the job, typed fresh each time ----
|
|
313
|
+
*
|
|
314
|
+
* A SAVED LOOP IS A LOOP WITH ITS GOAL TAKEN OUT, and that subtraction is the whole idea. Everything a loop
|
|
315
|
+
* needs besides "what are we doing" is the same every time somebody sets one up, end on `pnpm test`, fresh
|
|
316
|
+
* context, eight rounds, five dollars, stop after two idle ones, and every one of those was being retyped, in
|
|
317
|
+
* a modal, before any work could begin. The goal is the only field that is genuinely new each time, and it is
|
|
318
|
+
* the one field the user has ALREADY WRITTEN: it is sitting in the composer.
|
|
319
|
+
*
|
|
320
|
+
* So this holds the machinery and the composer holds the job, which makes a loop the same gesture as a
|
|
321
|
+
* workflow, pick the shape, type the request, send. `WorkflowSchema` and this are deliberately siblings: both
|
|
322
|
+
* are designs, both are picked from the composer, both leave the sentence to the message. What a workflow
|
|
323
|
+
* spreads across sessions, a loop repeats in one.
|
|
324
|
+
*
|
|
325
|
+
* NO `conversationId` AND NO `isolated`, unlike the Loop this becomes. Both are facts about the agent the loop
|
|
326
|
+
* is aimed at, decided at the moment of sending and unknowable when the design is written, a saved loop that
|
|
327
|
+
* remembered a conversation would be a loop that could only ever be run once.
|
|
328
|
+
*/
|
|
329
|
+
export const LoopDesignSchema = z.object({
|
|
330
|
+
id: entryId.describe("The design's id."),
|
|
331
|
+
// What it is called on the composer badge and in the picker, so it has to survive being read at pill width.
|
|
332
|
+
name: z.string().min(1).max(60).describe("What to call it. Short, because it has to be readable on a small badge."),
|
|
333
|
+
// One line: what this loop is FOR. Optional, because a well-named loop has already said it.
|
|
334
|
+
description: z.string().max(280).optional().describe("What it is for, in one line. Optional, because a well-named loop has already said it."),
|
|
335
|
+
/* What each iteration is asked to do, when that is worth saying twice. Optional for the reason the ad-hoc
|
|
336
|
+
* form made it optional: `goal` and `prompt` are different sentences, but making somebody write both before
|
|
337
|
+
* anything runs doubles the cost of trying a loop at all. Absent ⇒ the iteration works towards the goal
|
|
338
|
+
* however it sees fit. */
|
|
339
|
+
prompt: z
|
|
340
|
+
.string()
|
|
341
|
+
.optional()
|
|
342
|
+
.describe(
|
|
343
|
+
"What each round is asked to do, when that is worth saying separately from the goal. Absent means each round works towards the goal however it sees fit.",
|
|
344
|
+
),
|
|
345
|
+
context: LoopContextSchema.describe("How each round meets the last: starting clean, or carrying on."),
|
|
346
|
+
output: LoopOutputSchema.describe("What it has to produce."),
|
|
347
|
+
checks: z.array(LoopCheckSchema).describe("What else has to be true."),
|
|
348
|
+
maxIterations: z.number().int().min(1).max(LOOP_ITERATIONS_MAX).describe("How many rounds before it gives up."),
|
|
349
|
+
maxSpendUsd: z.number().positive().optional().describe("A ceiling on what it may spend, in dollars."),
|
|
350
|
+
stallLimit: z.number().int().min(1).describe("Stop after this many rounds in a row that changed nothing."),
|
|
351
|
+
});
|
|
352
|
+
export type LoopDesign = z.infer<typeof LoopDesignSchema>;
|
|
353
|
+
export const LoopDesignsListSchema = z.object({
|
|
354
|
+
designs: z
|
|
355
|
+
.array(LoopDesignSchema)
|
|
356
|
+
.describe("Saved loops: the machinery with the goal left out, so one design can be pointed at a different job every time."),
|
|
357
|
+
});
|
|
358
|
+
// Create and update on one route with the intent spelled out, exactly as a workflow saves, so an id collision
|
|
359
|
+
// cannot silently turn "new loop" into "replace the one you had".
|
|
360
|
+
export const LoopDesignSaveSchema = z.object({
|
|
361
|
+
design: LoopDesignSchema.describe("The design to write."),
|
|
362
|
+
create: z
|
|
363
|
+
.boolean()
|
|
364
|
+
.describe(
|
|
365
|
+
"Whether you mean to make a new one or replace an existing one, so an id that happens to collide cannot silently overwrite the one you had.",
|
|
366
|
+
),
|
|
367
|
+
});
|
|
368
|
+
export const LoopDesignIdParamSchema = z.object({ id: entryId.describe("Which saved loop.") });
|
|
369
|
+
/* The design, aimed at an agent, the one conversion in the feature, kept here so the composer and anything
|
|
370
|
+
* else that starts a saved loop cannot disagree about what a saved loop MEANS. The goal is the message the user
|
|
371
|
+
* typed; `isolated` is a fact about the agent it is aimed at. */
|
|
372
|
+
export const loopFromDesign = (design: LoopDesign, aim: { conversationId: string; goal: string; isolated: boolean }): Loop => ({
|
|
373
|
+
conversationId: aim.conversationId,
|
|
374
|
+
goal: aim.goal,
|
|
375
|
+
prompt: design.prompt ?? "Work towards the goal above. Do the next most useful thing.",
|
|
376
|
+
context: design.context,
|
|
377
|
+
output: design.output,
|
|
378
|
+
checks: design.checks,
|
|
379
|
+
maxIterations: design.maxIterations,
|
|
380
|
+
...(design.maxSpendUsd === undefined ? {} : { maxSpendUsd: design.maxSpendUsd }),
|
|
381
|
+
stallLimit: design.stallLimit,
|
|
382
|
+
isolated: aim.isolated,
|
|
383
|
+
});
|
|
384
|
+
/* HOW A SAVED LOOP ENDS, IN ONE LINE, the sentence under its name in the picker and on its card, computed
|
|
385
|
+
* rather than stored so the two can never describe the same loop differently. Ordered as it is read: the bar it
|
|
386
|
+
* has to clear first, then how far it may go trying. */
|
|
387
|
+
export const loopDesignLine = (design: LoopDesign): string => {
|
|
388
|
+
const command = design.checks.find((check) => check.kind === "command");
|
|
389
|
+
const ends =
|
|
390
|
+
command !== undefined
|
|
391
|
+
? command.command
|
|
392
|
+
: design.checks.some((check) => check.kind === "judge")
|
|
393
|
+
? "a reviewer agrees"
|
|
394
|
+
: design.output.kind === "none"
|
|
395
|
+
? "nothing checks it"
|
|
396
|
+
: "the agent says so";
|
|
397
|
+
const ceilings = [`${design.maxIterations} rounds`, design.maxSpendUsd === undefined ? `` : `$${design.maxSpendUsd}`].filter(
|
|
398
|
+
(part) => part !== ``,
|
|
399
|
+
);
|
|
400
|
+
return [ends, ...ceilings].join(" · ");
|
|
401
|
+
};
|