@xingular/harness 1.0.0 → 1.2.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/CHANGELOG.md +46 -5
- package/README.md +75 -21
- package/dist/cli.js +17421 -8711
- package/dist/sdk/accounts/accounts.d.ts +27 -3
- package/dist/sdk/accounts/accounts.js +78 -24
- package/dist/sdk/accounts/secrets.d.ts +12 -0
- package/dist/sdk/accounts/secrets.js +114 -7
- package/dist/sdk/accounts/store.d.ts +26 -1
- package/dist/sdk/accounts/store.js +1 -1
- package/dist/sdk/agents/builtin.d.ts +2 -0
- package/dist/sdk/agents/builtin.js +48 -0
- package/dist/sdk/agents/narrow.d.ts +13 -0
- package/dist/sdk/agents/narrow.js +29 -0
- package/dist/sdk/agents/planResearch.d.ts +5 -0
- package/dist/sdk/agents/planResearch.js +19 -0
- package/dist/sdk/agents/profiles.d.ts +81 -0
- package/dist/sdk/agents/profiles.js +226 -0
- package/dist/sdk/annotations/bridge.d.ts +42 -0
- package/dist/sdk/annotations/bridge.js +264 -0
- package/dist/sdk/annotations/capture.d.ts +116 -0
- package/dist/sdk/annotations/capture.js +308 -0
- package/dist/sdk/annotations/delivery.d.ts +72 -0
- package/dist/sdk/annotations/delivery.js +130 -0
- package/dist/sdk/annotations/inspect.d.ts +10 -0
- package/dist/sdk/annotations/inspect.js +33 -0
- package/dist/sdk/annotations/isolated.d.ts +6 -0
- package/dist/sdk/annotations/isolated.js +51 -0
- package/dist/sdk/annotations/pageScript.d.ts +28 -0
- package/dist/sdk/annotations/pageScript.js +871 -0
- package/dist/sdk/annotations/part.d.ts +10 -0
- package/dist/sdk/annotations/part.js +155 -0
- package/dist/sdk/annotations/queue.d.ts +4 -0
- package/dist/sdk/annotations/queue.js +40 -0
- package/dist/sdk/annotations/serverMethods.d.ts +3 -0
- package/dist/sdk/annotations/serverMethods.js +62 -0
- package/dist/sdk/annotations/store.d.ts +167 -0
- package/dist/sdk/annotations/store.js +394 -0
- package/dist/sdk/browser/backend.d.ts +16 -0
- package/dist/sdk/browser/backend.js +17 -0
- package/dist/sdk/browser/contracts.d.ts +19 -0
- package/dist/sdk/browser/contracts.js +116 -0
- package/dist/sdk/browser/index.d.ts +14 -3
- package/dist/sdk/browser/index.js +11 -4
- package/dist/sdk/browser/serverMethods.d.ts +3 -0
- package/dist/sdk/browser/serverMethods.js +7 -0
- package/dist/sdk/browser/session.d.ts +1 -0
- package/dist/sdk/browser/session.js +45 -9
- package/dist/sdk/browser/tools.d.ts +1 -4
- package/dist/sdk/browser/tools.js +14 -91
- package/dist/sdk/cli.js +24 -15
- package/dist/sdk/commands/list.d.ts +3 -0
- package/dist/sdk/commands/list.js +75 -0
- package/dist/sdk/commands/registry.d.ts +250 -0
- package/dist/sdk/commands/registry.js +47 -0
- package/dist/sdk/commands/routes.d.ts +16 -0
- package/dist/sdk/commands/routes.js +33 -0
- package/dist/sdk/core/bus.js +1 -1
- package/dist/sdk/core/commandBudget.d.ts +23 -0
- package/dist/sdk/core/commandBudget.js +57 -0
- package/dist/sdk/core/env.d.ts +1 -1
- package/dist/sdk/core/env.js +1 -1
- package/dist/sdk/core/index.js +17 -1
- package/dist/sdk/core/interactiveProfile.d.ts +46 -0
- package/dist/sdk/core/interactiveProfile.js +143 -0
- package/dist/sdk/core/workspace.d.ts +13 -0
- package/dist/sdk/core/workspace.js +88 -0
- package/dist/sdk/core/workspaceBashTool.d.ts +4 -0
- package/dist/sdk/core/workspaceBashTool.js +36 -0
- package/dist/sdk/core/workspaceSandbox.d.ts +31 -0
- package/dist/sdk/core/workspaceSandbox.js +320 -0
- package/dist/sdk/core/workspaceWriteOperations.d.ts +22 -0
- package/dist/sdk/core/workspaceWriteOperations.js +206 -0
- package/dist/sdk/doctor/serverMethods.d.ts +3 -0
- package/dist/sdk/doctor/serverMethods.js +8 -0
- package/dist/sdk/doctor/types.d.ts +2 -2
- package/dist/sdk/harness.d.ts +22 -0
- package/dist/sdk/harness.js +84 -5
- package/dist/sdk/history/recall.js +8 -8
- package/dist/sdk/history/serverMethods.d.ts +3 -0
- package/dist/sdk/history/serverMethods.js +8 -0
- package/dist/sdk/hub/cli.d.ts +1 -1
- package/dist/sdk/hub/cli.js +1 -1
- package/dist/sdk/hub/schema.d.ts +1 -1
- package/dist/sdk/hub/serverMethods.d.ts +3 -0
- package/dist/sdk/hub/serverMethods.js +11 -0
- package/dist/sdk/index.d.ts +16 -1
- package/dist/sdk/index.js +10 -0
- package/dist/sdk/mcp/connections.js +14 -7
- package/dist/sdk/mcp/serverMethods.d.ts +3 -0
- package/dist/sdk/mcp/serverMethods.js +22 -0
- package/dist/sdk/pi/runtime.d.ts +2 -1
- package/dist/sdk/pi/runtime.js +2 -2
- package/dist/sdk/plugins/builtin.d.ts +1 -0
- package/dist/sdk/plugins/builtin.js +145 -33
- package/dist/sdk/plugins/builtinRegistry.d.ts +60 -0
- package/dist/sdk/plugins/builtinRegistry.js +71 -0
- package/dist/sdk/plugins/catalogue.js +2 -1
- package/dist/sdk/plugins/cli.d.ts +1 -1
- package/dist/sdk/plugins/cli.js +4 -3
- package/dist/sdk/plugins/commandPrefix.d.ts +8 -0
- package/dist/sdk/plugins/commandPrefix.js +21 -0
- package/dist/sdk/plugins/firstParty.d.ts +1 -1
- package/dist/sdk/plugins/firstParty.js +8 -2
- package/dist/sdk/plugins/inventory.js +4 -3
- package/dist/sdk/plugins/manifest.d.ts +2 -0
- package/dist/sdk/plugins/manifest.js +2 -1
- package/dist/sdk/plugins/surfaces.d.ts +5 -0
- package/dist/sdk/plugins/surfaces.js +11 -0
- package/dist/sdk/plugins/types.d.ts +15 -0
- package/dist/sdk/prompt/compile.d.ts +19 -2
- package/dist/sdk/prompt/compile.js +79 -26
- package/dist/sdk/prompt/standard.d.ts +17 -0
- package/dist/sdk/prompt/standard.js +21 -0
- package/dist/sdk/refine/cli.d.ts +1 -1
- package/dist/sdk/refine/cli.js +2 -2
- package/dist/sdk/refine/serverMethods.d.ts +3 -0
- package/dist/sdk/refine/serverMethods.js +20 -0
- package/dist/sdk/server/methods.js +27 -86
- package/dist/sdk/server/params.d.ts +4 -0
- package/dist/sdk/server/params.js +11 -0
- package/dist/sdk/server/remote.js +36 -11
- package/dist/sdk/sessions/compactionCheckpoint.d.ts +11 -0
- package/dist/sdk/sessions/compactionCheckpoint.js +79 -0
- package/dist/sdk/sessions/continuation.d.ts +3 -0
- package/dist/sdk/sessions/continuation.js +5 -1
- package/dist/sdk/sessions/contracts.d.ts +185 -0
- package/dist/sdk/sessions/contracts.js +101 -4
- package/dist/sdk/sessions/control.d.ts +72 -0
- package/dist/sdk/sessions/control.js +158 -0
- package/dist/sdk/sessions/initialBash.d.ts +7 -0
- package/dist/sdk/sessions/initialBash.js +7 -0
- package/dist/sdk/sessions/planMode.d.ts +18 -4
- package/dist/sdk/sessions/planMode.js +82 -16
- package/dist/sdk/sessions/reasoningSummaries.d.ts +2 -2
- package/dist/sdk/sessions/reasoningSummaries.js +3 -3
- package/dist/sdk/sessions/registry.d.ts +2 -1
- package/dist/sdk/sessions/registry.js +6 -3
- package/dist/sdk/sessions/runIndex.js +7 -7
- package/dist/sdk/sessions/runStore.d.ts +14 -0
- package/dist/sdk/sessions/runStore.js +38 -1
- package/dist/sdk/sessions/runner.d.ts +40 -2
- package/dist/sdk/sessions/runner.js +163 -15
- package/dist/sdk/sessions/sessions.d.ts +40 -8
- package/dist/sdk/sessions/sessions.js +279 -27
- package/dist/sdk/sessions/sideQuestionServerMethods.d.ts +3 -0
- package/dist/sdk/sessions/sideQuestionServerMethods.js +19 -0
- package/dist/sdk/sessions/sideQuestions.d.ts +66 -0
- package/dist/sdk/sessions/sideQuestions.js +290 -0
- package/dist/sdk/sessions/subagentServerMethods.d.ts +3 -0
- package/dist/sdk/sessions/subagentServerMethods.js +41 -0
- package/dist/sdk/sessions/subagentService.d.ts +22 -2
- package/dist/sdk/sessions/subagentService.js +93 -16
- package/dist/sdk/sessions/subagents.d.ts +9 -1
- package/dist/sdk/sessions/subagents.js +19 -0
- package/dist/sdk/sessions/workSlice.d.ts +103 -0
- package/dist/sdk/sessions/workSlice.js +297 -0
- package/dist/sdk/sessions/workspaceBoundary.d.ts +15 -0
- package/dist/sdk/sessions/workspaceBoundary.js +46 -0
- package/dist/sdk/terminal/browser.d.ts +62 -0
- package/dist/sdk/terminal/browser.js +41 -0
- package/dist/sdk/terminal/browserControl.d.ts +29 -0
- package/dist/sdk/terminal/browserControl.js +187 -0
- package/dist/sdk/terminal/commandHelp.d.ts +17 -0
- package/dist/sdk/terminal/commandHelp.js +20 -0
- package/dist/sdk/terminal/controller.d.ts +15 -1
- package/dist/sdk/terminal/controller.js +67 -8
- package/dist/sdk/terminal/opentui/subagentsWidget.d.ts +28 -0
- package/dist/sdk/terminal/opentui/subagentsWidget.js +52 -0
- package/dist/sdk/terminal/opentui/theme.d.ts +43 -0
- package/dist/sdk/terminal/opentui/theme.js +87 -0
- package/dist/sdk/terminal/piExtension.d.ts +6 -1
- package/dist/sdk/terminal/piExtension.js +169 -84
- package/dist/sdk/terminal/socket.d.ts +6 -3
- package/dist/sdk/terminal/socket.js +40 -9
- package/dist/sdk/terminal/standalone.d.ts +9 -0
- package/dist/sdk/terminal/standalone.js +118 -19
- package/dist/sdk/terminal/subagentMonitor.d.ts +47 -0
- package/dist/sdk/terminal/subagentMonitor.js +152 -0
- package/dist/sdk/terminal/terminals.d.ts +60 -7
- package/dist/sdk/terminal/terminals.js +598 -47
- package/dist/sdk/terminal/trajectory.js +2 -2
- package/dist/sdk/terminal/tui/annotateCommand.d.ts +3 -0
- package/dist/sdk/terminal/tui/annotateCommand.js +22 -0
- package/dist/sdk/terminal/tui/commandPages.d.ts +7 -1
- package/dist/sdk/terminal/tui/commandPages.js +57 -6
- package/dist/sdk/terminal/tui/commands.d.ts +10 -4
- package/dist/sdk/terminal/tui/commands.js +269 -65
- package/dist/sdk/terminal/tui/dialogGeometry.d.ts +2 -2
- package/dist/sdk/terminal/tui/dialogGeometry.js +4 -2
- package/dist/sdk/terminal/tui/dialogs.d.ts +6 -1
- package/dist/sdk/terminal/tui/dialogs.js +9 -2
- package/dist/sdk/terminal/tui/list.d.ts +14 -1
- package/dist/sdk/terminal/tui/list.js +96 -14
- package/dist/sdk/terminal/tui/modelPicker.js +1 -6
- package/dist/sdk/terminal/tui/page.d.ts +3 -0
- package/dist/sdk/terminal/tui/pageOverlay.js +27 -7
- package/dist/sdk/terminal/tui/pages/accountsPage.d.ts +26 -4
- package/dist/sdk/terminal/tui/pages/accountsPage.js +264 -36
- package/dist/sdk/terminal/tui/pages/agentsPage.d.ts +74 -0
- package/dist/sdk/terminal/tui/pages/agentsPage.js +190 -0
- package/dist/sdk/terminal/tui/pages/annotatePage.d.ts +94 -0
- package/dist/sdk/terminal/tui/pages/annotatePage.js +341 -0
- package/dist/sdk/terminal/tui/pages/browserPage.d.ts +87 -0
- package/dist/sdk/terminal/tui/pages/browserPage.js +738 -0
- package/dist/sdk/terminal/tui/pages/doctorPage.d.ts +2 -0
- package/dist/sdk/terminal/tui/pages/doctorPage.js +103 -15
- package/dist/sdk/terminal/tui/pages/notesPage.d.ts +75 -0
- package/dist/sdk/terminal/tui/pages/notesPage.js +201 -0
- package/dist/sdk/terminal/tui/pages/pluginsPage.d.ts +0 -5
- package/dist/sdk/terminal/tui/pages/pluginsPage.js +9 -3
- package/dist/sdk/terminal/tui/pages/settingsPage.d.ts +8 -0
- package/dist/sdk/terminal/tui/pages/settingsPage.js +16 -1
- package/dist/sdk/terminal/tui/pages/subagentsPage.d.ts +24 -0
- package/dist/sdk/terminal/tui/pages/subagentsPage.js +152 -0
- package/dist/sdk/terminal/tui/pages/trajectoryPage.d.ts +12 -5
- package/dist/sdk/terminal/tui/pages/trajectoryPage.js +156 -83
- package/dist/sdk/terminal/tui/pages/usagePage.d.ts +43 -0
- package/dist/sdk/terminal/tui/pages/usagePage.js +370 -0
- package/dist/sdk/terminal/tui/pages/worktreesPage.d.ts +72 -0
- package/dist/sdk/terminal/tui/pages/worktreesPage.js +203 -0
- package/dist/sdk/terminal/tui/piAdapter.d.ts +1 -2
- package/dist/sdk/terminal/tui/piAdapter.js +3 -5
- package/dist/sdk/terminal/tui/planMode.d.ts +1 -1
- package/dist/sdk/terminal/tui/planMode.js +1 -1
- package/dist/sdk/terminal/tui/pluginCommands.d.ts +16 -0
- package/dist/sdk/terminal/tui/pluginCommands.js +31 -0
- package/dist/sdk/terminal/tui/questions.d.ts +2 -0
- package/dist/sdk/terminal/tui/runtime.js +27 -5
- package/dist/sdk/terminal/tui/sessionPicker.d.ts +40 -0
- package/dist/sdk/terminal/tui/sessionPicker.js +141 -0
- package/dist/sdk/terminal/tui/settingsModel.d.ts +2 -0
- package/dist/sdk/terminal/tui/settingsModel.js +32 -2
- package/dist/sdk/terminal/tui/sideQuestion.d.ts +26 -26
- package/dist/sdk/terminal/tui/sideQuestion.js +131 -98
- package/dist/sdk/terminal/tui/ui.d.ts +2 -0
- package/dist/sdk/terminal/tui/ui.js +1 -0
- package/dist/sdk/tools/askUser.js +26 -8
- package/dist/sdk/tools/checklist.js +3 -2
- package/dist/sdk/tools/checkpoint.d.ts +27 -0
- package/dist/sdk/tools/checkpoint.js +154 -0
- package/dist/sdk/tools/getCapabilities.d.ts +31 -0
- package/dist/sdk/tools/getCapabilities.js +34 -0
- package/dist/sdk/tools/harnessTools.d.ts +2 -0
- package/dist/sdk/tools/harnessTools.js +1 -1
- package/dist/sdk/tools/spawnSubagent.js +14 -4
- package/dist/sdk/usage/analytics.d.ts +20 -0
- package/dist/sdk/usage/analytics.js +151 -0
- package/dist/sdk/usage/ledger.d.ts +38 -0
- package/dist/sdk/usage/ledger.js +142 -0
- package/dist/sdk/usage/limits/adapters.d.ts +11 -0
- package/dist/sdk/usage/limits/adapters.js +349 -0
- package/dist/sdk/usage/limits/capture.d.ts +8 -0
- package/dist/sdk/usage/limits/capture.js +47 -0
- package/dist/sdk/usage/limits/http.d.ts +12 -0
- package/dist/sdk/usage/limits/http.js +51 -0
- package/dist/sdk/usage/limits/normalize.d.ts +15 -0
- package/dist/sdk/usage/limits/normalize.js +211 -0
- package/dist/sdk/usage/limits/service.d.ts +30 -0
- package/dist/sdk/usage/limits/service.js +176 -0
- package/dist/sdk/usage/limits/types.d.ts +65 -0
- package/dist/sdk/usage/limits/types.js +1 -0
- package/dist/sdk/usage/serverMethods.d.ts +3 -0
- package/dist/sdk/usage/serverMethods.js +22 -0
- package/dist/sdk/usage/service.d.ts +32 -0
- package/dist/sdk/usage/service.js +66 -0
- package/dist/sdk/usage/settings.d.ts +7 -0
- package/dist/sdk/usage/settings.js +28 -0
- package/dist/sdk/usage/types.d.ts +60 -0
- package/dist/sdk/usage/types.js +4 -0
- package/dist/sdk/web/part.d.ts +10 -0
- package/dist/sdk/web/part.js +6 -0
- package/dist/sdk/web/serverMethods.d.ts +3 -0
- package/dist/sdk/web/serverMethods.js +7 -0
- package/dist/sdk/wiki/serverMethods.d.ts +3 -0
- package/dist/sdk/wiki/serverMethods.js +26 -0
- package/dist/sdk/worktrees/cli.d.ts +11 -0
- package/dist/sdk/worktrees/cli.js +146 -0
- package/dist/sdk/worktrees/copy.d.ts +9 -0
- package/dist/sdk/worktrees/copy.js +111 -0
- package/dist/sdk/worktrees/git.d.ts +16 -0
- package/dist/sdk/worktrees/git.js +81 -0
- package/dist/sdk/worktrees/serverMethods.d.ts +3 -0
- package/dist/sdk/worktrees/serverMethods.js +30 -0
- package/dist/sdk/worktrees/service.d.ts +73 -0
- package/dist/sdk/worktrees/service.js +483 -0
- package/dist/sdk/worktrees/setup.d.ts +23 -0
- package/dist/sdk/worktrees/setup.js +65 -0
- package/dist/sdk/worktrees/types.d.ts +91 -0
- package/dist/sdk/worktrees/types.js +1 -0
- package/dist/sdk/world/cli.d.ts +2 -2
- package/dist/sdk/world/cli.js +6 -6
- package/dist/sdk/world/world.d.ts +3 -1
- package/dist/sdk/world/world.js +8 -9
- package/dist/terminal-opentui.js +16456 -5966
- package/dist/terminal-pi.js +1579 -573
- package/docs/README.md +22 -2
- package/docs/architecture/00-overview.md +28 -16
- package/docs/architecture/02-sessions-and-runs.md +184 -25
- package/docs/architecture/03-variants.md +10 -2
- package/docs/architecture/04-prompt.md +65 -7
- package/docs/architecture/06-plugins-and-capabilities.md +57 -4
- package/docs/architecture/07-tools-and-gate.md +112 -17
- package/docs/architecture/08-memory-and-history.md +4 -2
- package/docs/architecture/09-accounts-and-connectors.md +39 -1
- package/docs/architecture/10-server-protocol.md +168 -4
- package/docs/architecture/11-terminal.md +251 -8
- package/docs/architecture/12-storage.md +45 -3
- package/docs/architecture/13-world-tools.md +49 -6
- package/docs/architecture/14-surfaces-and-parity.md +136 -0
- package/docs/architecture/README.md +17 -4
- package/docs/architecture/proposals/PROP-0006-run-checklist.md +4 -2
- package/docs/architecture/proposals/PROP-0013-resource-browser.md +58 -0
- package/docs/architecture/proposals/PROP-0014-fullscreen-browser-tabs.md +58 -0
- package/docs/architecture/proposals/PROP-0015-one-capability-surface.md +88 -0
- package/docs/architecture/proposals/PROP-0016-managed-worktrees.md +156 -0
- package/docs/architecture/proposals/PROP-0017-page-annotations.md +131 -0
- package/docs/architecture/proposals/PROP-0018-annotation-queue-and-app-targets.md +179 -0
- package/docs/architecture/proposals/PROP-0019-contextual-side-questions.md +122 -0
- package/docs/architecture/proposals/PROP-0020-builtin-feature-plugins.md +105 -0
- package/docs/architecture/proposals/PROP-0021-command-namespaces-and-duplicates.md +99 -0
- package/docs/architecture/proposals/PROP-0022-plan-only-questions.md +102 -0
- package/docs/architecture/proposals/PROP-0023-xagent-cli-name.md +61 -0
- package/docs/architecture/proposals/PROP-0024-question-sketch-previews.md +130 -0
- package/docs/architecture/proposals/PROP-0025-contextual-question-wireframes.md +49 -0
- package/docs/architecture/proposals/PROP-0026-connected-sketch-display.md +94 -0
- package/docs/architecture/proposals/PROP-0027-xingular-agent-product-identity.md +60 -0
- package/docs/architecture/proposals/PROP-0028-normalize-question-wireframes.md +55 -0
- package/docs/architecture/proposals/PROP-0029-agent-profiles.md +124 -0
- package/docs/architecture/proposals/PROP-0030-subagent-title.md +86 -0
- package/docs/architecture/proposals/PROP-0031-plugin-command-owner-namespaces.md +54 -0
- package/docs/architecture/proposals/PROP-0032-planning-quality.md +196 -0
- package/docs/architecture/proposals/PROP-0033-compaction-plan-checkpoints.md +75 -0
- package/docs/architecture/proposals/PROP-0034-conversation-fast-mode.md +120 -0
- package/docs/architecture/proposals/PROP-0035-retain-subagent-status.md +47 -0
- package/docs/architecture/proposals/PROP-0036-first-class-harness-commands.md +59 -0
- package/docs/architecture/proposals/PROP-0037-workspace-write-boundary.md +63 -0
- package/docs/architecture/proposals/PROP-0038-annotate-open-shadow-roots.md +73 -0
- package/docs/architecture/proposals/PROP-0039-workspace-boundary-hardening.md +139 -0
- package/docs/architecture/proposals/PROP-0040-one-launch-path.md +87 -0
- package/docs/architecture/proposals/PROP-0041-bounded-work-slices.md +247 -0
- package/docs/architecture/proposals/PROP-0042-usage-and-provider-limits.md +127 -0
- package/docs/architecture/proposals/PROP-0043-read-only-plan-bash.md +74 -0
- package/docs/architecture/proposals/README.md +39 -0
- package/docs/decisions/ADR-0001-owned-terminal.md +1 -1
- package/docs/decisions/ADR-0009-xharness-command.md +6 -5
- package/docs/decisions/ADR-0014-public-release-baseline.md +3 -2
- package/docs/decisions/ADR-0015-resource-browser.md +28 -0
- package/docs/decisions/ADR-0016-fullscreen-browser-tabs.md +31 -0
- package/docs/decisions/ADR-0017-one-capability-surface.md +34 -0
- package/docs/decisions/ADR-0018-builtin-feature-plugins.md +35 -0
- package/docs/decisions/ADR-0019-managed-git-worktrees.md +31 -0
- package/docs/decisions/ADR-0020-page-annotations.md +37 -0
- package/docs/decisions/ADR-0021-required-command-namespaces.md +40 -0
- package/docs/decisions/ADR-0022-plan-only-question-tools.md +34 -0
- package/docs/decisions/ADR-0023-contextual-side-question-runs.md +35 -0
- package/docs/decisions/ADR-0024-xagent-command.md +40 -0
- package/docs/decisions/ADR-0025-question-choice-sketches.md +49 -0
- package/docs/decisions/ADR-0026-contextual-question-wireframes.md +58 -0
- package/docs/decisions/ADR-0027-connected-sketch-display.md +60 -0
- package/docs/decisions/ADR-0028-xingular-agent-product-identity.md +56 -0
- package/docs/decisions/ADR-0029-normalized-question-wireframe-borders.md +33 -0
- package/docs/decisions/ADR-0030-agent-profiles.md +43 -0
- package/docs/decisions/ADR-0031-plugin-command-owner-namespaces.md +37 -0
- package/docs/decisions/ADR-0032-compaction-run-checkpoints.md +33 -0
- package/docs/decisions/ADR-0033-plan-mode-research-delegation.md +47 -0
- package/docs/decisions/ADR-0034-first-class-harness-terminal-commands.md +25 -0
- package/docs/decisions/ADR-0035-one-launch-path.md +40 -0
- package/docs/decisions/ADR-0036-workspace-write-operation-boundary.md +54 -0
- package/docs/decisions/ADR-0037-usage-ledger-and-provider-limits.md +44 -0
- package/docs/decisions/ADR-0038-plan-bash-os-read-only.md +29 -0
- package/docs/doctor.md +10 -4
- package/docs/experiments/EXP-0003-performance-audit/data/session-runtime-replication.json +420 -0
- package/docs/experiments/EXP-0003-performance-audit/data/session-runtime.json +420 -0
- package/docs/experiments/EXP-0003-performance-audit/data/terminal-compact.json +376 -0
- package/docs/experiments/EXP-0003-performance-audit/data/terminal-history.json +422 -0
- package/docs/experiments/EXP-0003-performance-audit/data/terminal-question.json +95 -0
- package/docs/experiments/EXP-0003-performance-audit/data/terminal-wide.json +1036 -0
- package/docs/experiments/EXP-0003-performance-audit/plan.md +109 -0
- package/docs/experiments/EXP-0003-performance-audit/results.md +151 -0
- package/docs/features/README.md +26 -0
- package/docs/features/interfaces/README.md +1 -1
- package/docs/future-work.md +48 -0
- package/docs/handoff-2026-10-25-app-parity-and-solo-tabs.md +202 -0
- package/docs/parity.md +134 -0
- package/docs/releases/1.0.0.md +2 -2
- package/docs/releases/1.1.1.md +28 -0
- package/docs/releases/1.2.0.md +49 -0
- package/docs/releases/4.0.0.md +47 -0
- package/docs/releases/README.md +37 -27
- package/docs/study/00-index.md +8 -0
- package/docs/study/STUDY-0003-long-horizon-runs.md +210 -0
- package/docs/study/autonomous-engineering-sources.md +277 -0
- package/docs/study/autonomy-sources.md +147 -0
- package/docs/study/proactive-autonomy.md +408 -0
- package/docs/study/tui-resource-browser.md +78 -0
- package/docs/terminal-tui.md +386 -113
- package/package.json +6 -5
package/dist/sdk/index.js
CHANGED
|
@@ -20,9 +20,14 @@ export { fileSecretStore, memorySecretStore, secretKey } from "./accounts/secret
|
|
|
20
20
|
export { dispatch as harnessCall } from "./tools/dispatch.js";
|
|
21
21
|
export { compile, render, SECTION_ORDER, CONTEXT_MESSAGE_TYPE, CONTEXT_SNAPSHOT_KEY } from "./prompt/compile.js";
|
|
22
22
|
export { runEventSchema, runRecordSchema, isActiveStatus } from "./sessions/contracts.js";
|
|
23
|
+
export { CORE_COMMANDS, coreCommand } from "./commands/registry.js";
|
|
24
|
+
export { STANDARD_CONNECTIONS } from "./prompt/standard.js";
|
|
25
|
+
export { SideQuestions, SIDE_QUESTION_INSTRUCTION, buildSideQuestionText } from "./sessions/sideQuestions.js";
|
|
23
26
|
export { describeTool, HARNESS_TOOLS, DEFAULT_TOOL_NAMES, WIKI_WRITE } from "./tools/definitions.js";
|
|
24
27
|
export { SPAWN_SUBAGENT, SUBAGENT_RELATION } from "./tools/spawnSubagent.js";
|
|
25
28
|
export { CHECKLIST_WRITE, checklistOf } from "./tools/checklist.js";
|
|
29
|
+
export { BUILTIN_PROFILES } from "./agents/builtin.js";
|
|
30
|
+
export { PROFILE_COLORS, createProfile, listProfiles, parseProfile, profileDirs, removeProfile, resolveProfile } from "./agents/profiles.js";
|
|
26
31
|
export { continuationOf } from "./sessions/continuation.js";
|
|
27
32
|
export { webTools, WEB_PLUGIN, WEB_SEARCH_KEY } from "./web/tools.js";
|
|
28
33
|
export { safeRequest } from "./web/safeRequest.js";
|
|
@@ -39,10 +44,15 @@ export { attach as attachPlugin, inventoryFor as pluginInventory, list as listPl
|
|
|
39
44
|
export { HARNESS_PLUGINS } from "./plugins/builtin.js";
|
|
40
45
|
export { FIRST_PARTY_PLUGINS } from "./plugins/firstParty.js";
|
|
41
46
|
export { CONTRIBUTION_KINDS, PLUGIN_SOURCES } from "./plugins/types.js";
|
|
47
|
+
export { describePlugin, surfaceBadge } from "./plugins/surfaces.js";
|
|
42
48
|
export { methods } from "./server/methods.js";
|
|
43
49
|
export { remoteDirectory, remotePolicy, remoteSecrets, remoteTools } from "./server/remote.js";
|
|
44
50
|
export { PROTOCOL_VERSION, RpcPeer, stdioTransport } from "./server/rpc.js";
|
|
45
51
|
export { attach, serve } from "./server/serve.js";
|
|
46
52
|
export { DEFAULT_SUBAGENT_DEPTH, MAX_SUBAGENT_DEPTH } from "./sessions/subagents.js";
|
|
47
53
|
export { Subagents } from "./sessions/subagentService.js";
|
|
54
|
+
export { Worktrees } from "./worktrees/service.js";
|
|
48
55
|
export { WAIT_SUBAGENTS } from "./sessions/subagents.js";
|
|
56
|
+
export * as pageNotes from "./annotations/store.js";
|
|
57
|
+
export { PAGE_SCRIPT } from "./annotations/pageScript.js";
|
|
58
|
+
export { NoteDeliveries } from "./annotations/delivery.js";
|
|
@@ -449,11 +449,12 @@ export class Connections {
|
|
|
449
449
|
async launch(connection) {
|
|
450
450
|
if (connection.kind === 'remote') {
|
|
451
451
|
const headers = {};
|
|
452
|
-
|
|
453
|
-
const
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
452
|
+
if (connection.auth === 'headers')
|
|
453
|
+
for (const key of connection.headerKeys) {
|
|
454
|
+
const value = await this.secret(connection.id, headerItem(key));
|
|
455
|
+
if (value !== null)
|
|
456
|
+
headers[key] = value;
|
|
457
|
+
}
|
|
457
458
|
return { id: connection.id, name: connection.name, transport: 'http', url: connection.url ?? '', headers, auth: connection.auth, scopes: connection.oauthScopes };
|
|
458
459
|
}
|
|
459
460
|
let command = findBinary(connection.command) ?? (isAbsolute(connection.command) ? connection.command : null);
|
|
@@ -573,7 +574,13 @@ export class Connections {
|
|
|
573
574
|
throw scopeMigrationError();
|
|
574
575
|
}
|
|
575
576
|
connection.envKeys = [...(existing?.envKeys ?? [])];
|
|
576
|
-
connection.
|
|
577
|
+
const keepHeaders = remote && connection.auth === 'headers' && existing?.kind === 'remote'
|
|
578
|
+
&& existing.url === connection.url && existing.auth === 'headers';
|
|
579
|
+
connection.headerKeys = keepHeaders ? [...existing.headerKeys] : [];
|
|
580
|
+
if (!keepHeaders) {
|
|
581
|
+
for (const key of existing?.headerKeys ?? [])
|
|
582
|
+
await this.deleteSecret(connection.id, headerItem(key));
|
|
583
|
+
}
|
|
577
584
|
// A sign-in belongs to one server and one client; never carry it to another.
|
|
578
585
|
const sameServer = (existing?.url ?? null) === connection.url && (existing?.auth ?? '') === connection.auth && existing?.oauthClient === connection.oauthClient && existing?.catalogId === connection.catalogId && !oauthCredentials;
|
|
579
586
|
if (!sameServer || connection.auth !== 'oauth')
|
|
@@ -588,7 +595,7 @@ export class Connections {
|
|
|
588
595
|
else
|
|
589
596
|
await this.deleteSecret(connection.id, OAUTH_CLIENT_SECRET);
|
|
590
597
|
}
|
|
591
|
-
for (const [key, value] of Object.entries(headers ?? {})) {
|
|
598
|
+
for (const [key, value] of Object.entries(remote && connection.auth === 'headers' ? headers ?? {} : {})) {
|
|
592
599
|
if (!/^[A-Za-z0-9_-]+$/.test(key) || /[\r\n\0]/.test(value))
|
|
593
600
|
throw invalid('Invalid header name or value.');
|
|
594
601
|
await this.setSecret(connection.id, headerItem(key), value);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { validateScopeIds } from "./connections.js";
|
|
2
|
+
import { optional, text } from "../server/params.js";
|
|
3
|
+
export function connectedAppServerMethods(harness) {
|
|
4
|
+
const apps = harness.apps;
|
|
5
|
+
return {
|
|
6
|
+
'connections.list': () => apps.connections.list(),
|
|
7
|
+
'connections.forScope': (params) => apps.connections.forScope({ agentId: optional(params, 'agentId'), projectId: optional(params, 'projectId') }),
|
|
8
|
+
'connections.save': (params) => apps.save(params.input),
|
|
9
|
+
'connections.allowTool': (params) => apps.connections.allowTool(text(params, 'connectionId'), text(params, 'tool')),
|
|
10
|
+
'connections.remove': (params) => apps.remove(text(params, 'connectionId')),
|
|
11
|
+
'connections.test': (params) => apps.test(text(params, 'connectionId')),
|
|
12
|
+
'connections.signIn': (params) => apps.signIn(text(params, 'connectionId')),
|
|
13
|
+
'connections.signOut': (params) => apps.signOut(text(params, 'connectionId')),
|
|
14
|
+
'connections.runContext': (params) => apps.runContext(text(params, 'runId')),
|
|
15
|
+
'connections.refreshSource': (params) => apps.refreshSource(text(params, 'runId'), text(params, 'traceId'), text(params, 'sourceUri')),
|
|
16
|
+
'connections.setAgentScope': (params) => apps.setAgentScope(params.creator ?? {}, text(params, 'agentId'), Array.isArray(params.ids) ? params.ids : []),
|
|
17
|
+
'connections.removeAgentScope': (params) => apps.removeAgentScope(text(params, 'agentId')),
|
|
18
|
+
'connections.revision': () => apps.connections.revision(),
|
|
19
|
+
'connections.appClients': () => apps.appClients(),
|
|
20
|
+
'connections.validateScope': (params) => validateScopeIds(apps.connections.list(), { agentId: optional(params, 'agentId'), projectId: optional(params, 'projectId') }, Array.isArray(params.ids) ? params.ids : [])
|
|
21
|
+
};
|
|
22
|
+
}
|
package/dist/sdk/pi/runtime.d.ts
CHANGED
package/dist/sdk/pi/runtime.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { join } from 'node:path';
|
|
2
2
|
import { pathToFileURL } from 'node:url';
|
|
3
|
-
export const PINNED_PI_VERSION = '1.
|
|
4
|
-
const HTTP_DISPATCHER_CHUNK = 'dist/bundle/chunks/chunk-
|
|
3
|
+
export const PINNED_PI_VERSION = '1.4.0';
|
|
4
|
+
export const HTTP_DISPATCHER_CHUNK = 'dist/bundle/chunks/chunk-MM3LKT73.js';
|
|
5
5
|
export function assertPiRuntimeVersion(version) {
|
|
6
6
|
if (version !== PINNED_PI_VERSION)
|
|
7
7
|
throw new Error(`The Harness Pi runtime requires Pi ${PINNED_PI_VERSION}; found ${version}. Install the Harness package's pinned dependencies.`);
|
|
@@ -3,4 +3,5 @@ import type { PluginDescriptor } from "./types.js";
|
|
|
3
3
|
export declare const PI_PLUGIN: PluginDescriptor;
|
|
4
4
|
/** The variant: the eight components that shape what an agent is told and can do. */
|
|
5
5
|
export declare const VARIANT_PLUGIN: PluginDescriptor;
|
|
6
|
+
export declare const BUILTIN_PLUGIN_REGISTRY: import("./builtinRegistry.js").BuiltinPluginRegistry;
|
|
6
7
|
export declare const HARNESS_PLUGINS: readonly PluginDescriptor[];
|
|
@@ -1,21 +1,50 @@
|
|
|
1
|
-
//
|
|
2
|
-
// exists; none of it is loaded through Pi's extension system.
|
|
1
|
+
// Built-in feature modules register their contributions here; this registry never loads Pi code.
|
|
3
2
|
import { CONNECTION_TOOLS, NATIVE_GROUP } from "../prompt/compile.js";
|
|
4
|
-
import { ASK_USER } from "../tools/askUser.js";
|
|
5
|
-
import { CHECKLIST_WRITE } from "../tools/checklist.js";
|
|
3
|
+
import { ASK_USER, askUserTool } from "../tools/askUser.js";
|
|
4
|
+
import { CHECKLIST_WRITE, checklistTool } from "../tools/checklist.js";
|
|
5
|
+
import { CHECKPOINT_WRITE, checkpointTool } from "../tools/checkpoint.js";
|
|
6
|
+
import { sliceOf } from "../sessions/workSlice.js";
|
|
6
7
|
import { SPAWN_SUBAGENT, WAIT_SUBAGENTS } from "../sessions/subagents.js";
|
|
8
|
+
import { subagentTools } from "../tools/spawnSubagent.js";
|
|
9
|
+
import { SESSION_NAME } from "../tools/sessionName.js";
|
|
7
10
|
import { RECALL_TOOLS, SKILL_TOOLS, TRAJECTORY_TOOLS, WIKI_READ_TOOLS, WIKI_WRITE_TOOLS } from "../tools/definitions.js";
|
|
8
11
|
import { FIRST_PARTY_PLUGINS } from "./firstParty.js";
|
|
9
12
|
import { WEB_PLUGIN } from "../web/tools.js";
|
|
10
|
-
import {
|
|
13
|
+
import { KEYLESS_SEARCH, webPart } from "../web/part.js";
|
|
14
|
+
import { BROWSER_PLUGIN, browserPluginPart } from "../browser/index.js";
|
|
15
|
+
import { ANNOTATIONS_PLUGIN } from "../annotations/part.js";
|
|
16
|
+
import { annotationsPart } from "../annotations/part.js";
|
|
17
|
+
import { webServerMethods } from "../web/serverMethods.js";
|
|
18
|
+
import { browserServerMethods } from "../browser/serverMethods.js";
|
|
19
|
+
import { annotationServerMethods } from "../annotations/serverMethods.js";
|
|
20
|
+
import { doctorServerMethods } from "../doctor/serverMethods.js";
|
|
21
|
+
import { worktreeServerMethods } from "../worktrees/serverMethods.js";
|
|
22
|
+
import { hubServerMethods } from "../hub/serverMethods.js";
|
|
23
|
+
import { refinementServerMethods } from "../refine/serverMethods.js";
|
|
24
|
+
import { wikiServerMethods } from "../wiki/serverMethods.js";
|
|
25
|
+
import { historyServerMethods } from "../history/serverMethods.js";
|
|
26
|
+
import { subagentServerMethods } from "../sessions/subagentServerMethods.js";
|
|
27
|
+
import { sideQuestionServerMethods } from "../sessions/sideQuestionServerMethods.js";
|
|
28
|
+
import { connectedAppServerMethods } from "../mcp/serverMethods.js";
|
|
29
|
+
import { harnessTools } from "../tools/harnessTools.js";
|
|
30
|
+
import { GET_CAPABILITIES } from "../tools/getCapabilities.js";
|
|
31
|
+
import { USAGE_SETTINGS } from "../usage/settings.js";
|
|
32
|
+
import { usageServerMethods } from "../usage/serverMethods.js";
|
|
33
|
+
import { createBuiltinPluginRegistry } from "./builtinRegistry.js";
|
|
11
34
|
const tools = (definitions) => definitions.map((tool) => ({ name: tool.name, description: tool.label }));
|
|
35
|
+
const toolContribution = (definitions, toolOrder) => ({
|
|
36
|
+
toolOrder,
|
|
37
|
+
tools: (context) => context.harnessTools
|
|
38
|
+
? harnessTools(context.env, context.caller, { variantDir: context.variantDir, definitions })
|
|
39
|
+
: []
|
|
40
|
+
});
|
|
12
41
|
/** Pi itself. Its command's built-in extensions are added to it as they are found. */
|
|
13
42
|
export const PI_PLUGIN = {
|
|
14
43
|
id: 'pi',
|
|
15
44
|
title: 'Pi',
|
|
16
45
|
description: 'The engine every session runs on: its base prompt, its file and shell tools, and the extensions built into its command.',
|
|
17
46
|
required: 'Pi runs every session.',
|
|
18
|
-
tools: NATIVE_GROUP.map((name) => ({ name })),
|
|
47
|
+
tools: [...NATIVE_GROUP.map((name) => ({ name })), { name: SESSION_NAME }],
|
|
19
48
|
toolGroups: ['Native']
|
|
20
49
|
};
|
|
21
50
|
/** The variant: the eight components that shape what an agent is told and can do. */
|
|
@@ -25,6 +54,7 @@ export const VARIANT_PLUGIN = {
|
|
|
25
54
|
description: 'The agent\'s own variant: system prompt, guardrails, memory and tool guidance in every prompt; skills, scripts and subagents on demand; plugins in the tool loop. Versioned, and refined from evidence.',
|
|
26
55
|
required: 'Every agent runs on a variant.',
|
|
27
56
|
sections: [
|
|
57
|
+
{ id: 'harness-identity', name: 'Harness identity', description: 'Fixed foundation identity; not part of the variant.' },
|
|
28
58
|
{ id: 'system', name: 'System prompt', description: 'c1: role and procedure.' },
|
|
29
59
|
{ id: 'guardrails', name: 'Guardrails', description: 'c2: standing rules.' },
|
|
30
60
|
{ id: 'memory', name: 'Memory', description: 'c3: durable facts about this kind of work.' },
|
|
@@ -34,35 +64,117 @@ export const VARIANT_PLUGIN = {
|
|
|
34
64
|
],
|
|
35
65
|
tools: tools(SKILL_TOOLS)
|
|
36
66
|
};
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
67
|
+
const SUBAGENTS_PLUGIN = { id: 'subagents', title: 'Subagents', description: 'Isolated child runs of the same caller, bounded by parent capabilities and nesting depth.', required: 'Availability is selected by the session host; child runs retain the parent permission boundary.', tools: [{ name: SPAWN_SUBAGENT, description: 'Start a subagent' }, { name: WAIT_SUBAGENTS, description: 'Wait for subagents' }] };
|
|
68
|
+
const WIKI_PLUGIN = {
|
|
69
|
+
id: 'wiki',
|
|
70
|
+
title: 'Wiki',
|
|
71
|
+
description: 'Notes about projects, linked to each other, that agents search and read.',
|
|
72
|
+
required: 'Project notes are reached through it.',
|
|
73
|
+
tools: tools([...WIKI_READ_TOOLS, ...WIKI_WRITE_TOOLS]),
|
|
74
|
+
sections: [
|
|
75
|
+
{ id: 'wiki', name: 'Wiki', description: 'The current project\'s notes.' },
|
|
76
|
+
{ id: 'references', name: 'Selected references', description: 'Notes pinned to one request.' }
|
|
77
|
+
],
|
|
78
|
+
toolGroups: ['Wiki']
|
|
79
|
+
};
|
|
80
|
+
const HISTORY_PLUGIN = { id: 'history', title: 'History', description: 'Search earlier conversations and inspect recorded run trajectories.', required: 'Earlier runs are how an agent picks up where work stopped.', tools: tools([...RECALL_TOOLS, ...TRAJECTORY_TOOLS]), toolGroups: ['History'] };
|
|
81
|
+
const ASK_USER_PLUGIN = { id: 'ask-user', title: 'Ask the user', description: 'Lets the agent stop and ask a question with choices.', required: 'An agent must be able to stop and ask you.', tools: [{ name: ASK_USER }] };
|
|
82
|
+
const CHECKLIST_PLUGIN = { id: 'checklist', title: 'Checklist', description: 'Lets the agent keep a checklist of the steps of its work, recorded with the run so progress can be shown and picked up again.', required: 'Progress of longer work is kept through it.', tools: [{ name: CHECKLIST_WRITE, description: 'Write the checklist' }] };
|
|
83
|
+
const CHECKPOINT_PLUGIN = { id: 'checkpoint', title: 'Checkpoint', description: 'Lets a bounded reply record a handoff at a work-slice boundary so the next slice starts from it.', required: 'A reply that stops at its budget leaves the state the next one resumes from.', tools: [{ name: CHECKPOINT_WRITE, description: 'Write the handoff checkpoint' }] };
|
|
84
|
+
const CONNECTED_APPS_PLUGIN = {
|
|
85
|
+
id: 'connected-apps',
|
|
86
|
+
title: 'Connected apps',
|
|
87
|
+
description: 'Outside services reached over MCP, behind two tools that list and call what is connected.',
|
|
88
|
+
required: 'Connected apps are reached only through it. Each app is switched on its own.',
|
|
89
|
+
manage: 'connections',
|
|
90
|
+
tools: CONNECTION_TOOLS.map((name) => ({ name })),
|
|
91
|
+
toolGroups: ['Connections']
|
|
92
|
+
};
|
|
93
|
+
const DOCTOR_PLUGIN = { id: 'doctor', title: 'Doctor', description: 'Local readiness checks and explicitly confirmed live probes for accounts, models and tools.', required: 'Every local terminal has readiness diagnostics.' };
|
|
94
|
+
const WORKTREES_PLUGIN = { id: 'worktrees', title: 'Worktrees', description: 'Create and manage isolated git worktrees, move changes between them, and restore removed worktrees.', required: 'Managed worktrees are available to every local terminal.' };
|
|
95
|
+
const HUB_PLUGIN = { id: 'hub', title: 'Hub', description: 'Browse and install reviewed skills, plugins and documents from configured registries.', required: 'Reviewed Harness resources are available to every host.' };
|
|
96
|
+
const REFINEMENT_PLUGIN = { id: 'refinement', title: 'Refinement', description: 'Improve variants from recorded evidence through isolated refinement runs and reviewed candidates.', required: 'Variant refinement is available to every host.' };
|
|
97
|
+
const CAPABILITIES_PLUGIN = { id: 'capabilities', title: 'Capability discovery', description: 'Inspect the callable tools of the current run, including their input schemas. Discovery never grants access.', required: 'Every interactive session can inspect its own registered capabilities.', tools: [{ name: GET_CAPABILITIES, description: 'Inspect current capabilities' }] };
|
|
98
|
+
const USAGE_PLUGIN = {
|
|
99
|
+
id: 'usage',
|
|
100
|
+
title: 'Usage',
|
|
101
|
+
description: 'Token, cost and latency totals from recorded runs, and the plan windows, balances or rate limits each provider reports.',
|
|
102
|
+
settings: [...USAGE_SETTINGS]
|
|
103
|
+
};
|
|
104
|
+
const SIDE_QUESTIONS_PLUGIN = {
|
|
105
|
+
id: 'side-questions',
|
|
106
|
+
title: 'Side questions',
|
|
107
|
+
description: 'Separate, tool-free answers that use a redacted projection of the main conversation.',
|
|
108
|
+
required: 'Every host can ask a side question without steering its main run.',
|
|
109
|
+
sections: [{ id: 'side-question', name: 'Side-question role', description: 'Fixed instructions for an independent, tool-free side run.' }]
|
|
110
|
+
};
|
|
111
|
+
export const BUILTIN_PLUGIN_REGISTRY = createBuiltinPluginRegistry([
|
|
112
|
+
{
|
|
113
|
+
descriptor: PI_PLUGIN,
|
|
114
|
+
toolOrder: 60,
|
|
115
|
+
tools: context => context.harnessTools ? [context.sessionName] : []
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
descriptor: SUBAGENTS_PLUGIN,
|
|
119
|
+
toolOrder: 70,
|
|
120
|
+
tools: context => context.allowedTools.includes(SPAWN_SUBAGENT)
|
|
121
|
+
? subagentTools(context.subagents, context.runId).filter(tool => context.allowedTools.includes(tool.name))
|
|
122
|
+
: [],
|
|
123
|
+
serverMethods: subagentServerMethods
|
|
124
|
+
},
|
|
125
|
+
{ descriptor: VARIANT_PLUGIN, ...toolContribution(SKILL_TOOLS, 30) },
|
|
126
|
+
{ descriptor: WIKI_PLUGIN, ...toolContribution([...WIKI_READ_TOOLS, ...WIKI_WRITE_TOOLS], 20), serverMethods: wikiServerMethods },
|
|
41
127
|
{
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
128
|
+
descriptor: HISTORY_PLUGIN,
|
|
129
|
+
...toolContribution([...RECALL_TOOLS, ...TRAJECTORY_TOOLS], 10),
|
|
130
|
+
serverMethods: historyServerMethods
|
|
131
|
+
},
|
|
132
|
+
{ descriptor: ASK_USER_PLUGIN, toolOrder: 40, tools: context => context.harnessTools && context.allowedTools.includes(ASK_USER) ? [askUserTool(context.run)] : [] },
|
|
133
|
+
{ descriptor: CHECKLIST_PLUGIN, toolOrder: 50, tools: context => context.harnessTools ? [checklistTool(context.run)] : [] },
|
|
134
|
+
{ descriptor: CHECKPOINT_PLUGIN, toolOrder: 51, tools: context => context.harnessTools && context.allowedTools.includes(CHECKPOINT_WRITE) ? [checkpointTool(context.run, () => sliceOf(context.env.root, context.runId))] : [] },
|
|
135
|
+
{
|
|
136
|
+
descriptor: CONNECTED_APPS_PLUGIN,
|
|
137
|
+
toolOrder: 0,
|
|
138
|
+
tools: context => context.connectionTools?.() ?? [],
|
|
139
|
+
serverMethods: connectedAppServerMethods
|
|
140
|
+
},
|
|
141
|
+
{ descriptor: HUB_PLUGIN, serverMethods: hubServerMethods },
|
|
142
|
+
{ descriptor: REFINEMENT_PLUGIN, serverMethods: refinementServerMethods },
|
|
143
|
+
{ descriptor: SIDE_QUESTIONS_PLUGIN, serverMethods: sideQuestionServerMethods },
|
|
144
|
+
{
|
|
145
|
+
descriptor: WEB_PLUGIN,
|
|
146
|
+
createWorldPart: ({ options, setting }) => webPart({ secrets: options.secrets, request: options.request, keyless: () => setting(WEB_PLUGIN.id, KEYLESS_SEARCH) === 1 }),
|
|
147
|
+
serverMethods: webServerMethods
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
descriptor: BROWSER_PLUGIN,
|
|
151
|
+
createWorldPart: ({ browserEngine }) => browserEngine ? browserPluginPart(browserEngine) : null,
|
|
152
|
+
serverMethods: browserServerMethods
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
descriptor: ANNOTATIONS_PLUGIN,
|
|
156
|
+
commandPrefix: 'annotate',
|
|
157
|
+
defaultCommand: 'annotate',
|
|
158
|
+
commands: [
|
|
159
|
+
{ name: 'notes', description: 'Review web annotations saved from pages and apps' },
|
|
160
|
+
{ name: 'annotate', description: 'Inspect a page or app, comment on components, and send fixes: /annotate:annotate [url | --app <devtools address> | --bridge]' }
|
|
50
161
|
],
|
|
51
|
-
|
|
162
|
+
createWorldPart: ({ options }) => annotationsPart({ root: options.root, changed: options.notesChanged }),
|
|
163
|
+
serverMethods: annotationServerMethods
|
|
52
164
|
},
|
|
53
|
-
{
|
|
54
|
-
{ id: 'ask-user', title: 'Ask the user', description: 'Lets the agent stop and ask a question with choices.', required: 'An agent must be able to stop and ask you.', tools: [{ name: ASK_USER }] },
|
|
55
|
-
{ id: 'checklist', title: 'Checklist', description: 'Lets the agent keep a checklist of the steps of its work, recorded with the run so progress can be shown and picked up again.', required: 'Progress of longer work is kept through it.', tools: [{ name: CHECKLIST_WRITE, description: 'Write the checklist' }] },
|
|
165
|
+
{ descriptor: CAPABILITIES_PLUGIN },
|
|
56
166
|
{
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
167
|
+
descriptor: USAGE_PLUGIN,
|
|
168
|
+
commandPrefix: 'usage',
|
|
169
|
+
defaultCommand: 'analysis',
|
|
170
|
+
commands: [
|
|
171
|
+
{ name: 'analysis', description: 'Token, cost and latency totals: /usage:analysis [today | 7d | 30d | all]' },
|
|
172
|
+
{ name: 'limit', description: 'Provider plan windows, balances and rate limits: /usage:limit' }
|
|
173
|
+
],
|
|
174
|
+
serverMethods: usageServerMethods
|
|
64
175
|
},
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
...FIRST_PARTY_PLUGINS
|
|
68
|
-
];
|
|
176
|
+
{ descriptor: DOCTOR_PLUGIN, serverMethods: doctorServerMethods },
|
|
177
|
+
{ descriptor: WORKTREES_PLUGIN, serverMethods: worktreeServerMethods },
|
|
178
|
+
...FIRST_PARTY_PLUGINS.map(descriptor => ({ descriptor }))
|
|
179
|
+
]);
|
|
180
|
+
export const HARNESS_PLUGINS = BUILTIN_PLUGIN_REGISTRY.descriptors();
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { Harness } from "../harness.js";
|
|
2
|
+
import type { Handler } from "../server/rpc.js";
|
|
3
|
+
import type { WorldOptions, WorldPart } from "../world/world.js";
|
|
4
|
+
import type { BrowserEngine } from "../browser/index.js";
|
|
5
|
+
import type { CallerContext } from "../core/caller.js";
|
|
6
|
+
import type { DispatchEnv } from "../tools/dispatch.js";
|
|
7
|
+
import type { ToolSpec } from "../tools/types.js";
|
|
8
|
+
import type { Subagents } from "../sessions/subagentService.js";
|
|
9
|
+
import type { ActiveRun } from "../sessions/registry.js";
|
|
10
|
+
import type { PluginDescriptor } from "./types.js";
|
|
11
|
+
export interface BuiltinPluginCommand {
|
|
12
|
+
pluginId: string;
|
|
13
|
+
prefix: string;
|
|
14
|
+
name: string;
|
|
15
|
+
description: string;
|
|
16
|
+
legacyBare: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface BuiltinWorldContext {
|
|
19
|
+
options: WorldOptions;
|
|
20
|
+
setting(pluginId: string, key: string): number;
|
|
21
|
+
browserEngine: BrowserEngine | null;
|
|
22
|
+
}
|
|
23
|
+
export interface BuiltinToolContext {
|
|
24
|
+
env: DispatchEnv;
|
|
25
|
+
caller: CallerContext;
|
|
26
|
+
variantDir: string | null;
|
|
27
|
+
run: ActiveRun;
|
|
28
|
+
runId: string;
|
|
29
|
+
allowedTools: readonly string[];
|
|
30
|
+
harnessTools: boolean;
|
|
31
|
+
subagents: Subagents;
|
|
32
|
+
sessionName: ToolSpec;
|
|
33
|
+
connectionTools?: () => ToolSpec[];
|
|
34
|
+
}
|
|
35
|
+
export interface BuiltinPluginModule {
|
|
36
|
+
descriptor: PluginDescriptor;
|
|
37
|
+
/** Stable terminal command namespace; defaults to the plugin id. */
|
|
38
|
+
commandPrefix?: string;
|
|
39
|
+
/** Command invoked by the namespace root, such as `/annotate:`. */
|
|
40
|
+
defaultCommand?: string;
|
|
41
|
+
/** Stable order for model tools, independent of descriptor display order. */
|
|
42
|
+
toolOrder?: number;
|
|
43
|
+
tools?: (context: BuiltinToolContext) => ToolSpec[];
|
|
44
|
+
commands?: readonly Omit<BuiltinPluginCommand, 'pluginId' | 'prefix' | 'legacyBare'>[];
|
|
45
|
+
createWorldPart?: (context: BuiltinWorldContext) => WorldPart | null;
|
|
46
|
+
serverMethods?: (harness: Harness) => Record<string, Handler>;
|
|
47
|
+
}
|
|
48
|
+
export interface BuiltinPluginRegistry {
|
|
49
|
+
readonly modules: readonly BuiltinPluginModule[];
|
|
50
|
+
descriptors(): PluginDescriptor[];
|
|
51
|
+
commands(): BuiltinPluginCommand[];
|
|
52
|
+
command(prefix: string, name: string): BuiltinPluginCommand | undefined;
|
|
53
|
+
commandsNamed(name: string): BuiltinPluginCommand[];
|
|
54
|
+
defaultCommand(prefix: string): BuiltinPluginCommand | undefined;
|
|
55
|
+
tools(context: BuiltinToolContext): ToolSpec[];
|
|
56
|
+
worldParts(context: BuiltinWorldContext): WorldPart[];
|
|
57
|
+
serverMethods(harness: Harness): Record<string, Handler>;
|
|
58
|
+
}
|
|
59
|
+
/** One checked registry for the Harness-owned plugin modules and their surface contributions. */
|
|
60
|
+
export declare function createBuiltinPluginRegistry(modules: readonly BuiltinPluginModule[]): BuiltinPluginRegistry;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/** One checked registry for the Harness-owned plugin modules and their surface contributions. */
|
|
2
|
+
export function createBuiltinPluginRegistry(modules) {
|
|
3
|
+
const pluginIds = new Set();
|
|
4
|
+
const prefixOwners = new Map();
|
|
5
|
+
const routeKeys = new Set();
|
|
6
|
+
for (const module of modules) {
|
|
7
|
+
const id = module.descriptor.id;
|
|
8
|
+
if (pluginIds.has(id))
|
|
9
|
+
throw new Error(`Duplicate built-in plugin id: ${id}`);
|
|
10
|
+
pluginIds.add(id);
|
|
11
|
+
const prefix = module.commandPrefix ?? id;
|
|
12
|
+
if (!/^[a-z][a-z0-9-]*$/.test(prefix) || prefix === 'plugin' || prefix === 'skill')
|
|
13
|
+
throw new Error(`Invalid built-in plugin command prefix: ${prefix}`);
|
|
14
|
+
if ((module.commands?.length || module.defaultCommand) && prefixOwners.has(prefix)) {
|
|
15
|
+
throw new Error(`Duplicate built-in plugin command prefix: ${prefix}`);
|
|
16
|
+
}
|
|
17
|
+
if (module.commands?.length || module.defaultCommand)
|
|
18
|
+
prefixOwners.set(prefix, id);
|
|
19
|
+
for (const command of module.commands ?? []) {
|
|
20
|
+
if (!/^[a-z][a-z0-9-]*$/.test(command.name))
|
|
21
|
+
throw new Error(`Invalid built-in plugin command: ${command.name}`);
|
|
22
|
+
const key = `${prefix}:${command.name}`;
|
|
23
|
+
if (routeKeys.has(key))
|
|
24
|
+
throw new Error(`Duplicate built-in plugin command: ${key}`);
|
|
25
|
+
routeKeys.add(key);
|
|
26
|
+
}
|
|
27
|
+
if (module.defaultCommand && !module.commands?.some(command => command.name === module.defaultCommand)) {
|
|
28
|
+
throw new Error(`Unknown default command for built-in plugin ${id}: ${module.defaultCommand}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const commands = modules.flatMap(module => (module.commands ?? []).map(command => ({
|
|
32
|
+
pluginId: module.descriptor.id,
|
|
33
|
+
prefix: module.commandPrefix ?? module.descriptor.id,
|
|
34
|
+
...command,
|
|
35
|
+
legacyBare: !!module.descriptor.required
|
|
36
|
+
})));
|
|
37
|
+
const byRoute = new Map(commands.map(command => [`${command.prefix}:${command.name}`, command]));
|
|
38
|
+
const byName = new Map();
|
|
39
|
+
for (const command of commands)
|
|
40
|
+
byName.set(command.name, [...(byName.get(command.name) ?? []), command]);
|
|
41
|
+
const defaults = new Map(modules.flatMap(module => module.defaultCommand
|
|
42
|
+
? [[module.commandPrefix ?? module.descriptor.id, byRoute.get(`${module.commandPrefix ?? module.descriptor.id}:${module.defaultCommand}`)]]
|
|
43
|
+
: []));
|
|
44
|
+
const toolModules = modules.map((module, index) => ({ module, index })).filter(({ module }) => module.tools)
|
|
45
|
+
.sort((left, right) => (left.module.toolOrder ?? left.index) - (right.module.toolOrder ?? right.index));
|
|
46
|
+
return {
|
|
47
|
+
modules,
|
|
48
|
+
descriptors: () => modules.map(module => module.descriptor),
|
|
49
|
+
commands: () => [...commands],
|
|
50
|
+
command: (prefix, name) => byRoute.get(`${prefix}:${name}`),
|
|
51
|
+
commandsNamed: name => [...(byName.get(name) ?? [])],
|
|
52
|
+
defaultCommand: prefix => defaults.get(prefix),
|
|
53
|
+
tools: context => toolModules.flatMap(({ module }) => module.tools(context)),
|
|
54
|
+
worldParts: context => modules.flatMap(module => {
|
|
55
|
+
const part = module.createWorldPart?.(context);
|
|
56
|
+
return part ? [part] : [];
|
|
57
|
+
}),
|
|
58
|
+
serverMethods: harness => {
|
|
59
|
+
const methods = {};
|
|
60
|
+
for (const module of modules) {
|
|
61
|
+
const contributed = module.serverMethods?.(harness) ?? {};
|
|
62
|
+
for (const [name, handler] of Object.entries(contributed)) {
|
|
63
|
+
if (name in methods)
|
|
64
|
+
throw new Error(`Duplicate built-in server method: ${name}`);
|
|
65
|
+
methods[name] = handler;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return methods;
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
@@ -43,6 +43,7 @@ function fromDescriptor(descriptor, source, attachments = null, caller = {}) {
|
|
|
43
43
|
settings: (descriptor.settings ?? []).map((setting) => ({ ...setting, value: settingValue(setting, attachments?.settings[descriptor.id]) })),
|
|
44
44
|
connectorTemplates: descriptor.connectorTemplates ?? [],
|
|
45
45
|
attachment: switchable ? describe(attachments, descriptor.id, switchable.on) : null,
|
|
46
|
+
surfaces: descriptor.surfaces ?? null,
|
|
46
47
|
contributions: [
|
|
47
48
|
...(descriptor.code ?? []).map((code) => contribution(descriptor.id, 'code', code.name, { description: code.description, state: on ? 'on' : 'off' })),
|
|
48
49
|
...(descriptor.sections ?? []).map((section) => contribution(descriptor.id, 'instruction', section.name, { description: section.description ?? '' })),
|
|
@@ -102,7 +103,7 @@ function foundContribution(plugin, item, trusted, input, projects) {
|
|
|
102
103
|
const state = !item.enabled || !on ? 'off' : loads(item, trusted) ? 'on' : 'untrusted';
|
|
103
104
|
const rest = { state, attachment, scope: attachment ? scopeWords(attachment, projects) : null };
|
|
104
105
|
if (item.path.startsWith(BUILTIN_PREFIX))
|
|
105
|
-
return contribution(plugin, kind, name, { ...rest, description: 'Built into the pi command.
|
|
106
|
+
return contribution(plugin, kind, name, { ...rest, description: 'Built into the pi command. Xingular sessions do not load it, in the terminal or in a host, so both offer the same tools.' });
|
|
106
107
|
if (item.kind === 'extension') {
|
|
107
108
|
const observed = input.registered[item.path];
|
|
108
109
|
const hash = input.loading ? registrationHash(input.loading, item.path) : null;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Harness, type HarnessOptions } from "../harness.js";
|
|
2
|
-
export declare const PLUGINS_USAGE = "Usage:
|
|
2
|
+
export declare const PLUGINS_USAGE = "Usage: xagent plugins <command> [options]\n\n list Every plugin and whether it is on\n show <plugin id> One plugin: what it brings, where it is on, its code\n install <source> A folder, an npm name, or a git address. It arrives off and untrusted\n remove <plugin id> Remove a plugin you installed\n update [plugin id] Fetch a newer version of one installed plugin, or of all\n attach <id> Switch a plugin, or one thing it brings, on\n detach <id> Switch it off\n trust <plugin id> [--yes] Show the files of its code, then trust them\n untrust <plugin id> Stop trusting its code\n\nOptions:\n --data <dir> Data directory (default: ~/.xingular-harness/data)\n --state <dir> State directory (default: ~/.xingular-harness/state)\n --cwd <dir> Also list what this working folder brings\n --project <id> attach/detach for one project instead of everywhere\n --agent <id> attach/detach for one agent instead of everywhere\n";
|
|
3
3
|
export interface PluginsCliDependencies {
|
|
4
4
|
home?: string;
|
|
5
5
|
cwd?: string;
|
package/dist/sdk/plugins/cli.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
// `
|
|
1
|
+
// `xagent plugins …`: plugin control for a person using the harness without an
|
|
2
2
|
// application. It runs outside any session, as the person who typed it, and acts directly.
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
4
|
import { join, resolve } from 'node:path';
|
|
5
5
|
import { createInterface } from 'node:readline/promises';
|
|
6
|
+
import { DEFAULT_PRODUCT_NAME } from "../core/env.js";
|
|
6
7
|
import { Harness } from "../harness.js";
|
|
7
8
|
import * as api from "./api.js";
|
|
8
9
|
import * as install from "./install.js";
|
|
9
|
-
export const PLUGINS_USAGE = `Usage:
|
|
10
|
+
export const PLUGINS_USAGE = `Usage: xagent plugins <command> [options]
|
|
10
11
|
|
|
11
12
|
list Every plugin and whether it is on
|
|
12
13
|
show <plugin id> One plugin: what it brings, where it is on, its code
|
|
@@ -81,7 +82,7 @@ export async function runPluginsCli(argv, dependencies = {}) {
|
|
|
81
82
|
}
|
|
82
83
|
const base = dependencies.cwd ?? process.cwd();
|
|
83
84
|
const root = join(dependencies.home ?? homedir(), '.xingular-harness');
|
|
84
|
-
const options = { dataRoot: parsed.values.data ? resolve(base, parsed.values.data) : join(root, 'data'), stateDir: parsed.values.state ? resolve(base, parsed.values.state) : join(root, 'state'), productName:
|
|
85
|
+
const options = { dataRoot: parsed.values.data ? resolve(base, parsed.values.data) : join(root, 'data'), stateDir: parsed.values.state ? resolve(base, parsed.values.state) : join(root, 'state'), productName: DEFAULT_PRODUCT_NAME };
|
|
85
86
|
// Built without opening the data root: a plugin command must not settle runs or migrate a Wiki
|
|
86
87
|
// that another process may be using.
|
|
87
88
|
const harness = dependencies.createHarness ? dependencies.createHarness(options) : new Harness(options);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface CommandSourceInfo {
|
|
2
|
+
path: string;
|
|
3
|
+
source?: string;
|
|
4
|
+
origin?: 'package' | 'top-level';
|
|
5
|
+
baseDir?: string;
|
|
6
|
+
}
|
|
7
|
+
/** Stable command namespace for a Pi extension's owning package or loose extension file. */
|
|
8
|
+
export declare function pluginCommandPrefix(source: CommandSourceInfo): string;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { basename, dirname, extname } from 'node:path';
|
|
2
|
+
import { packageManifest } from "./manifest.js";
|
|
3
|
+
const slug = (value) => {
|
|
4
|
+
const normalized = value.toLowerCase().replace(/[^a-z0-9-]+/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '');
|
|
5
|
+
const prefix = /^[a-z]/.test(normalized) ? normalized : `plugin-${normalized || 'command'}`;
|
|
6
|
+
return prefix === 'plugin' || prefix === 'skill' ? `extension-${prefix}` : prefix;
|
|
7
|
+
};
|
|
8
|
+
/** Stable command namespace for a Pi extension's owning package or loose extension file. */
|
|
9
|
+
export function pluginCommandPrefix(source) {
|
|
10
|
+
if (source.origin === 'package' && source.baseDir) {
|
|
11
|
+
const manifest = packageManifest(source.baseDir);
|
|
12
|
+
return manifest.commandPrefix ?? slug(manifest.name);
|
|
13
|
+
}
|
|
14
|
+
if (source.path.startsWith('builtin:'))
|
|
15
|
+
return slug(source.path.slice('builtin:'.length));
|
|
16
|
+
const synthetic = /^<[^:>]+:([^>]+)>$/.exec(source.path);
|
|
17
|
+
if (synthetic)
|
|
18
|
+
return slug(synthetic[1]);
|
|
19
|
+
const file = basename(source.path, extname(source.path));
|
|
20
|
+
return slug(file === 'index' ? basename(dirname(source.path)) : file);
|
|
21
|
+
}
|
|
@@ -5,7 +5,7 @@ interface Api {
|
|
|
5
5
|
on(event: 'tool_call', handler: (event: {
|
|
6
6
|
toolName: string;
|
|
7
7
|
}) => unknown): void;
|
|
8
|
-
on(event: 'turn_start', handler: () => unknown): void;
|
|
8
|
+
on(event: 'turn_start' | 'agent_start', handler: () => unknown): void;
|
|
9
9
|
on(event: 'message_end', handler: (event: {
|
|
10
10
|
message: {
|
|
11
11
|
role: string;
|
|
@@ -21,7 +21,7 @@ export const FIRST_PARTY_PLUGINS = [
|
|
|
21
21
|
description: 'Cuts a very long tool result to its beginning and its end before the model reads it, and says how much was cut.',
|
|
22
22
|
switchable: { on: false },
|
|
23
23
|
settings: OUTPUT_TRIM_SETTINGS,
|
|
24
|
-
code: [{ name: 'Trim long tool results', description: 'Runs after every tool call, in conversations, task threads and unattended work.
|
|
24
|
+
code: [{ name: 'Trim long tool results', description: 'Runs after every tool call, in conversations, terminal sessions, task threads and unattended work.' }]
|
|
25
25
|
},
|
|
26
26
|
{
|
|
27
27
|
id: BUDGET_GUARD,
|
|
@@ -29,7 +29,7 @@ export const FIRST_PARTY_PLUGINS = [
|
|
|
29
29
|
description: 'Stops a reply that keeps going: past a limit of model requests or tokens, further tool calls are refused and the agent is told to wrap up.',
|
|
30
30
|
switchable: { on: false },
|
|
31
31
|
settings: BUDGET_GUARD_SETTINGS,
|
|
32
|
-
code: [{ name: 'Refuse tool calls past the limit', description: 'Counts model requests and tokens in one reply, in conversations, task threads and unattended work.
|
|
32
|
+
code: [{ name: 'Refuse tool calls past the limit', description: 'Counts model requests and tokens in one reply, in conversations, terminal sessions, task threads and unattended work.' }]
|
|
33
33
|
},
|
|
34
34
|
{
|
|
35
35
|
id: LESSONS,
|
|
@@ -75,6 +75,12 @@ export function budgetGuard(saved) {
|
|
|
75
75
|
let requests = 0;
|
|
76
76
|
let tokens = 0;
|
|
77
77
|
let refusedInRequest = 0;
|
|
78
|
+
// A terminal session keeps one Pi session for many replies; each reply starts its own count.
|
|
79
|
+
pi.on('agent_start', () => {
|
|
80
|
+
requests = 0;
|
|
81
|
+
tokens = 0;
|
|
82
|
+
refusedInRequest = 0;
|
|
83
|
+
});
|
|
78
84
|
pi.on('turn_start', () => {
|
|
79
85
|
requests += 1;
|
|
80
86
|
});
|