@selesai/code 0.13.16 → 0.13.19
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 +41 -0
- package/README.md +2 -14
- package/dist/bun/cli.d.ts +3 -1
- package/dist/bun/cli.js +3 -9
- package/dist/bun/{register-bedrock.js → runtime-setup.js} +5 -0
- package/dist/bun/sandbox-env-setup.d.ts +1 -0
- package/dist/bun/sandbox-env-setup.js +3 -0
- package/dist/cli/auth-command.d.ts +23 -0
- package/dist/cli/auth-command.js +102 -0
- package/dist/cli/config-selector.js +2 -1
- package/dist/cli/setup.d.ts +1 -0
- package/dist/cli/setup.js +11 -0
- package/dist/cli.js +2 -14
- package/dist/config.d.ts +3 -2
- package/dist/config.js +9 -4
- package/dist/core/agent-session-runtime.js +15 -7
- package/dist/core/agent-session.d.ts +2 -6
- package/dist/core/agent-session.js +15 -4
- package/dist/core/compaction/branch-summarization.d.ts +1 -1
- package/dist/core/compaction/branch-summarization.js +2 -1
- package/dist/core/extensions/loader.js +3 -0
- package/dist/core/extensions/types.d.ts +16 -2
- package/dist/core/http-dispatcher.js +2 -0
- package/dist/core/keybindings.d.ts +5 -0
- package/dist/core/keybindings.js +4 -0
- package/dist/core/messages.d.ts +1 -1
- package/dist/core/model-config.d.ts +15 -0
- package/dist/core/model-config.js +3 -0
- package/dist/core/model-runtime.d.ts +1 -0
- package/dist/core/model-runtime.js +5 -2
- package/dist/core/provider-composer.js +8 -2
- package/dist/core/session-export.d.ts +3 -0
- package/dist/core/session-export.js +31 -0
- package/dist/core/session-manager.d.ts +3 -2
- package/dist/core/session-manager.js +40 -13
- package/dist/core/skills.d.ts +1 -1
- package/dist/core/skills.js +4 -2
- package/dist/core/system-prompt.js +10 -10
- package/dist/core/tools/bash.js +3 -117
- package/dist/core/tools/edit.d.ts +1 -12
- package/dist/core/tools/edit.js +5 -163
- package/dist/core/tools/find.js +4 -55
- package/dist/core/tools/grep.js +4 -60
- package/dist/core/tools/ls.js +4 -49
- package/dist/core/tools/read.d.ts +4 -0
- package/dist/core/tools/read.js +10 -122
- package/dist/core/tools/renderers/bash.d.ts +11 -0
- package/dist/core/tools/renderers/bash.js +129 -0
- package/dist/core/tools/renderers/edit.d.ts +22 -0
- package/dist/core/tools/renderers/edit.js +166 -0
- package/dist/core/tools/renderers/find.d.ts +9 -0
- package/dist/core/tools/renderers/find.js +63 -0
- package/dist/core/tools/renderers/grep.d.ts +9 -0
- package/dist/core/tools/renderers/grep.js +68 -0
- package/dist/core/tools/renderers/index.d.ts +27 -0
- package/dist/core/tools/renderers/index.js +46 -0
- package/dist/core/tools/renderers/ls.d.ts +9 -0
- package/dist/core/tools/renderers/ls.js +57 -0
- package/dist/core/tools/renderers/read.d.ts +10 -0
- package/dist/core/tools/renderers/read.js +128 -0
- package/dist/core/tools/renderers/write.d.ts +9 -0
- package/dist/core/tools/renderers/write.js +152 -0
- package/dist/core/tools/write.js +5 -146
- package/dist/extensions/agent-browser.ts +1 -2
- package/dist/extensions/package.json +0 -1
- package/dist/extensions/pi-hermes-memory/CHANGELOG.md +18 -0
- package/dist/extensions/pi-hermes-memory/README.md +16 -12
- package/dist/extensions/pi-hermes-memory/docs/ROADMAP.md +1 -1
- package/dist/extensions/pi-hermes-memory/package-lock.json +587 -62
- package/dist/extensions/pi-hermes-memory/package.json +4 -4
- package/dist/extensions/pi-hermes-memory/src/config.ts +32 -0
- package/dist/extensions/pi-hermes-memory/src/constants.ts +12 -2
- package/dist/extensions/pi-hermes-memory/src/handlers/background-review.ts +109 -51
- package/dist/extensions/pi-hermes-memory/src/handlers/index-sessions.ts +9 -3
- package/dist/extensions/pi-hermes-memory/src/handlers/review-memory-ops.ts +257 -98
- package/dist/extensions/pi-hermes-memory/src/handlers/session-backfill.ts +9 -2
- package/dist/extensions/pi-hermes-memory/src/handlers/sync-markdown-memories.ts +5 -0
- package/dist/extensions/pi-hermes-memory/src/index.ts +22 -2
- package/dist/extensions/pi-hermes-memory/src/paths.ts +1 -1
- package/dist/extensions/pi-hermes-memory/src/store/db.ts +6 -0
- package/dist/extensions/pi-hermes-memory/src/store/fts-query.ts +58 -1
- package/dist/extensions/pi-hermes-memory/src/store/memory-store.ts +60 -8
- package/dist/extensions/pi-hermes-memory/src/store/session-indexer.ts +169 -7
- package/dist/extensions/pi-hermes-memory/src/store/session-search.ts +7 -21
- package/dist/extensions/pi-hermes-memory/src/store/sqlite-memory-store.ts +134 -15
- package/dist/extensions/pi-hermes-memory/src/tools/memory-search-tool.ts +4 -2
- package/dist/extensions/pi-hermes-memory/src/tools/memory-tool.ts +24 -9
- package/dist/extensions/pi-hermes-memory/src/types.ts +11 -0
- package/dist/extensions/pi-hermes-memory/tests/config.test.ts +42 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/background-review.test.ts +159 -3
- package/dist/extensions/pi-hermes-memory/tests/handlers/review-memory-ops.test.ts +452 -0
- package/dist/extensions/pi-hermes-memory/tests/handlers/session-backfill.test.ts +39 -0
- package/dist/extensions/pi-hermes-memory/tests/integration/corruption-recovery-integration.test.ts +91 -0
- package/dist/extensions/pi-hermes-memory/tests/store/db.test.ts +29 -0
- package/dist/extensions/pi-hermes-memory/tests/store/fts-query.test.ts +116 -0
- package/dist/extensions/pi-hermes-memory/tests/store/memory-store.test.ts +163 -0
- package/dist/extensions/pi-hermes-memory/tests/store/session-indexer.test.ts +233 -0
- package/dist/extensions/pi-hermes-memory/tests/store/session-search.test.ts +12 -0
- package/dist/extensions/pi-hermes-memory/tests/store/sqlite-memory-store.test.ts +175 -0
- package/dist/extensions/pi-hermes-memory/tests/store/sqlite-native.test.ts +2 -2
- package/dist/extensions/pi-hermes-memory/tests/tools/memory-search-tool.test.ts +22 -0
- package/dist/extensions/pi-hermes-memory/tests/tools/memory-tool.test.ts +37 -1
- package/dist/extensions/pi-intercom/CHANGELOG.md +13 -0
- package/dist/extensions/pi-intercom/README.md +16 -2
- package/dist/extensions/pi-intercom/broker/spawn.test.ts +19 -2
- package/dist/extensions/pi-intercom/broker/spawn.ts +4 -4
- package/dist/extensions/pi-intercom/index.ts +1 -1
- package/dist/extensions/pi-intercom/intercom.integration.test.ts +121 -2
- package/dist/extensions/pi-intercom/package.json +1 -1
- package/dist/extensions/pi-intercom/project-agent.test.ts +1 -1
- package/dist/extensions/pi-intercom/project-agent.ts +1 -6
- package/dist/extensions/pi-intercom/skills/pi-intercom/SKILL.md +7 -6
- package/dist/extensions/pi-rewind-hook/index.test.ts +7 -0
- package/dist/extensions/pi-subagents/.github/workflows/test.yml +36 -4
- package/dist/extensions/pi-subagents/CHANGELOG.md +120 -0
- package/dist/extensions/pi-subagents/README.md +3 -3
- package/dist/extensions/pi-subagents/agents/researcher.md +23 -13
- package/dist/extensions/pi-subagents/agents/reviewer.md +1 -1
- package/dist/extensions/pi-subagents/agents/scout.md +1 -1
- package/dist/extensions/pi-subagents/docs/agents.md +32 -16
- package/dist/extensions/pi-subagents/docs/configuration.md +41 -15
- package/dist/extensions/pi-subagents/docs/extension-api.md +109 -6
- package/dist/extensions/pi-subagents/docs/missions.md +2 -0
- package/dist/extensions/pi-subagents/docs/models.md +58 -1
- package/dist/extensions/pi-subagents/docs/observability.md +50 -12
- package/dist/extensions/pi-subagents/docs/tool-reference.md +17 -10
- package/dist/extensions/pi-subagents/docs/watchdog.md +1 -1
- package/dist/extensions/pi-subagents/docs/workflows.md +26 -9
- package/dist/extensions/pi-subagents/package-lock.json +747 -177
- package/dist/extensions/pi-subagents/package.json +6 -4
- package/dist/extensions/pi-subagents/runner-server-preload.mjs +13 -0
- package/dist/extensions/pi-subagents/skills/pi-subagents/SKILL.md +2 -1
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/constraints-and-recipes.md +1 -1
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/execution-controls.md +21 -4
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/management-authoring-rpc.md +2 -1
- package/dist/extensions/pi-subagents/skills/pi-subagents/references/multi-lane-orchestration.md +2 -0
- package/dist/extensions/pi-subagents/src/agents/advertised-agent-prompt.ts +63 -0
- package/dist/extensions/pi-subagents/src/agents/agent-management.ts +61 -16
- package/dist/extensions/pi-subagents/src/agents/agent-serializer.ts +2 -0
- package/dist/extensions/pi-subagents/src/agents/agents.ts +8 -0
- package/dist/extensions/pi-subagents/src/api/capability-ceiling.ts +0 -1
- package/dist/extensions/pi-subagents/src/api/{pi-args.ts → child-tool-plan.ts} +1 -1
- package/dist/extensions/pi-subagents/src/api/preflight.ts +7 -4
- package/dist/extensions/pi-subagents/src/api/shared-types.ts +2 -2
- package/dist/extensions/pi-subagents/src/api/workflow-resources.ts +6 -0
- package/dist/extensions/pi-subagents/src/extension/config.ts +4 -2
- package/dist/extensions/pi-subagents/src/extension/doctor.ts +2 -10
- package/dist/extensions/pi-subagents/src/extension/fanout-child.ts +9 -11
- package/dist/extensions/pi-subagents/src/extension/index.ts +99 -10
- package/dist/extensions/pi-subagents/src/extension/public-execution.ts +13 -0
- package/dist/extensions/pi-subagents/src/extension/rpc.ts +7 -23
- package/dist/extensions/pi-subagents/src/extension/schemas.ts +11 -8
- package/dist/extensions/pi-subagents/src/extension/tool-description.ts +25 -7
- package/dist/extensions/pi-subagents/src/integrations/pi-web-session-liveness.ts +73 -0
- package/dist/extensions/pi-subagents/src/intercom/native-supervisor-channel.ts +228 -136
- package/dist/extensions/pi-subagents/src/intercom/supervisor-ui.ts +244 -0
- package/dist/extensions/pi-subagents/src/missions/workflow-state.ts +37 -16
- package/dist/extensions/pi-subagents/src/runs/background/active-async-capacity.ts +18 -18
- package/dist/extensions/pi-subagents/src/runs/background/async-execution.ts +51 -25
- package/dist/extensions/pi-subagents/src/runs/background/async-job-tracker.ts +46 -3
- package/dist/extensions/pi-subagents/src/runs/background/async-resume.ts +14 -3
- package/dist/extensions/pi-subagents/src/runs/background/async-retention.ts +9 -0
- package/dist/extensions/pi-subagents/src/runs/background/async-status-snapshot.ts +10 -12
- package/dist/extensions/pi-subagents/src/runs/background/async-status.ts +18 -15
- package/dist/extensions/pi-subagents/src/runs/background/auto-drain.ts +40 -29
- package/dist/extensions/pi-subagents/src/runs/background/chain-root-attachment.ts +8 -0
- package/dist/extensions/pi-subagents/src/runs/background/control-channel.ts +79 -247
- package/dist/extensions/pi-subagents/src/runs/background/notify.ts +88 -12
- package/dist/extensions/pi-subagents/src/runs/background/owned-process-tree.ts +6 -6
- package/dist/extensions/pi-subagents/src/runs/background/process-terminal.ts +24 -24
- package/dist/extensions/pi-subagents/src/runs/background/retained-nested-route-tracker.ts +96 -0
- package/dist/extensions/pi-subagents/src/runs/background/run-child-session.ts +642 -0
- package/dist/extensions/pi-subagents/src/runs/background/run-status.ts +75 -6
- package/dist/extensions/pi-subagents/src/runs/background/runner-aliases.ts +163 -0
- package/dist/extensions/pi-subagents/src/runs/background/runner-child-launch.ts +86 -0
- package/dist/extensions/pi-subagents/src/runs/background/runner-child-sessions.ts +31 -0
- package/dist/extensions/pi-subagents/src/runs/background/scheduled-runs.ts +18 -4
- package/dist/extensions/pi-subagents/src/runs/background/stale-run-reconciler.ts +3 -1
- package/dist/extensions/pi-subagents/src/runs/background/subagent-runner.ts +597 -1092
- package/dist/extensions/pi-subagents/src/runs/background/subagent-wait.ts +3 -0
- package/dist/extensions/pi-subagents/src/runs/background/wait-completions.ts +4 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/async-steering-action.ts +20 -17
- package/dist/extensions/pi-subagents/src/runs/foreground/execution.ts +296 -394
- package/dist/extensions/pi-subagents/src/runs/foreground/foreground-control.ts +4 -0
- package/dist/extensions/pi-subagents/src/runs/foreground/foreground-history.ts +3 -1
- package/dist/extensions/pi-subagents/src/runs/foreground/prompt-audit.ts +9 -5
- package/dist/extensions/pi-subagents/src/runs/foreground/subagent-executor.ts +630 -283
- package/dist/extensions/pi-subagents/src/runs/foreground/workflow-detach-reconcile.ts +8 -5
- package/dist/extensions/pi-subagents/src/runs/foreground/workflow-foreground-steering.ts +78 -98
- package/dist/extensions/pi-subagents/src/runs/shared/abort-recovery.ts +3 -3
- package/dist/extensions/pi-subagents/src/runs/shared/acceptance.ts +16 -3
- package/dist/extensions/pi-subagents/src/runs/shared/agent-contract.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/shared/async-status-projection.ts +47 -47
- package/dist/extensions/pi-subagents/src/runs/shared/capability-ceiling.ts +1 -2
- package/dist/extensions/pi-subagents/src/runs/shared/child-hooks.ts +174 -0
- package/dist/extensions/pi-subagents/src/runs/shared/child-identity.ts +14 -3
- package/dist/extensions/pi-subagents/src/runs/shared/child-launch.ts +319 -0
- package/dist/extensions/pi-subagents/src/runs/shared/child-lifecycle.ts +25 -0
- package/dist/extensions/pi-subagents/src/runs/shared/child-runtime-config.ts +126 -0
- package/dist/extensions/pi-subagents/src/runs/shared/child-session.ts +373 -0
- package/dist/extensions/pi-subagents/src/runs/shared/child-tool-plan.ts +530 -0
- package/dist/extensions/pi-subagents/src/runs/shared/completion-evidence.ts +2 -2
- package/dist/extensions/pi-subagents/src/runs/shared/completion-guard.ts +2 -1
- package/dist/extensions/pi-subagents/src/runs/shared/external-cli-preflight.ts +16 -0
- package/dist/extensions/pi-subagents/src/runs/shared/host-step-status.ts +11 -11
- package/dist/extensions/pi-subagents/src/runs/shared/llm-intent-arbiter.ts +30 -20
- package/dist/extensions/pi-subagents/src/runs/shared/mcp-direct-tool-allowlist.ts +5 -4
- package/dist/extensions/pi-subagents/src/runs/shared/model-exclusions.ts +84 -15
- package/dist/extensions/pi-subagents/src/runs/shared/model-fallback.ts +88 -12
- package/dist/extensions/pi-subagents/src/runs/shared/nested-events.ts +37 -53
- package/dist/extensions/pi-subagents/src/runs/shared/nested-path.ts +1 -1
- package/dist/extensions/pi-subagents/src/runs/shared/orca-progress-tabs.ts +18 -7
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-handoff.ts +57 -12
- package/dist/extensions/pi-subagents/src/runs/shared/parallel-utils.ts +3 -4
- package/dist/extensions/pi-subagents/src/runs/shared/permissions.ts +0 -11
- package/dist/extensions/pi-subagents/src/runs/shared/process-signal.ts +4 -1
- package/dist/extensions/pi-subagents/src/runs/shared/readonly-drain-observation.ts +42 -0
- package/dist/extensions/pi-subagents/src/runs/shared/readonly-model-continuation.ts +69 -0
- package/dist/extensions/pi-subagents/src/runs/shared/readonly-session-evidence.ts +307 -0
- package/dist/extensions/pi-subagents/src/runs/shared/run-fanout-budget.ts +8 -21
- package/dist/extensions/pi-subagents/src/runs/shared/runtime-acknowledged-extensions.ts +3 -30
- package/dist/extensions/pi-subagents/src/runs/shared/structured-output.ts +17 -4
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-control.ts +2 -0
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-prompt-runtime.ts +99 -386
- package/dist/extensions/pi-subagents/src/runs/shared/tool-availability.ts +18 -62
- package/dist/extensions/pi-subagents/src/runs/shared/tool-budget.ts +0 -14
- package/dist/extensions/pi-subagents/src/runs/shared/worktree-cleanup-plan.ts +31 -9
- package/dist/extensions/pi-subagents/src/runs/shared/worktree-setup-command.ts +190 -0
- package/dist/extensions/pi-subagents/src/runs/shared/worktree.ts +506 -226
- package/dist/extensions/pi-subagents/src/shared/child-session-name.ts +1 -1
- package/dist/extensions/pi-subagents/src/shared/jsonl-writer.ts +11 -0
- package/dist/extensions/pi-subagents/src/shared/model-response-aliases.ts +13 -0
- package/dist/extensions/pi-subagents/src/shared/thinking-ceiling.ts +0 -6
- package/dist/extensions/pi-subagents/src/shared/types.ts +145 -89
- package/dist/extensions/pi-subagents/src/shared/utils.ts +13 -6
- package/dist/extensions/pi-subagents/src/shared/watch-strategy.ts +2 -0
- package/dist/extensions/pi-subagents/src/shared/workflow-child-permit.ts +18 -13
- package/dist/extensions/pi-subagents/src/slash/slash-commands.ts +0 -6
- package/dist/extensions/pi-subagents/src/tui/fleet-status.ts +1 -1
- package/dist/extensions/pi-subagents/src/tui/fleet.ts +11 -6
- package/dist/extensions/pi-subagents/src/tui/render.ts +277 -46
- package/dist/extensions/pi-subagents/src/watchdog/child-status.ts +0 -1
- package/dist/extensions/pi-subagents/src/watchdog/register-child.ts +12 -12
- package/dist/extensions/pi-subagents/src/workflows/chat-progress.ts +3 -3
- package/dist/extensions/pi-subagents/src/workflows/scripted-workflow.ts +116 -15
- package/dist/extensions/pi-subagents/src/workflows/workflow-checklist.ts +15 -18
- package/dist/extensions/pi-subagents/src/workflows/workflow-child-summary.ts +57 -8
- package/dist/extensions/pi-subagents/src/workflows/workflow-preflight.ts +19 -19
- package/dist/extensions/pi-subagents/src/workflows/workflow-receipt.ts +3 -3
- package/dist/extensions/pi-subagents/src/workflows/workflow-resources.ts +97 -22
- package/dist/extensions/pi-subagents/src/workflows/workflow-settlement.ts +3 -0
- package/dist/extensions/pi-subagents/test/integration/acceptance-file-report.test.ts +336 -21
- package/dist/extensions/pi-subagents/test/integration/async-execution.part-1.test.ts +1181 -0
- package/dist/extensions/pi-subagents/test/integration/async-execution.part-2.test.ts +2240 -0
- package/dist/extensions/pi-subagents/test/integration/async-execution.part-3.test.ts +2268 -0
- package/dist/extensions/pi-subagents/test/integration/async-execution.part-4.test.ts +1512 -0
- package/dist/extensions/pi-subagents/test/integration/async-job-tracker.test.ts +231 -16
- package/dist/extensions/pi-subagents/test/integration/error-handling.test.ts +4 -18
- package/dist/extensions/pi-subagents/test/integration/foreign-workflow-steering.test.ts +95 -0
- package/dist/extensions/pi-subagents/test/integration/fork-context-execution.test.ts +9 -15
- package/dist/extensions/pi-subagents/test/integration/in-process-child.test.ts +374 -0
- package/dist/extensions/pi-subagents/test/integration/intercom-result-delivery.test.ts +20 -10
- package/dist/extensions/pi-subagents/test/integration/orca-progress-tabs.test.ts +18 -6
- package/dist/extensions/pi-subagents/test/integration/recovered-assistant-error.test.ts +151 -0
- package/dist/extensions/pi-subagents/test/integration/render-fork-badge.test.ts +42 -1
- package/dist/extensions/pi-subagents/test/integration/render-widget.test.ts +150 -25
- package/dist/extensions/pi-subagents/test/integration/result-publication.test.ts +354 -0
- package/dist/extensions/pi-subagents/test/integration/shared-cwd-terminal-evidence.test.ts +117 -0
- package/dist/extensions/pi-subagents/test/integration/single-execution.part-1.test.ts +3678 -0
- package/dist/extensions/pi-subagents/test/integration/{single-execution.test.ts → single-execution.part-2.test.ts} +500 -4207
- package/dist/extensions/pi-subagents/test/integration/slash-commands.test.ts +1 -2
- package/dist/extensions/pi-subagents/test/integration/workflow-result-publication.test.ts +127 -0
- package/dist/extensions/pi-subagents/test/integration/workflow-steer-inbox.test.ts +365 -0
- package/dist/extensions/pi-subagents/test/smoke/pi085-child.ts +31 -0
- package/dist/extensions/pi-subagents/test/smoke/pi085-clean-install.mjs +74 -0
- package/dist/extensions/pi-subagents/test/smoke/pi085-extension.ts +16 -0
- package/dist/extensions/pi-subagents/test/support/async-execution-fixture.ts +699 -0
- package/dist/extensions/pi-subagents/test/support/fake-child-session.ts +418 -0
- package/dist/extensions/pi-subagents/test/support/foreign-workflow-steer-host.mjs +13 -0
- package/dist/extensions/pi-subagents/test/support/mock-pi.ts +30 -76
- package/dist/extensions/pi-subagents/test/support/notify-diagnostics-fixture.ts +84 -0
- package/dist/extensions/pi-subagents/test/support/result-publication-capacity-preload.mjs +70 -0
- package/dist/extensions/pi-subagents/test/support/runner-child-session-factory.ts +17 -0
- package/dist/extensions/pi-subagents/test/support/single-execution-fixture.ts +390 -0
- package/dist/extensions/pi-subagents/test/unit/acceptance-compaction.test.ts +120 -0
- package/dist/extensions/pi-subagents/test/unit/acceptance.test.ts +24 -3
- package/dist/extensions/pi-subagents/test/unit/advertised-agent-prompt.test.ts +87 -0
- package/dist/extensions/pi-subagents/test/unit/advertised-agent-refresh.test.ts +163 -0
- package/dist/extensions/pi-subagents/test/unit/agent-frontmatter.test.ts +70 -31
- package/dist/extensions/pi-subagents/test/unit/agent-management.test.ts +78 -3
- package/dist/extensions/pi-subagents/test/unit/agent-overrides.test.ts +2 -8
- package/dist/extensions/pi-subagents/test/unit/async-execution.test.ts +1 -1
- package/dist/extensions/pi-subagents/test/unit/async-interrupt-action.test.ts +73 -66
- package/dist/extensions/pi-subagents/test/unit/async-recovery-descriptor.test.ts +51 -1
- package/dist/extensions/pi-subagents/test/unit/async-retention.test.ts +49 -1
- package/dist/extensions/pi-subagents/test/unit/async-spawn-preload.test.ts +103 -0
- package/dist/extensions/pi-subagents/test/unit/async-status-projection.test.ts +3 -3
- package/dist/extensions/pi-subagents/test/unit/capability-ceiling-agent-allowlist.test.ts +9 -8
- package/dist/extensions/pi-subagents/test/unit/capability-ceiling.test.ts +10 -7
- package/dist/extensions/pi-subagents/test/unit/chain-root-attachment.test.ts +48 -6
- package/dist/extensions/pi-subagents/test/unit/child-runtime-config.test.ts +90 -0
- package/dist/extensions/pi-subagents/test/unit/{pi-args-permission-system.test.ts → child-tool-plan-permission-system.test.ts} +48 -86
- package/dist/extensions/pi-subagents/test/unit/child-tool-plan.test.ts +33 -0
- package/dist/extensions/pi-subagents/test/unit/compaction-resume.test.ts +18 -18
- package/dist/extensions/pi-subagents/test/unit/completion-evidence.test.ts +9 -9
- package/dist/extensions/pi-subagents/test/unit/completion-guard.test.ts +8 -7
- package/dist/extensions/pi-subagents/test/unit/control-channel.test.ts +225 -65
- package/dist/extensions/pi-subagents/test/unit/extension-bindings.test.ts +17 -22
- package/dist/extensions/pi-subagents/test/unit/fleet-status.test.ts +11 -1
- package/dist/extensions/pi-subagents/test/unit/fleet.test.ts +47 -3
- package/dist/extensions/pi-subagents/test/unit/foreign-workflow-steering.test.ts +74 -0
- package/dist/extensions/pi-subagents/test/unit/fork-cache-key.test.ts +23 -29
- package/dist/extensions/pi-subagents/test/unit/host-peer-runtime-imports.test.ts +96 -4
- package/dist/extensions/pi-subagents/test/unit/host-step-status.test.ts +4 -4
- package/dist/extensions/pi-subagents/test/unit/index-child-registration.test.ts +116 -55
- package/dist/extensions/pi-subagents/test/unit/index-segment.test.ts +58 -1
- package/dist/extensions/pi-subagents/test/unit/llm-intent-arbiter.test.ts +104 -3
- package/dist/extensions/pi-subagents/test/unit/mission-lifecycle.test.ts +10 -1
- package/dist/extensions/pi-subagents/test/unit/mission-store.test.ts +31 -1
- package/dist/extensions/pi-subagents/test/unit/model-exclusions.test.ts +102 -51
- package/dist/extensions/pi-subagents/test/unit/model-fallback.test.ts +196 -6
- package/dist/extensions/pi-subagents/test/unit/native-supervisor-channel.test.ts +181 -38
- package/dist/extensions/pi-subagents/test/unit/nested-control.test.ts +62 -70
- package/dist/extensions/pi-subagents/test/unit/nested-events.test.ts +58 -53
- package/dist/extensions/pi-subagents/test/unit/notify-diagnostics.test.ts +42 -0
- package/dist/extensions/pi-subagents/test/unit/notify.test.ts +84 -0
- package/dist/extensions/pi-subagents/test/unit/orca-progress-tabs.test.ts +13 -5
- package/dist/extensions/pi-subagents/test/unit/package-manifest.test.ts +21 -5
- package/dist/extensions/pi-subagents/test/unit/parallel-handoff.test.ts +5 -4
- package/dist/extensions/pi-subagents/test/unit/permissions.test.ts +2 -6
- package/dist/extensions/pi-subagents/test/unit/pi-coding-agent-dir.test.ts +28 -2
- package/dist/extensions/pi-subagents/test/unit/pi-web-session-liveness.test.ts +209 -0
- package/dist/extensions/pi-subagents/test/unit/preflight.test.ts +38 -1
- package/dist/extensions/pi-subagents/test/unit/prompt-audit-optional-peers.test.ts +43 -0
- package/dist/extensions/pi-subagents/test/unit/public-execution.test.ts +24 -2
- package/dist/extensions/pi-subagents/test/unit/readonly-drain-observation.test.ts +174 -0
- package/dist/extensions/pi-subagents/test/unit/readonly-model-continuation.test.ts +94 -0
- package/dist/extensions/pi-subagents/test/unit/readonly-session-evidence.test.ts +1329 -0
- package/dist/extensions/pi-subagents/test/unit/recursion-guard.test.ts +29 -80
- package/dist/extensions/pi-subagents/test/unit/render-helpers.test.ts +11 -8
- package/dist/extensions/pi-subagents/test/unit/result-files.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/unit/retained-nested-route-tracker.test.ts +175 -0
- package/dist/extensions/pi-subagents/test/unit/rpc.test.ts +38 -12
- package/dist/extensions/pi-subagents/test/unit/run-fanout-budget.test.ts +2 -5
- package/dist/extensions/pi-subagents/test/unit/run-status.test.ts +89 -1
- package/dist/extensions/pi-subagents/test/unit/runtime-acknowledged-extensions.test.ts +2 -16
- package/dist/extensions/pi-subagents/test/unit/scheduled-runs.test.ts +27 -3
- package/dist/extensions/pi-subagents/test/unit/scheduled-supervisor-demand.test.ts +215 -0
- package/dist/extensions/pi-subagents/test/unit/schemas.test.ts +15 -11
- package/dist/extensions/pi-subagents/test/unit/scripted-workflow.test.ts +237 -1
- package/dist/extensions/pi-subagents/test/unit/steering-action.test.ts +2 -5
- package/dist/extensions/pi-subagents/test/unit/streamed-progress-bounds.test.ts +2 -2
- package/dist/extensions/pi-subagents/test/unit/subagent-guide.test.ts +14 -1
- package/dist/extensions/pi-subagents/test/unit/subagent-prompt-runtime.test.ts +130 -739
- package/dist/extensions/pi-subagents/test/unit/supervisor-ask-registration.test.ts +682 -0
- package/dist/extensions/pi-subagents/test/unit/supervisor-ui.test.ts +137 -0
- package/dist/extensions/pi-subagents/test/unit/tool-budget.test.ts +1 -11
- package/dist/extensions/pi-subagents/test/unit/tool-description.test.ts +23 -3
- package/dist/extensions/pi-subagents/test/unit/wait-completions.test.ts +8 -1
- package/dist/extensions/pi-subagents/test/unit/watchdog-tool-actions.test.ts +19 -1
- package/dist/extensions/pi-subagents/test/unit/workflow-chat-progress.test.ts +72 -4
- package/dist/extensions/pi-subagents/test/unit/workflow-checklist.test.ts +17 -3
- package/dist/extensions/pi-subagents/test/unit/workflow-child-summary.test.ts +34 -0
- package/dist/extensions/pi-subagents/test/unit/workflow-detach-reconcile.test.ts +12 -2
- package/dist/extensions/pi-subagents/test/unit/workflow-launch-params.test.ts +46 -6
- package/dist/extensions/pi-subagents/test/unit/workflow-receipt.test.ts +3 -3
- package/dist/extensions/pi-subagents/test/unit/workflow-resources.test.ts +133 -1
- package/dist/extensions/pi-subagents/test/unit/workflow-resume-hint.test.ts +53 -2
- package/dist/extensions/pi-subagents/test/unit/worktree-cleanup-plan.test.ts +222 -14
- package/dist/extensions/pi-subagents/test/unit/worktree.test.ts +526 -85
- package/dist/extensions/pi-web-agent/README.md +6 -5
- package/dist/extensions/pi-web-agent/src/backends/config.ts +12 -6
- package/dist/extensions/pi-web-agent/src/backends/factory.ts +2 -2
- package/dist/extensions/pi-web-agent/src/backends/settings-reader.ts +4 -5
- package/dist/extensions/pi-web-agent/src/commands/web-agent-config.ts +8 -8
- package/dist/extensions/pi-web-agent/src/extension.ts +3 -3
- package/dist/extensions/pi-web-agent/src/presentation/config-store.ts +2 -2
- package/dist/extensions/pi-web-agent/src/search/tokenin.ts +14 -3
- package/dist/extensions/pi-zentui/README.md +17 -0
- package/dist/extensions/pi-zentui/assets/screenshots/footer-status-hyperlink.png +0 -0
- package/dist/extensions/pi-zentui/docs/configuration.md +71 -2
- package/dist/extensions/pi-zentui/extensions/zentui/config.ts +11 -0
- package/dist/extensions/pi-zentui/extensions/zentui/editor-transfer.ts +14 -0
- package/dist/extensions/pi-zentui/extensions/zentui/extension-status.ts +29 -13
- package/dist/extensions/pi-zentui/extensions/zentui/footer-layout.ts +5 -4
- package/dist/extensions/pi-zentui/extensions/zentui/footer-text.ts +11 -0
- package/dist/extensions/pi-zentui/extensions/zentui/footer.ts +11 -10
- package/dist/extensions/pi-zentui/extensions/zentui/index.ts +77 -3
- package/dist/extensions/pi-zentui/extensions/zentui/presets.ts +77 -0
- package/dist/extensions/pi-zentui/extensions/zentui/settings-command.ts +103 -2
- package/dist/extensions/pi-zentui/extensions/zentui/working-line-extension-segments.ts +115 -0
- package/dist/extensions/pi-zentui/extensions/zentui/working-line.ts +87 -5
- package/dist/extensions/pi-zentui/package-lock.json +277 -517
- package/dist/extensions/pi-zentui/package.json +7 -4
- package/dist/extensions/pi-zentui/test/config-presets.test.ts +238 -0
- package/dist/extensions/pi-zentui/test/editor-transfer.test.ts +24 -1
- package/dist/extensions/pi-zentui/test/extension-compliance.test.ts +570 -2
- package/dist/extensions/pi-zentui/test/extension-status.test.ts +90 -0
- package/dist/extensions/pi-zentui/test/footer-hyperlink.test.ts +243 -0
- package/dist/extensions/pi-zentui/test/package-contents.mjs +1 -0
- package/dist/extensions/pi-zentui/test/presets.test.ts +121 -0
- package/dist/extensions/pi-zentui/test/settings-command.test.ts +205 -1
- package/dist/extensions/pi-zentui/test/working-line-extension-segments.test.ts +139 -0
- package/dist/extensions/pi-zentui/test/working-line-lifecycle.integration.test.ts +237 -3
- package/dist/extensions/pi-zentui/test/working-line.test.ts +94 -2
- package/dist/index.d.ts +1 -1
- package/dist/main.js +4 -1
- package/dist/modes/interactive/chat-viewport.d.ts +19 -0
- package/dist/modes/interactive/chat-viewport.js +27 -0
- package/dist/modes/interactive/components/assistant-message.d.ts +6 -2
- package/dist/modes/interactive/components/assistant-message.js +30 -13
- package/dist/modes/interactive/components/custom-editor.d.ts +10 -1
- package/dist/modes/interactive/components/custom-editor.js +39 -1
- package/dist/modes/interactive/components/first-time-setup.js +1 -1
- package/dist/modes/interactive/components/index.d.ts +1 -1
- package/dist/modes/interactive/components/markdown-transform.d.ts +2 -0
- package/dist/modes/interactive/components/markdown-transform.js +18 -0
- package/dist/modes/interactive/components/model-selector.js +19 -17
- package/dist/modes/interactive/components/scoped-models-selector.js +21 -23
- package/dist/modes/interactive/components/settings-selector.d.ts +7 -1
- package/dist/modes/interactive/components/settings-selector.js +128 -20
- package/dist/modes/interactive/components/settings-submenu.d.ts +71 -0
- package/dist/modes/interactive/components/settings-submenu.js +164 -0
- package/dist/modes/interactive/components/status-indicator.d.ts +3 -1
- package/dist/modes/interactive/components/status-indicator.js +10 -3
- package/dist/modes/interactive/components/thinking-selector.d.ts +15 -3
- package/dist/modes/interactive/components/thinking-selector.js +75 -18
- package/dist/modes/interactive/components/tool-execution.d.ts +21 -4
- package/dist/modes/interactive/components/tool-execution.js +35 -33
- package/dist/modes/interactive/components/trust-selector.js +2 -2
- package/dist/modes/interactive/interactive-mode.d.ts +13 -15
- package/dist/modes/interactive/interactive-mode.js +144 -80
- package/dist/modes/interactive/session-share.d.ts +15 -0
- package/dist/modes/interactive/session-share.js +183 -0
- package/dist/modes/interactive/theme/dark.json +2 -1
- package/dist/modes/interactive/theme/light.json +2 -1
- package/dist/modes/interactive/theme/theme-controller.d.ts +1 -0
- package/dist/modes/interactive/theme/theme-controller.js +5 -0
- package/dist/modes/interactive/theme/theme-json.d.ts +83 -0
- package/dist/modes/interactive/theme/theme-json.js +129 -0
- package/dist/modes/interactive/theme/theme-schema.json +9 -1
- package/dist/modes/interactive/theme/theme.d.ts +14 -5
- package/dist/modes/interactive/theme/theme.js +18 -119
- package/dist/modes/interactive/tui-renderer.d.ts +20 -0
- package/dist/modes/interactive/tui-renderer.js +65 -0
- package/dist/utils/exif-orientation.js +2 -3
- package/dist/utils/management-http.d.ts +24 -0
- package/dist/utils/management-http.js +53 -0
- package/dist/utils/text.d.ts +7 -0
- package/dist/utils/text.js +8 -0
- package/dist/utils/tools-manager.d.ts +1 -0
- package/dist/utils/tools-manager.js +43 -21
- package/docs/docs.json +0 -4
- package/package.json +6 -6
- package/dist/extensions/pi-subagents/src/runs/shared/child-protocol.ts +0 -415
- package/dist/extensions/pi-subagents/src/runs/shared/pi-args.ts +0 -1059
- package/dist/extensions/pi-subagents/src/runs/shared/subagent-startup-retry.ts +0 -116
- package/dist/extensions/pi-subagents/src/shared/post-exit-stdio-guard.ts +0 -85
- package/dist/extensions/pi-subagents/test/e2e/real-session-subagent.test.ts +0 -224
- package/dist/extensions/pi-subagents/test/integration/async-execution.test.ts +0 -6986
- package/dist/extensions/pi-subagents/test/support/mock-pi-script.mjs +0 -447
- package/dist/extensions/pi-subagents/test/support/real-session-child-cli.mjs +0 -185
- package/dist/extensions/pi-subagents/test/support/real-session-runner.ts +0 -311
- package/dist/extensions/pi-subagents/test/unit/capability-ceiling-pi-args.test.ts +0 -84
- package/dist/extensions/pi-subagents/test/unit/child-protocol.test.ts +0 -202
- package/dist/extensions/pi-subagents/test/unit/close-grace-timer.test.ts +0 -101
- package/dist/extensions/pi-subagents/test/unit/pi-args.test.ts +0 -2347
- package/dist/extensions/pi-subagents/test/unit/subagent-startup-retry.test.ts +0 -104
- package/dist/extensions/pi-subagents/test/unit/windows-hide-spawn.test.ts +0 -49
- package/dist/extensions/web-agent-onboarding.test.ts +0 -415
- package/dist/extensions/web-agent-onboarding.ts +0 -222
- package/dist/skills/imagegen-frontend-mobile/SKILL.md +0 -1465
- package/dist/skills/imagegen-frontend-web/SKILL.md +0 -987
- package/dist/skills/implanger/SKILL.md +0 -70
- package/dist/skills/output/SKILL.md +0 -49
- package/dist/skills/planger/SKILL.md +0 -167
- package/dist/skills/workflow/SKILL.md +0 -95
- package/docs/workflows.md +0 -18
- /package/dist/bun/{register-bedrock.d.ts → runtime-setup.d.ts} +0 -0
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
/** Internal, opt-in factory evidence. No runner enables continuation through this module. */
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { lstatSync, readFileSync } from "node:fs";
|
|
4
|
+
import { resolve } from "node:path";
|
|
5
|
+
import { isDeepStrictEqual } from "node:util";
|
|
6
|
+
import type { AgentSession, SessionEntry, SessionHeader } from "@selesai/code";
|
|
7
|
+
import type { ChildSession, ChildSessionLaunch, PiCodingAgentModule } from "./child-session.ts";
|
|
8
|
+
import { captureReadonlyChildDrain, isReadonlyChildHookProfile, isReadonlyChildSessionReporting, observeReadonlyChildHookDrain } from "./child-hooks.ts";
|
|
9
|
+
|
|
10
|
+
type Runtime = Awaited<ReturnType<PiCodingAgentModule["ModelRuntime"]["create"]>>;
|
|
11
|
+
type Model = NonNullable<AgentSession["model"]>;
|
|
12
|
+
|
|
13
|
+
export interface SettledReadonlyEvidence {
|
|
14
|
+
readonly sessionFile: string;
|
|
15
|
+
readonly sessionId: string;
|
|
16
|
+
readonly leafId: string;
|
|
17
|
+
readonly provider: string;
|
|
18
|
+
readonly model: string;
|
|
19
|
+
readonly api: string;
|
|
20
|
+
readonly status: 429;
|
|
21
|
+
/** Complete active context, not the host's attempt-only event projection. */
|
|
22
|
+
readonly contextJson: string;
|
|
23
|
+
readonly completedToolResults: number;
|
|
24
|
+
readonly fileDigest: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const requested = new WeakMap<ChildSessionLaunch, SettledReadonlyEvidence | null>();
|
|
28
|
+
const receipts = new WeakMap<ChildSession, SettledReadonlyEvidence>();
|
|
29
|
+
// Opaque configured-provider continuity, never an implementation-origin attestation.
|
|
30
|
+
const providers = new WeakMap<SettledReadonlyEvidence, object>();
|
|
31
|
+
|
|
32
|
+
/** Internal integration seam: opt in before factory creation. Ordinary launches do no evidence I/O. */
|
|
33
|
+
export function requestReadonlySessionEvidence(launch: ChildSessionLaunch, expected?: SettledReadonlyEvidence): void {
|
|
34
|
+
requested.set(launch, expected ?? null);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Only the default factory can produce a receipt; duck-typed fake child properties are ignored. */
|
|
38
|
+
export function getReadonlySessionEvidence(child: ChildSession): SettledReadonlyEvidence | undefined {
|
|
39
|
+
return receipts.get(child);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function digest(bytes: string): string {
|
|
43
|
+
return createHash("sha256").update(bytes).digest("hex");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function absent(file: string): boolean {
|
|
47
|
+
try { lstatSync(file); return false; }
|
|
48
|
+
catch (error) { return (error as NodeJS.ErrnoException).code === "ENOENT"; }
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function sameStored(disk: unknown, live: unknown): boolean {
|
|
52
|
+
// The SDK keeps optional undefined fields in memory which JSONL intentionally omits.
|
|
53
|
+
return isDeepStrictEqual(disk, JSON.parse(JSON.stringify(live)));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Must run before opening a retained file. Never repairs, truncates, or creates it. */
|
|
57
|
+
export function validateReadonlySessionCheckpoint(evidence: SettledReadonlyEvidence): boolean {
|
|
58
|
+
if (!providers.has(evidence)) return false;
|
|
59
|
+
try { return digest(readFileSync(evidence.sessionFile, "utf8")) === evidence.fileDigest; }
|
|
60
|
+
catch { return false; }
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function readHistory(file: string): { header: SessionHeader; entries: SessionEntry[]; bytes: string } {
|
|
64
|
+
const bytes = readFileSync(file, "utf8");
|
|
65
|
+
if (!bytes.endsWith("\n")) throw new Error("Incomplete session file");
|
|
66
|
+
const rows = bytes.slice(0, -1).split("\n").map((line) => JSON.parse(line));
|
|
67
|
+
const [header, ...entries] = rows;
|
|
68
|
+
if (header?.type !== "session" || header.version !== 3 || typeof header.id !== "string" || !header.id || typeof header.cwd !== "string" || !entries.length) throw new Error("Unsupported session header");
|
|
69
|
+
const ids = new Set<string>();
|
|
70
|
+
for (const entry of entries) {
|
|
71
|
+
if (!entry || typeof entry.id !== "string" || !entry.id || ids.has(entry.id) || typeof entry.type !== "string" || typeof entry.timestamp !== "string" || (entry.parentId !== null && !ids.has(entry.parentId))) throw new Error("Broken session chain");
|
|
72
|
+
ids.add(entry.id);
|
|
73
|
+
}
|
|
74
|
+
return { header, entries, bytes };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function activeMessages(branch: SessionEntry[]): AgentSession["messages"] {
|
|
78
|
+
const messages = branch.flatMap((entry) => {
|
|
79
|
+
if (entry.type === "message") return [entry.message];
|
|
80
|
+
// Compaction/branch summaries and custom context need their own proof; do not reconstruct them.
|
|
81
|
+
if (!["model_change", "thinking_level_change", "session_info", "label"].includes(entry.type)) throw new Error("Unsupported active context");
|
|
82
|
+
return [];
|
|
83
|
+
});
|
|
84
|
+
// Snapshot the persisted representation, not mutable SDK message references.
|
|
85
|
+
return JSON.parse(JSON.stringify(messages));
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function completedResults(messages: AgentSession["messages"]): number {
|
|
89
|
+
const pending = new Map<string, string>();
|
|
90
|
+
const seen = new Set<string>();
|
|
91
|
+
let completed = 0;
|
|
92
|
+
for (const message of messages) {
|
|
93
|
+
if (message.role === "toolResult") {
|
|
94
|
+
if (typeof message.toolCallId !== "string" || !pending.has(message.toolCallId) || pending.get(message.toolCallId) !== message.toolName || !Array.isArray(message.content)) throw new Error("Unmatched tool result");
|
|
95
|
+
pending.delete(message.toolCallId);
|
|
96
|
+
if (!message.isError && message.content.length) completed++;
|
|
97
|
+
} else {
|
|
98
|
+
if (pending.size) throw new Error("Unresolved tool call");
|
|
99
|
+
if (message.role === "assistant") {
|
|
100
|
+
if (!Array.isArray(message.content)) throw new Error("Invalid assistant content");
|
|
101
|
+
for (const block of message.content) {
|
|
102
|
+
if (block.type !== "toolCall") continue;
|
|
103
|
+
if (!block.id || typeof block.id !== "string" || seen.has(block.id) || !["read", "ls"].includes(block.name)) throw new Error("Uncertified tool call");
|
|
104
|
+
seen.add(block.id);
|
|
105
|
+
pending.set(block.id, block.name);
|
|
106
|
+
}
|
|
107
|
+
} else if (message.role !== "user") throw new Error("Unsupported context message");
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
if (pending.size) throw new Error("Unresolved tool call");
|
|
111
|
+
return completed;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function eligibleLaunch(launch: ChildSessionLaunch): boolean {
|
|
115
|
+
const r = launch.runtime;
|
|
116
|
+
return launch.ambientExtensions === false && !launch.extensionPaths.length
|
|
117
|
+
&& isReadonlyChildSessionReporting(launch)
|
|
118
|
+
&& (!launch.hooks.length || (launch.storage.kind === "file" && isReadonlyChildHookProfile(launch.hooks, r)))
|
|
119
|
+
&& launch.tools !== undefined && launch.tools.every((tool) => tool === "read" || tool === "ls")
|
|
120
|
+
&& !r.toolBudget && !r.permissions && !r.childWatchdog && !r.watchdogStatus && !r.structuredOutput
|
|
121
|
+
&& !r.waitTool.enabled && !r.fanoutChild && !r.fast && !r.nestedRoute && !r.nestedParent && !r.runFanoutBudget
|
|
122
|
+
&& !r.supervisorChannelDir && !r.mcpDirectTools?.length;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export interface ReadonlyEvidenceObserver {
|
|
126
|
+
start(): void;
|
|
127
|
+
settled(): void;
|
|
128
|
+
invalidate(): void;
|
|
129
|
+
beforeShutdown(): void;
|
|
130
|
+
finish(child: ChildSession): void;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** Called only on the explicit opt-in path, before SessionManager.open can permissively repair input. */
|
|
134
|
+
export function prepareReadonlySessionEvidence(launch: ChildSessionLaunch): { loadingHooks(enabled: boolean): void; beforeOpen(): void; opened(manager: AgentSession["sessionManager"]): void; observe(pi: PiCodingAgentModule, runtime: Runtime, session: AgentSession): ReadonlyEvidenceObserver | undefined } | undefined {
|
|
135
|
+
if (!requested.has(launch)) return undefined;
|
|
136
|
+
const expected = requested.get(launch);
|
|
137
|
+
requested.delete(launch);
|
|
138
|
+
const deny = (): undefined => {
|
|
139
|
+
if (expected) throw new Error("Unsupported read-only continuation session");
|
|
140
|
+
return undefined;
|
|
141
|
+
};
|
|
142
|
+
const checkExpected = (): void => {
|
|
143
|
+
if (expected && (launch.storage.kind !== "file" || resolve(launch.storage.sessionFile) !== expected.sessionFile || !validateReadonlySessionCheckpoint(expected))) throw new Error("Read-only continuation checkpoint changed");
|
|
144
|
+
};
|
|
145
|
+
checkExpected();
|
|
146
|
+
if (!eligibleLaunch(launch) || launch.storage.kind !== "file") return deny();
|
|
147
|
+
const file = resolve(launch.storage.sessionFile);
|
|
148
|
+
// Only an initially absent *assigned exact file* may use SDK initialization.
|
|
149
|
+
// Empty files, dangling symlinks, inaccessible and corrupt inputs are not fresh.
|
|
150
|
+
let fresh = !expected && absent(file);
|
|
151
|
+
let initialHeader: SessionHeader | undefined;
|
|
152
|
+
try { if (!fresh) initialHeader = readHistory(file).header; }
|
|
153
|
+
catch { return deny(); }
|
|
154
|
+
const beforeOpen = (): void => {
|
|
155
|
+
checkExpected();
|
|
156
|
+
if (fresh) fresh = absent(file);
|
|
157
|
+
};
|
|
158
|
+
const opened = (manager: AgentSession["sessionManager"]): void => {
|
|
159
|
+
if (fresh && manager.getSessionFile() === file && manager.getEntries().length === 0 && manager.getLeafId() === null) {
|
|
160
|
+
// Capture the real SDK-generated identity immediately after open, before hooks.
|
|
161
|
+
initialHeader = JSON.parse(JSON.stringify(manager.getHeader()));
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
const observe = (pi: PiCodingAgentModule, runtime: Runtime, session: AgentSession): ReadonlyEvidenceObserver | undefined => {
|
|
165
|
+
const drainSettled = captureReadonlyChildDrain(launch.hooks);
|
|
166
|
+
// A deliberately tested capability floor, not an attestation of installed code origin.
|
|
167
|
+
if (!initialHeader || pi.VERSION !== "0.85.1" || !session.model || !session.agent.streamFunction) return deny();
|
|
168
|
+
const header = initialHeader;
|
|
169
|
+
const model = { ...session.model };
|
|
170
|
+
const provider = runtime.getProvider(model.provider);
|
|
171
|
+
if (expected && provider !== providers.get(expected)) return deny();
|
|
172
|
+
// Coverage is namespace/API plus the observed POST topology below, not builtin provider origin.
|
|
173
|
+
const supported = (m: Model): boolean => m.provider === "baseten" && m.api === "openai-completions"
|
|
174
|
+
&& runtime.getProvider(m.provider) === provider
|
|
175
|
+
&& !runtime.getRegisteredNativeProvider(m.provider) && !runtime.getRegisteredProviderConfig(m.provider);
|
|
176
|
+
const allowed = launch.tools!.filter((name) => !launch.excludeTools?.includes(name)).sort();
|
|
177
|
+
const toolsMatch = (): boolean => {
|
|
178
|
+
const tools = session.getAllTools();
|
|
179
|
+
return isDeepStrictEqual(session.getActiveToolNames().sort(), allowed)
|
|
180
|
+
&& isDeepStrictEqual(tools.map((tool) => tool.name).sort(), allowed)
|
|
181
|
+
&& tools.every((tool) => tool.sourceInfo?.source === "builtin");
|
|
182
|
+
};
|
|
183
|
+
const idle = (): boolean => session.isIdle && !session.isRetrying && !session.agent.hasQueuedMessages()
|
|
184
|
+
&& session.agent.state.pendingToolCalls.size === 0 && !session.hasPendingBashMessages;
|
|
185
|
+
const continuity = (): boolean => eligibleLaunch(launch) && toolsMatch() && session.model !== undefined
|
|
186
|
+
&& session.model.id === model.id && session.model.provider === model.provider && session.model.api === model.api && supported(session.model);
|
|
187
|
+
const history = () => {
|
|
188
|
+
const disk = readHistory(file);
|
|
189
|
+
const manager = session.sessionManager;
|
|
190
|
+
const leaf = manager.getLeafId();
|
|
191
|
+
if (session.sessionFile !== file || session.sessionId !== header.id || !leaf || leaf !== disk.entries.at(-1)?.id
|
|
192
|
+
|| !isDeepStrictEqual(disk.header, header) || !sameStored(disk.header, manager.getHeader())
|
|
193
|
+
|| !sameStored(disk.entries, manager.getEntries())) throw new Error("Session checkpoint mismatch");
|
|
194
|
+
// The disk chain and live entries already agree; use the SDK's raw branch walk.
|
|
195
|
+
const messages = activeMessages(manager.getBranch());
|
|
196
|
+
if (!sameStored(messages, session.messages)) throw new Error("Incomplete active context");
|
|
197
|
+
return { ...disk, messages, leaf, completed: completedResults(messages) };
|
|
198
|
+
};
|
|
199
|
+
const startingHistory = () => {
|
|
200
|
+
// SDK defers persistence until its first assistant response. This exception
|
|
201
|
+
// is for the empty source baseline only; settlement always reads strict disk history.
|
|
202
|
+
if (fresh && absent(file)) {
|
|
203
|
+
const manager = session.sessionManager;
|
|
204
|
+
if (session.sessionFile !== file || session.sessionId !== header.id || !sameStored(header, manager.getHeader())
|
|
205
|
+
|| session.messages.length
|
|
206
|
+
|| manager.getEntries().some((entry) => !["model_change", "thinking_level_change", "session_info", "label"].includes(entry.type))) throw new Error("Fresh session initialization changed");
|
|
207
|
+
return { messages: [] as AgentSession["messages"], completed: 0 };
|
|
208
|
+
}
|
|
209
|
+
return history();
|
|
210
|
+
};
|
|
211
|
+
if (!provider || !eligibleLaunch(launch) || !supported(model) || !toolsMatch() || !idle()) return deny();
|
|
212
|
+
try {
|
|
213
|
+
const restored = startingHistory();
|
|
214
|
+
if (expected && (model.provider !== expected.provider || JSON.stringify(restored.messages) !== expected.contextJson)) throw new Error("Restored continuation context changed");
|
|
215
|
+
} catch (error) {
|
|
216
|
+
if (expected) throw error;
|
|
217
|
+
return undefined;
|
|
218
|
+
}
|
|
219
|
+
let invalid = false;
|
|
220
|
+
let phase: "new" | "running" | "settled" = "new";
|
|
221
|
+
let owner: ChildSession | undefined;
|
|
222
|
+
let baseline = 0;
|
|
223
|
+
let before: AgentSession["messages"] = [];
|
|
224
|
+
let inFlight = 0;
|
|
225
|
+
type Invocation = { status?: number; pending: number; ambiguous: boolean; result?: Awaited<ReturnType<Awaited<ReturnType<typeof session.agent.streamFunction>>["result"]>> };
|
|
226
|
+
let latest: Invocation | undefined;
|
|
227
|
+
const original = session.agent.streamFunction;
|
|
228
|
+
const wrapped: typeof original = async (m, context, options) => {
|
|
229
|
+
const invocation: Invocation = { pending: 0, ambiguous: false };
|
|
230
|
+
latest = invocation;
|
|
231
|
+
if (inFlight++ || phase !== "running" || !eligibleLaunch(launch) || !supported(m) || m.id !== model.id || !toolsMatch()) invalid = true;
|
|
232
|
+
if (expected && (!continuity() || session.agent.streamFunction !== wrapped)) invalid = true;
|
|
233
|
+
// The repository's older agent-core types omit this documented 0.85.1 request option.
|
|
234
|
+
const transport = (options as (typeof options & { fetch?: typeof fetch }))?.fetch ?? globalThis.fetch;
|
|
235
|
+
const observedFetch: typeof fetch = async (...args) => {
|
|
236
|
+
invocation.status = undefined; // Starting even a rejected retry invalidates any earlier 429.
|
|
237
|
+
if (invocation.pending++ || invocation.result) invocation.ambiguous = true;
|
|
238
|
+
try {
|
|
239
|
+
try {
|
|
240
|
+
const [input, init] = args;
|
|
241
|
+
const url = new URL(input instanceof Request ? input.url : String(input));
|
|
242
|
+
// Only the tested completions POST topology. Radius /messages and auxiliary requests deny.
|
|
243
|
+
if (init?.method !== "POST" || !url.pathname.endsWith("/chat/completions") || typeof init.body !== "string") invocation.ambiguous = true;
|
|
244
|
+
} catch { invocation.ambiguous = true; }
|
|
245
|
+
const response = await transport(...args);
|
|
246
|
+
invocation.status = response.status;
|
|
247
|
+
return response;
|
|
248
|
+
} catch (error) {
|
|
249
|
+
invocation.status = undefined;
|
|
250
|
+
throw error;
|
|
251
|
+
} finally { invocation.pending--; }
|
|
252
|
+
};
|
|
253
|
+
try {
|
|
254
|
+
// Guarded continuations must veto known changes before entering configured SDK dispatch.
|
|
255
|
+
if (expected && invalid) throw new Error("Read-only continuation changed before dispatch");
|
|
256
|
+
const stream = await original.call(session.agent, m, context, { ...options, fetch: observedFetch });
|
|
257
|
+
// Observe result without consuming or replacing the event stream.
|
|
258
|
+
void stream.result().then((result) => {
|
|
259
|
+
invocation.result = result;
|
|
260
|
+
inFlight--;
|
|
261
|
+
}, () => { invalid = true; inFlight--; });
|
|
262
|
+
return stream;
|
|
263
|
+
} catch (error) { invalid = true; inFlight--; throw error; }
|
|
264
|
+
};
|
|
265
|
+
session.agent.streamFunction = wrapped;
|
|
266
|
+
return {
|
|
267
|
+
start() {
|
|
268
|
+
if (owner) receipts.delete(owner);
|
|
269
|
+
if (phase !== "new" || !idle()) invalid = true;
|
|
270
|
+
if (expected && (!continuity() || session.agent.streamFunction !== wrapped)) invalid = true;
|
|
271
|
+
phase = "running";
|
|
272
|
+
latest = undefined;
|
|
273
|
+
try {
|
|
274
|
+
const h = startingHistory(); baseline = h.completed; before = h.messages;
|
|
275
|
+
if (expected && JSON.stringify(h.messages) !== expected.contextJson) invalid = true;
|
|
276
|
+
} catch { invalid = true; }
|
|
277
|
+
if (expected && invalid) throw new Error("Read-only continuation changed before prompt");
|
|
278
|
+
},
|
|
279
|
+
settled() { phase = "settled"; },
|
|
280
|
+
invalidate() { invalid = true; if (owner) receipts.delete(owner); },
|
|
281
|
+
beforeShutdown() {
|
|
282
|
+
// Only the identity-certified prompt runtime may finalize owned acknowledgements.
|
|
283
|
+
if (!launch.hooks.length || !continuity()) invalid = true;
|
|
284
|
+
},
|
|
285
|
+
finish(child) {
|
|
286
|
+
owner = child;
|
|
287
|
+
if (!drainSettled()) return;
|
|
288
|
+
if (invalid || child.detached || child.shutDown || phase !== "settled" || inFlight || !eligibleLaunch(launch) || !idle() || !supported(model) || !toolsMatch() || session.agent.streamFunction !== wrapped
|
|
289
|
+
|| session.model?.id !== model.id || session.model.provider !== model.provider || session.model.api !== model.api) return;
|
|
290
|
+
const invocation = latest;
|
|
291
|
+
const terminal = invocation?.result;
|
|
292
|
+
if (!invocation || invocation.ambiguous || invocation.pending || invocation.status !== 429 || terminal?.stopReason !== "error"
|
|
293
|
+
|| terminal.content.length || terminal.provider !== model.provider || terminal.model !== model.id || terminal.api !== model.api) return;
|
|
294
|
+
try {
|
|
295
|
+
const h = history();
|
|
296
|
+
if (h.completed <= baseline || !isDeepStrictEqual(h.messages.slice(0, before.length), before) || !sameStored(h.messages.at(-1), terminal)) return;
|
|
297
|
+
const receipt: SettledReadonlyEvidence = Object.freeze({ sessionFile: file, sessionId: session.sessionId, leafId: h.leaf,
|
|
298
|
+
provider: model.provider, model: model.id, api: model.api, status: 429, contextJson: JSON.stringify(h.messages),
|
|
299
|
+
completedToolResults: h.completed, fileDigest: digest(h.bytes) });
|
|
300
|
+
providers.set(receipt, provider);
|
|
301
|
+
receipts.set(child, receipt);
|
|
302
|
+
} catch { /* Strict checkpoint failures only deny evidence; never repair storage. */ }
|
|
303
|
+
},
|
|
304
|
+
};
|
|
305
|
+
};
|
|
306
|
+
return { beforeOpen, opened, observe, loadingHooks: (enabled) => observeReadonlyChildHookDrain(launch.hooks, enabled, file) };
|
|
307
|
+
}
|
|
@@ -9,17 +9,16 @@ import {
|
|
|
9
9
|
type RunFanoutRejection,
|
|
10
10
|
} from "../../shared/types.ts";
|
|
11
11
|
|
|
12
|
-
export const RUN_FANOUT_BUDGET_ENV = "SELESAI_SUBAGENT_RUN_FANOUT_BUDGET";
|
|
13
12
|
const RUN_FANOUT_ROOT = path.join(TEMP_ROOT_DIR, "run-fanout-budgets");
|
|
14
13
|
|
|
15
|
-
interface
|
|
14
|
+
interface FanoutBudgetManifest {
|
|
16
15
|
version: 1;
|
|
17
16
|
rootRunId: string;
|
|
18
17
|
limit: number;
|
|
19
18
|
createdAt: number;
|
|
20
19
|
}
|
|
21
20
|
|
|
22
|
-
interface
|
|
21
|
+
interface FanoutBudgetClaim {
|
|
23
22
|
version: 1;
|
|
24
23
|
claimId: string;
|
|
25
24
|
path: string;
|
|
@@ -42,16 +41,16 @@ function safeRootRunId(rootRunId: string): string {
|
|
|
42
41
|
return rootRunId.replace(/[^A-Za-z0-9._-]/g, "_").slice(0, 120) || randomUUID();
|
|
43
42
|
}
|
|
44
43
|
|
|
45
|
-
function parseManifest(value: unknown):
|
|
44
|
+
function parseManifest(value: unknown): FanoutBudgetManifest | undefined {
|
|
46
45
|
if (!value || typeof value !== "object" || Array.isArray(value)) return undefined;
|
|
47
|
-
const manifest = value as Partial<
|
|
46
|
+
const manifest = value as Partial<FanoutBudgetManifest>;
|
|
48
47
|
if (manifest.version !== 1 || typeof manifest.rootRunId !== "string" || !manifest.rootRunId
|
|
49
48
|
|| !Number.isInteger(manifest.limit) || (manifest.limit ?? 0) <= 0
|
|
50
49
|
|| typeof manifest.createdAt !== "number" || !Number.isFinite(manifest.createdAt)) return undefined;
|
|
51
|
-
return manifest as
|
|
50
|
+
return manifest as FanoutBudgetManifest;
|
|
52
51
|
}
|
|
53
52
|
|
|
54
|
-
function readManifest(directory: string):
|
|
53
|
+
function readManifest(directory: string): FanoutBudgetManifest {
|
|
55
54
|
let parsed: unknown;
|
|
56
55
|
try {
|
|
57
56
|
parsed = JSON.parse(fs.readFileSync(path.join(directory, "manifest.json"), "utf-8"));
|
|
@@ -85,7 +84,7 @@ export function createRunFanoutBudget(rootRunId: string, limit: number): RunFano
|
|
|
85
84
|
do directory = path.join(RUN_FANOUT_ROOT, `${safeRootRunId(rootRunId)}-${randomUUID()}`);
|
|
86
85
|
while (fs.existsSync(directory));
|
|
87
86
|
fs.mkdirSync(path.join(directory, "claims"), { recursive: true, mode: 0o700 });
|
|
88
|
-
const manifest:
|
|
87
|
+
const manifest: FanoutBudgetManifest = { version: 1, rootRunId, limit, createdAt: Date.now() };
|
|
89
88
|
fs.writeFileSync(path.join(directory, "manifest.json"), `${JSON.stringify(manifest)}\n`, { mode: 0o600, flag: "wx" });
|
|
90
89
|
return { version: 1, rootRunId, directory, limit };
|
|
91
90
|
}
|
|
@@ -124,18 +123,6 @@ export function readRunFanoutBudgetDescriptor(asyncDir: string | undefined): Run
|
|
|
124
123
|
}
|
|
125
124
|
}
|
|
126
125
|
|
|
127
|
-
export function encodeRunFanoutBudgetDescriptor(descriptor: RunFanoutBudgetDescriptor): string {
|
|
128
|
-
return Buffer.from(JSON.stringify(validateRunFanoutBudgetDescriptor(descriptor)), "utf-8").toString("base64url");
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
export function decodeRunFanoutBudgetDescriptor(encoded: string | undefined): RunFanoutBudgetDescriptor | undefined {
|
|
132
|
-
if (!encoded) return undefined;
|
|
133
|
-
try {
|
|
134
|
-
return validateRunFanoutBudgetDescriptor(JSON.parse(Buffer.from(encoded, "base64url").toString("utf-8")));
|
|
135
|
-
} catch (error) {
|
|
136
|
-
throw new Error(`Invalid inherited run fan-out budget: ${error instanceof Error ? error.message : String(error)}`);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
126
|
|
|
140
127
|
interface AdmissionLockOwner {
|
|
141
128
|
pid: number;
|
|
@@ -243,7 +230,7 @@ function commitRunFanoutBatch<T>(descriptor: RunFanoutBudgetDescriptor, paths: s
|
|
|
243
230
|
const fd = fs.openSync(slotPath, "wx", 0o600);
|
|
244
231
|
created.push(slotPath);
|
|
245
232
|
try {
|
|
246
|
-
const claim:
|
|
233
|
+
const claim: FanoutBudgetClaim = { version: 1, claimId: randomUUID(), path: claimPath, claimedAt: Date.now() };
|
|
247
234
|
fs.writeFileSync(fd, `${JSON.stringify(claim)}\n`, "utf-8");
|
|
248
235
|
} finally { fs.closeSync(fd); }
|
|
249
236
|
break;
|
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import * as path from "node:path";
|
|
3
|
-
import type { RuntimeAcknowledgedChildExtensionsV1 } from "../../shared/types.ts";
|
|
1
|
+
import type { RuntimeAcknowledgedChildExtensions } from "../../shared/types.ts";
|
|
4
2
|
|
|
5
3
|
export const RUNTIME_EXTENSION_ACK_EVENT = "subagent:acknowledge-extension";
|
|
6
|
-
export const RUNTIME_EXTENSION_ACK_PATH_ENV = "SELESAI_SUBAGENT_RUNTIME_ACKNOWLEDGED_EXTENSIONS";
|
|
7
4
|
export const MAX_RUNTIME_ACKNOWLEDGED_EXTENSION_IDS = 32;
|
|
8
5
|
export const MAX_RUNTIME_ACKNOWLEDGED_EXTENSION_ID_LENGTH = 128;
|
|
9
|
-
// Generous bound for a valid capture (32 ids x 128 chars plus envelope); larger files are child misbehavior.
|
|
10
|
-
export const MAX_RUNTIME_ACKNOWLEDGED_EXTENSION_FILE_BYTES = 64 * 1024;
|
|
11
6
|
|
|
12
7
|
export function isRuntimeAcknowledgedExtensionId(value: unknown): value is string {
|
|
13
8
|
return typeof value === "string"
|
|
@@ -19,7 +14,7 @@ export function isRuntimeAcknowledgedExtensionId(value: unknown): value is strin
|
|
|
19
14
|
&& !value.includes("\\");
|
|
20
15
|
}
|
|
21
16
|
|
|
22
|
-
export function projectRuntimeAcknowledgedExtensions(ids: Iterable<unknown>):
|
|
17
|
+
export function projectRuntimeAcknowledgedExtensions(ids: Iterable<unknown>): RuntimeAcknowledgedChildExtensions | undefined {
|
|
23
18
|
const unique: string[] = [];
|
|
24
19
|
const seen = new Set<string>();
|
|
25
20
|
for (const id of ids) {
|
|
@@ -36,7 +31,7 @@ export function projectRuntimeAcknowledgedExtensions(ids: Iterable<unknown>): Ru
|
|
|
36
31
|
};
|
|
37
32
|
}
|
|
38
33
|
|
|
39
|
-
export function sanitizeRuntimeAcknowledgedExtensions(value: unknown):
|
|
34
|
+
export function sanitizeRuntimeAcknowledgedExtensions(value: unknown): RuntimeAcknowledgedChildExtensions | undefined {
|
|
40
35
|
if (!value || typeof value !== "object") return undefined;
|
|
41
36
|
const raw = value as Record<string, unknown>;
|
|
42
37
|
if (raw.version !== 1 || raw.source !== "child-runtime" || !Array.isArray(raw.ids)) return undefined;
|
|
@@ -47,25 +42,3 @@ export function sanitizeRuntimeAcknowledgedExtensions(value: unknown): RuntimeAc
|
|
|
47
42
|
: 0;
|
|
48
43
|
return { ...projected, omitted: projected.omitted + omitted };
|
|
49
44
|
}
|
|
50
|
-
|
|
51
|
-
export function readRuntimeAcknowledgedExtensions(filePath: string | undefined): RuntimeAcknowledgedChildExtensionsV1 | undefined {
|
|
52
|
-
if (!filePath) return undefined;
|
|
53
|
-
try {
|
|
54
|
-
if (fs.statSync(filePath).size > MAX_RUNTIME_ACKNOWLEDGED_EXTENSION_FILE_BYTES) return undefined;
|
|
55
|
-
const parsed = JSON.parse(fs.readFileSync(filePath, "utf-8")) as unknown;
|
|
56
|
-
return sanitizeRuntimeAcknowledgedExtensions(parsed);
|
|
57
|
-
} catch {
|
|
58
|
-
return undefined;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export function writeRuntimeAcknowledgedExtensions(filePath: string, ids: Iterable<unknown>): void {
|
|
63
|
-
const projection = projectRuntimeAcknowledgedExtensions(ids);
|
|
64
|
-
try {
|
|
65
|
-
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
66
|
-
if (projection) fs.writeFileSync(filePath, JSON.stringify(projection), { mode: 0o600 });
|
|
67
|
-
else fs.rmSync(filePath, { force: true });
|
|
68
|
-
} catch {
|
|
69
|
-
// Runtime acknowledgement is best-effort observability only.
|
|
70
|
-
}
|
|
71
|
-
}
|
|
@@ -7,10 +7,6 @@ import { SELESAI_CODING_AGENT_PACKAGE_ROOT_ENV } from "../../shared/utils.ts";
|
|
|
7
7
|
import type { JsonSchemaObject } from "../../shared/types.ts";
|
|
8
8
|
import type { ResolvedAcceptanceReportMode } from "./acceptance.ts";
|
|
9
9
|
|
|
10
|
-
export const STRUCTURED_OUTPUT_SCHEMA_ENV = "SELESAI_SUBAGENT_STRUCTURED_OUTPUT_SCHEMA";
|
|
11
|
-
export const STRUCTURED_OUTPUT_CAPTURE_ENV = "SELESAI_SUBAGENT_STRUCTURED_OUTPUT_CAPTURE";
|
|
12
|
-
export const STRUCTURED_OUTPUT_ACCEPTANCE_CAPTURE_ENV = "SELESAI_SUBAGENT_STRUCTURED_OUTPUT_ACCEPTANCE_CAPTURE";
|
|
13
|
-
export const STRUCTURED_OUTPUT_ACCEPTANCE_REQUIRED_ENV = "SELESAI_SUBAGENT_STRUCTURED_OUTPUT_ACCEPTANCE_REQUIRED";
|
|
14
10
|
export const MISSING_STRUCTURED_OUTPUT_CALL_ERROR = "Missing structured_output call; this step has outputSchema and must finish by calling structured_output.";
|
|
15
11
|
export const MISSING_STRUCTURED_ACCEPTANCE_REPORT_ERROR = "Missing acceptanceReport in structured_output call; acceptance.report is \"on\".";
|
|
16
12
|
|
|
@@ -200,6 +196,23 @@ export function readStructuredOutputAcceptanceReport(runtime: StructuredOutputRu
|
|
|
200
196
|
}
|
|
201
197
|
}
|
|
202
198
|
|
|
199
|
+
/**
|
|
200
|
+
* Capture callback that persists the structured output (and acceptance report)
|
|
201
|
+
* to the runtime's files, for hosts that read the value back from disk.
|
|
202
|
+
*/
|
|
203
|
+
export function createStructuredOutputFileCapture(runtime: StructuredOutputRuntime): (value: unknown, acceptanceReport: unknown | undefined) => void {
|
|
204
|
+
return (value, acceptanceReport) => {
|
|
205
|
+
fs.mkdirSync(path.dirname(runtime.outputPath), { recursive: true });
|
|
206
|
+
if (runtime.acceptanceReportPath && acceptanceReport !== undefined) {
|
|
207
|
+
fs.mkdirSync(path.dirname(runtime.acceptanceReportPath), { recursive: true });
|
|
208
|
+
fs.writeFileSync(runtime.acceptanceReportPath, JSON.stringify(acceptanceReport), { mode: 0o600 });
|
|
209
|
+
} else if (runtime.acceptanceReportPath && fs.existsSync(runtime.acceptanceReportPath)) {
|
|
210
|
+
fs.unlinkSync(runtime.acceptanceReportPath);
|
|
211
|
+
}
|
|
212
|
+
fs.writeFileSync(runtime.outputPath, JSON.stringify(value), { mode: 0o600 });
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
203
216
|
export function clearStructuredOutputCaptures(runtime: StructuredOutputRuntime): string | undefined {
|
|
204
217
|
let cleanupError: string | undefined;
|
|
205
218
|
for (const filePath of [runtime.outputPath, runtime.acceptanceReportPath]) {
|
|
@@ -138,6 +138,7 @@ export function buildControlEvent(input: {
|
|
|
138
138
|
tokens?: number;
|
|
139
139
|
toolCount?: number;
|
|
140
140
|
currentTool?: string;
|
|
141
|
+
toolCallId?: string;
|
|
141
142
|
currentToolDurationMs?: number;
|
|
142
143
|
currentPath?: string;
|
|
143
144
|
elapsedMs?: number;
|
|
@@ -170,6 +171,7 @@ export function buildControlEvent(input: {
|
|
|
170
171
|
...(input.tokens !== undefined ? { tokens: input.tokens } : {}),
|
|
171
172
|
...(input.toolCount !== undefined ? { toolCount: input.toolCount } : {}),
|
|
172
173
|
...(input.currentTool ? { currentTool: input.currentTool } : {}),
|
|
174
|
+
...(input.toolCallId ? { toolCallId: input.toolCallId } : {}),
|
|
173
175
|
...(input.currentToolDurationMs !== undefined ? { currentToolDurationMs: input.currentToolDurationMs } : {}),
|
|
174
176
|
...(input.currentPath ? { currentPath: input.currentPath } : {}),
|
|
175
177
|
...(elapsedMs !== undefined ? { elapsedMs } : {}),
|