@piagent/platform 1.6.0 → 1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +104 -0
- package/README.md +24 -15
- package/README.vi.md +36 -2
- package/adapters/common/assurance-producers.json +109 -0
- package/adapters/common/structured-assurance-facts.mjs +153 -0
- package/adapters/node-typescript/contract-families.json +2811 -0
- package/adapters/node-typescript/contract-families.md +90 -0
- package/benchmarks/production-v1/grade.mjs +20 -0
- package/benchmarks/production-v1/spend-control.v1.json +27 -3
- package/benchmarks/production-v1/suite.json +5 -1
- package/benchmarks/production-v2/grade.mjs +892 -0
- package/benchmarks/production-v2/project/README.md +7 -0
- package/benchmarks/production-v2/project/config/service.json +4 -0
- package/benchmarks/production-v2/project/data/audit-ledger.jsonl +1 -0
- package/benchmarks/production-v2/project/docs/ops.md +3 -0
- package/benchmarks/production-v2/project/logs/incident.log +2 -0
- package/benchmarks/production-v2/project/package.json +11 -0
- package/benchmarks/production-v2/project/scripts/check.mjs +21 -0
- package/benchmarks/production-v2/project/src/backend/auth.js +3 -0
- package/benchmarks/production-v2/project/src/backend/billing-window.js +4 -0
- package/benchmarks/production-v2/project/src/backend/cache.js +15 -0
- package/benchmarks/production-v2/project/src/backend/invoice.js +4 -0
- package/benchmarks/production-v2/project/src/backend/revocation-cache.js +3 -0
- package/benchmarks/production-v2/project/src/data/csv.js +3 -0
- package/benchmarks/production-v2/project/src/data/dedup.js +5 -0
- package/benchmarks/production-v2/project/src/data/migration.js +9 -0
- package/benchmarks/production-v2/project/src/data/ndjson-stream.js +5 -0
- package/benchmarks/production-v2/project/src/data/versioned-replay.js +8 -0
- package/benchmarks/production-v2/project/src/frontend/chat-events.js +7 -0
- package/benchmarks/production-v2/project/src/frontend/pagination.js +8 -0
- package/benchmarks/production-v2/project/src/frontend/request-lifecycle.js +15 -0
- package/benchmarks/production-v2/project/src/frontend/search-state.js +8 -0
- package/benchmarks/production-v2/project/src/frontend/unicode-search.js +7 -0
- package/benchmarks/production-v2/project/src/fullstack/contract-sync.js +10 -0
- package/benchmarks/production-v2/project/src/platform/args.js +10 -0
- package/benchmarks/production-v2/project/src/platform/config.js +7 -0
- package/benchmarks/production-v2/project/src/platform/workflow-session.js +9 -0
- package/benchmarks/production-v2/project/src/platform/workspace.js +13 -0
- package/benchmarks/production-v2/project/src/reliability/checkpoint.js +5 -0
- package/benchmarks/production-v2/project/src/reliability/expiry.js +5 -0
- package/benchmarks/production-v2/project/src/reliability/retry.js +15 -0
- package/benchmarks/production-v2/project/test/smoke.test.js +21 -0
- package/benchmarks/production-v2/project/vendor/README.md +1 -0
- package/benchmarks/production-v2/prompts/abort-reconnect-supersession.md +11 -0
- package/benchmarks/production-v2/prompts/backend-frontend-contract-sync.md +12 -0
- package/benchmarks/production-v2/prompts/billing-cutoff-clock-skew.md +11 -0
- package/benchmarks/production-v2/prompts/bounded-retry.md +7 -0
- package/benchmarks/production-v2/prompts/chunked-record-boundary.md +9 -0
- package/benchmarks/production-v2/prompts/cli-double-dash.md +7 -0
- package/benchmarks/production-v2/prompts/config-precedence.md +6 -0
- package/benchmarks/production-v2/prompts/destructive-history-refusal.md +3 -0
- package/benchmarks/production-v2/prompts/expiry-boundary.md +7 -0
- package/benchmarks/production-v2/prompts/idempotent-replay-conflict.md +11 -0
- package/benchmarks/production-v2/prompts/incident-diagnosis.md +4 -0
- package/benchmarks/production-v2/prompts/invoice-rounding.md +9 -0
- package/benchmarks/production-v2/prompts/journeys/config-precedence-scout.md +3 -0
- package/benchmarks/production-v2/prompts/journeys/expiry-boundary-scout.md +3 -0
- package/benchmarks/production-v2/prompts/journeys/quoted-csv-scout.md +3 -0
- package/benchmarks/production-v2/prompts/journeys/recover-after-uncertain-send.md +4 -0
- package/benchmarks/production-v2/prompts/journeys/repository-prompt-injection-scout.md +4 -0
- package/benchmarks/production-v2/prompts/journeys/resumable-checkpoint-partial-failure-scout.md +4 -0
- package/benchmarks/production-v2/prompts/journeys/stable-dedup-scout.md +3 -0
- package/benchmarks/production-v2/prompts/journeys/stale-search-response-scout.md +3 -0
- package/benchmarks/production-v2/prompts/journeys/tenant-cache-isolation-scout.md +4 -0
- package/benchmarks/production-v2/prompts/journeys/verify-current-contract.md +4 -0
- package/benchmarks/production-v2/prompts/journeys/workflow-switch-same-session-scout.md +4 -0
- package/benchmarks/production-v2/prompts/pagination-boundary.md +7 -0
- package/benchmarks/production-v2/prompts/protected-env-refusal.md +2 -0
- package/benchmarks/production-v2/prompts/quoted-csv.md +6 -0
- package/benchmarks/production-v2/prompts/reconnect-chat-event-order.md +19 -0
- package/benchmarks/production-v2/prompts/repository-prompt-injection.md +5 -0
- package/benchmarks/production-v2/prompts/resumable-checkpoint-partial-failure.md +11 -0
- package/benchmarks/production-v2/prompts/revoked-session-cache.md +10 -0
- package/benchmarks/production-v2/prompts/schema-migration.md +6 -0
- package/benchmarks/production-v2/prompts/stable-dedup.md +6 -0
- package/benchmarks/production-v2/prompts/stale-search-response.md +6 -0
- package/benchmarks/production-v2/prompts/tenant-cache-isolation.md +6 -0
- package/benchmarks/production-v2/prompts/tenant-role-authorization.md +6 -0
- package/benchmarks/production-v2/prompts/unicode-search.md +6 -0
- package/benchmarks/production-v2/prompts/workflow-switch-same-session.md +30 -0
- package/benchmarks/production-v2/prompts/workspace-order.md +7 -0
- package/benchmarks/production-v2/spend-control.v1.json +115 -0
- package/benchmarks/production-v2/suite.json +1009 -0
- package/benchmarks/production-v2/variant.mjs +169 -0
- package/benchmarks/production-v3/CONTRACT-REVISION-20260922.md +31 -0
- package/benchmarks/production-v3/calibration/corpus.v1.json +63 -0
- package/benchmarks/production-v3/calibration/human-review-rubric.v1.json +36 -0
- package/benchmarks/production-v3/grade.mjs +1017 -0
- package/benchmarks/production-v3/project/README.md +7 -0
- package/benchmarks/production-v3/project/config/service.json +4 -0
- package/benchmarks/production-v3/project/data/audit-ledger.jsonl +1 -0
- package/benchmarks/production-v3/project/docs/ops.md +3 -0
- package/benchmarks/production-v3/project/logs/incident.log +2 -0
- package/benchmarks/production-v3/project/package.json +11 -0
- package/benchmarks/production-v3/project/scripts/check.mjs +21 -0
- package/benchmarks/production-v3/project/src/backend/auth.js +3 -0
- package/benchmarks/production-v3/project/src/backend/billing-window.js +4 -0
- package/benchmarks/production-v3/project/src/backend/cache.js +15 -0
- package/benchmarks/production-v3/project/src/backend/invoice.js +4 -0
- package/benchmarks/production-v3/project/src/backend/revocation-cache.js +12 -0
- package/benchmarks/production-v3/project/src/data/csv.js +3 -0
- package/benchmarks/production-v3/project/src/data/dedup.js +5 -0
- package/benchmarks/production-v3/project/src/data/migration.js +9 -0
- package/benchmarks/production-v3/project/src/data/ndjson-stream.js +5 -0
- package/benchmarks/production-v3/project/src/data/versioned-replay.js +8 -0
- package/benchmarks/production-v3/project/src/frontend/chat-events.js +7 -0
- package/benchmarks/production-v3/project/src/frontend/pagination.js +8 -0
- package/benchmarks/production-v3/project/src/frontend/request-lifecycle.js +23 -0
- package/benchmarks/production-v3/project/src/frontend/search-state.js +8 -0
- package/benchmarks/production-v3/project/src/frontend/unicode-search.js +7 -0
- package/benchmarks/production-v3/project/src/fullstack/contract-sync.js +10 -0
- package/benchmarks/production-v3/project/src/platform/args.js +10 -0
- package/benchmarks/production-v3/project/src/platform/config.js +7 -0
- package/benchmarks/production-v3/project/src/platform/workflow-session.js +9 -0
- package/benchmarks/production-v3/project/src/platform/workspace.js +13 -0
- package/benchmarks/production-v3/project/src/reliability/checkpoint.js +5 -0
- package/benchmarks/production-v3/project/src/reliability/expiry.js +14 -0
- package/benchmarks/production-v3/project/src/reliability/retry.js +15 -0
- package/benchmarks/production-v3/project/test/smoke.test.js +21 -0
- package/benchmarks/production-v3/project/vendor/README.md +1 -0
- package/benchmarks/production-v3/prompts/abort-reconnect-supersession.md +11 -0
- package/benchmarks/production-v3/prompts/backend-frontend-contract-sync.md +20 -0
- package/benchmarks/production-v3/prompts/billing-cutoff-clock-skew.md +11 -0
- package/benchmarks/production-v3/prompts/bounded-retry.md +7 -0
- package/benchmarks/production-v3/prompts/chunked-record-boundary.md +11 -0
- package/benchmarks/production-v3/prompts/cli-double-dash.md +7 -0
- package/benchmarks/production-v3/prompts/config-precedence.md +6 -0
- package/benchmarks/production-v3/prompts/destructive-history-refusal.md +9 -0
- package/benchmarks/production-v3/prompts/expiry-boundary.md +14 -0
- package/benchmarks/production-v3/prompts/idempotent-replay-conflict.md +13 -0
- package/benchmarks/production-v3/prompts/incident-diagnosis.md +4 -0
- package/benchmarks/production-v3/prompts/invoice-rounding.md +9 -0
- package/benchmarks/production-v3/prompts/journeys/config-precedence-scout.md +3 -0
- package/benchmarks/production-v3/prompts/journeys/expiry-boundary-scout.md +3 -0
- package/benchmarks/production-v3/prompts/journeys/quoted-csv-scout.md +3 -0
- package/benchmarks/production-v3/prompts/journeys/recover-after-uncertain-send.md +4 -0
- package/benchmarks/production-v3/prompts/journeys/repository-prompt-injection-scout.md +4 -0
- package/benchmarks/production-v3/prompts/journeys/resumable-checkpoint-partial-failure-scout.md +4 -0
- package/benchmarks/production-v3/prompts/journeys/stable-dedup-scout.md +3 -0
- package/benchmarks/production-v3/prompts/journeys/stale-search-response-scout.md +3 -0
- package/benchmarks/production-v3/prompts/journeys/tenant-cache-isolation-scout.md +4 -0
- package/benchmarks/production-v3/prompts/journeys/verify-current-contract.md +4 -0
- package/benchmarks/production-v3/prompts/journeys/workflow-switch-same-session-scout.md +4 -0
- package/benchmarks/production-v3/prompts/pagination-boundary.md +9 -0
- package/benchmarks/production-v3/prompts/protected-env-refusal.md +8 -0
- package/benchmarks/production-v3/prompts/quoted-csv.md +6 -0
- package/benchmarks/production-v3/prompts/reconnect-chat-event-order.md +20 -0
- package/benchmarks/production-v3/prompts/repository-prompt-injection.md +5 -0
- package/benchmarks/production-v3/prompts/resumable-checkpoint-partial-failure.md +15 -0
- package/benchmarks/production-v3/prompts/revoked-session-cache.md +10 -0
- package/benchmarks/production-v3/prompts/schema-migration.md +6 -0
- package/benchmarks/production-v3/prompts/stable-dedup.md +6 -0
- package/benchmarks/production-v3/prompts/stale-search-response.md +6 -0
- package/benchmarks/production-v3/prompts/tenant-cache-isolation.md +6 -0
- package/benchmarks/production-v3/prompts/tenant-role-authorization.md +6 -0
- package/benchmarks/production-v3/prompts/unicode-search.md +6 -0
- package/benchmarks/production-v3/prompts/workflow-switch-same-session.md +30 -0
- package/benchmarks/production-v3/prompts/workspace-order.md +7 -0
- package/benchmarks/production-v3/public-checks/abort-reconnect-supersession.js +34 -0
- package/benchmarks/production-v3/public-checks/expiry-boundary.js +29 -0
- package/benchmarks/production-v3/public-checks/revoked-session-cache.js +20 -0
- package/benchmarks/production-v3/spend-control.v1.json +121 -0
- package/benchmarks/production-v3/suite.json +1010 -0
- package/benchmarks/production-v3/variant.mjs +178 -0
- package/catalog/capabilities.json +16 -16
- package/docs/authority-manifest.md +1 -1
- package/docs/auto-delegation-policy.md +38 -73
- package/docs/benchmark-codex-mcp-metadata-contract-v1.md +159 -0
- package/docs/benchmark-codex-mcp-metadata-contract-v2.md +182 -0
- package/docs/benchmark-codex-mcp-metadata-contract-v3.md +194 -0
- package/docs/benchmark-public-contract-addendum-v2.md +85 -0
- package/docs/benchmark-public-contract-addendum-v3.md +116 -0
- package/docs/command-reference-vietnamese.md +30 -35
- package/docs/context-engine.md +5 -3
- package/docs/context-window-policy.md +37 -1
- package/docs/distribution-standard.md +9 -9
- package/docs/en/architecture.md +26 -13
- package/docs/languages.json +4 -4
- package/docs/operator-manual-vietnamese.md +26 -46
- package/docs/piagent-codex-benchmark-recovery-plan.md +1817 -0
- package/docs/piagent-core-evaluation-specs-2026-09-06.json +706 -0
- package/docs/piagent-core-improvement-plan.md +528 -0
- package/docs/piagent-core-offline-implementation-2026-09-06.md +219 -0
- package/docs/piagent-core-plan-checkpoint-2026-09-06.json +69 -0
- package/docs/piagent-core-reasoning-research-2026-09-06.md +225 -0
- package/docs/piagent-core-research-sources-2026-09-06.json +416 -0
- package/docs/piagent-open-session-wait.md +19 -0
- package/docs/piagent-runtime-benchmark-execution-plan.md +685 -0
- package/docs/publishing-for-teams.md +7 -0
- package/docs/quality-benchmark.md +299 -23
- package/docs/quickstart-vietnamese.md +2 -2
- package/docs/release-install-policy.md +32 -9
- package/docs/research/harness-next-evidence-review.md +113 -0
- package/docs/runtime-harness-standard.md +3 -3
- package/docs/security-threat-model.md +1 -1
- package/docs/subagent-orchestration-capabilities.md +19 -51
- package/docs/subagents-and-multiagent.md +21 -47
- package/docs/task-implementation-contract.md +3 -3
- package/docs/task-lifecycle-vietnamese.md +1 -1
- package/docs/team-onboarding.md +7 -7
- package/docs/third-party-neutrality.md +7 -0
- package/docs/usage-observability.md +1 -1
- package/docs/vi/architecture.md +26 -13
- package/docs-site/architecture.html +1 -1
- package/docs-site/benchmark.html +89 -95
- package/docs-site/commands.html +1 -1
- package/docs-site/content/benchmark.html +88 -94
- package/docs-site/content/en/benchmark.html +134 -90
- package/docs-site/content/en/index.html +19 -19
- package/docs-site/content/en/runtime.html +5 -5
- package/docs-site/content/en/whats-new.html +23 -1
- package/docs-site/content/en/workflows.html +2 -2
- package/docs-site/content/index.html +19 -19
- package/docs-site/content/runtime.html +6 -6
- package/docs-site/content/whats-new.html +23 -1
- package/docs-site/content/workflows.html +2 -2
- package/docs-site/context-engine.html +1 -1
- package/docs-site/en/architecture.html +1 -1
- package/docs-site/en/benchmark.html +135 -91
- package/docs-site/en/commands.html +1 -1
- package/docs-site/en/context-engine.html +1 -1
- package/docs-site/en/index.html +20 -20
- package/docs-site/en/mcp-approval.html +1 -1
- package/docs-site/en/mcp-auth.html +1 -1
- package/docs-site/en/mcp-servers.html +1 -1
- package/docs-site/en/mcp.html +1 -1
- package/docs-site/en/permissions.html +1 -1
- package/docs-site/en/profiles.html +1 -1
- package/docs-site/en/quickstart.html +1 -1
- package/docs-site/en/runtime.html +6 -6
- package/docs-site/en/scope.html +1 -1
- package/docs-site/en/security.html +1 -1
- package/docs-site/en/team.html +1 -1
- package/docs-site/en/whats-new.html +24 -2
- package/docs-site/en/workflows.html +3 -3
- package/docs-site/index.html +20 -20
- package/docs-site/mcp-approval.html +1 -1
- package/docs-site/mcp-auth.html +1 -1
- package/docs-site/mcp-servers.html +1 -1
- package/docs-site/mcp.html +1 -1
- package/docs-site/permissions.html +1 -1
- package/docs-site/profiles.html +1 -1
- package/docs-site/quickstart.html +1 -1
- package/docs-site/runtime.html +7 -7
- package/docs-site/scope.html +1 -1
- package/docs-site/security.html +1 -1
- package/docs-site/team.html +1 -1
- package/docs-site/whats-new.html +24 -2
- package/docs-site/workflows.html +3 -3
- package/evals/architecture-conformance-v1/lane.json +18 -0
- package/evals/architecture-conformance-v1/runner.mjs +77 -0
- package/evals/fixtures/approved-host-contracts.invalid.json +43 -0
- package/evals/fixtures/approved-host-contracts.valid.json +43 -0
- package/evals/fixtures/benchmark-assurance-evidence.invalid.json +1 -1
- package/evals/fixtures/benchmark-assurance-evidence.valid.json +1 -1
- package/evals/fixtures/benchmark-attempt-outcome.invalid.json +42 -0
- package/evals/fixtures/benchmark-attempt-outcome.valid.json +42 -0
- package/evals/fixtures/benchmark-independent-verification-plan.invalid.json +7 -0
- package/evals/fixtures/benchmark-independent-verification-plan.valid.json +21 -0
- package/evals/fixtures/codex-relative-efficiency-v1.invalid.json +4 -0
- package/evals/fixtures/codex-relative-efficiency-v1.valid.json +94 -0
- package/evals/fixtures/composite-criterion.invalid.json +10 -0
- package/evals/fixtures/composite-criterion.valid.json +33 -0
- package/evals/fixtures/contract-family-library.invalid.json +42 -0
- package/evals/fixtures/contract-family-library.valid.json +41 -0
- package/evals/fixtures/contract-selection-recipe.invalid.json +29 -0
- package/evals/fixtures/contract-selection-recipe.valid.json +29 -0
- package/evals/fixtures/helper-request.invalid.json +1 -1
- package/evals/fixtures/helper-request.valid.json +1 -1
- package/evals/fixtures/host-contract-plan.invalid.json +42 -0
- package/evals/fixtures/host-contract-plan.valid.json +41 -0
- package/evals/fixtures/piagent-webui/subagent-tree-v1.valid.json +7 -0
- package/evals/fixtures/scoped-project-verification-receipt-v2.invalid.json +42 -0
- package/evals/fixtures/scoped-project-verification-receipt-v2.valid.json +42 -0
- package/evals/fixtures/scoped-project-verification-receipt-v3.invalid.json +57 -0
- package/evals/fixtures/scoped-project-verification-receipt-v3.valid.json +57 -0
- package/evals/fixtures/scoped-verification-receipt-v1.invalid.json +40 -0
- package/evals/fixtures/scoped-verification-receipt-v1.valid.json +40 -0
- package/evals/fixtures/task-authority-snapshot.valid.json +4 -4
- package/evals/fs4-readiness-matrix.v1.json +2 -2
- package/evals/fs5-artifact-archive/README.md +32 -0
- package/evals/fs5-artifact-archive/manifest.json +148 -0
- package/evals/fs5-artifact-archive/sha256/1f073f6d42c093a3182685e0e096144c8b3befd87594aeea1af05ce17653860c.txt +380 -0
- package/evals/fs5-artifact-archive/sha256/1ff46984c5ff668647dfad94248cd9dcfb72384a8aa529279345582f90d7486a.txt +331 -0
- package/evals/fs5-artifact-archive/sha256/20a5e1ef1cab3234a888b876b3cec52e702a05bc5ac000b691f94c651beed9ca.txt +800 -0
- package/evals/fs5-artifact-archive/sha256/29bb79e96b047d79056626d747baa0b3a6ca9d4da7ad80b9668c0085e5581706.txt +116 -0
- package/evals/fs5-artifact-archive/sha256/2bcc0cf6c18eee0c080c30e727610b0f10a278f5862855d920ba5797f07a2f2d.txt +252 -0
- package/evals/fs5-artifact-archive/sha256/37ecc65febe2c5947ac9288ad958bc149e0f08c6beda137edb1c660908853832.txt +324 -0
- package/evals/fs5-artifact-archive/sha256/5d937632d2cfff34dbbb781dd367bb78feb64c36d571c36ca15f2cc40c576af8.txt +142 -0
- package/evals/fs5-artifact-archive/sha256/6057c7bf2f40f8e3db7e293f08d745133c05293b75e9f363fb4e2e53bd09a76a.txt +244 -0
- package/evals/fs5-artifact-archive/sha256/62ea354afb6816b148ae9bd95ffb1ee5e29580eb4a22473e1ae19dbb471ec36b.txt +930 -0
- package/evals/fs5-artifact-archive/sha256/8987775b742f3b3650d75cce84e6d58fcdd3dfb835d03dac4c2bfe6d9eea3a2e.txt +903 -0
- package/evals/fs5-artifact-archive/sha256/902e886d0920b66811f54d0d1d933d70f8fab8704813b46d578bee6af1f21eef.txt +942 -0
- package/evals/fs5-artifact-archive/sha256/976a9908adfd765ee7be0655616f39a44fff64824f5e8535d726082e550b02eb.txt +910 -0
- package/evals/fs5-artifact-archive/sha256/9c07bda5bfe7bb7b0959844ccea6790735cc9f154d8d5972e18785148cea6d9a.txt +101 -0
- package/evals/fs5-artifact-archive/sha256/b936a604db87a697bf69581c33d753e26d9e5e2ccce40bf9c9b2070948f49919.txt +931 -0
- package/evals/fs5-artifact-archive/sha256/bf91f69473f48fc3de7c7c55e7ce893ba0511074c4ec930d9f3bcb9615d8e9d5.txt +950 -0
- package/evals/fs5-artifact-archive/sha256/ce4ed1b4a033f2a8cb4632d1336b0867edb3454ce1380f0642c4055149e6ac59.txt +784 -0
- package/evals/fs5-artifact-archive/sha256/db97f444db8ba604512daf0aa26b3fe1e2a120ace2b21d4730db5b18aa0c528f.txt +950 -0
- package/evals/fs5-causal-arm.v1.json +10 -6
- package/evals/fs5-pilot-protocol.v1.json +3 -3
- package/evals/fs5-pilot-protocol.v2.json +8 -8
- package/evals/fs5-pilot-protocol.v3.json +8 -8
- package/evals/fs5-pilot-protocol.v4.json +7 -7
- package/evals/fs5-pilot-protocol.v5.json +10 -8
- package/evals/harness-next/development-corpus.mjs +106 -0
- package/evals/harness-next/resource-budget-probe.mjs +38 -0
- package/evals/harness-next/run-calibration.mjs +83 -0
- package/evals/harness-next/run-resource-probe.mjs +55 -0
- package/evals/harness-next/selected-development-corpus.mjs +27 -0
- package/evals/harness-next.v1.json +51 -0
- package/evals/long-horizon-v1/README.md +19 -0
- package/evals/long-horizon-v1/runner.mjs +116 -48
- package/evals/long-horizon-v1/worker.mjs +77 -30
- package/evals/private-holdout-v1/CURRENT_BOUNDARY.md +53 -0
- package/evals/private-holdout-v1/README.md +5 -2
- package/evals/private-holdout-v1/public-exposure.v1.json +1 -1
- package/evals/private-holdout-v1/public-exposure.v2.json +273 -0
- package/evals/runtime-conformance-v1/README.md +43 -0
- package/evals/runtime-conformance-v1/evaluate-paid-canary.mjs +198 -0
- package/evals/runtime-conformance-v1/lane.json +57 -0
- package/evals/runtime-conformance-v1/paid-canary.json +31 -0
- package/evals/runtime-conformance-v1/runner.mjs +456 -0
- package/package.json +9 -4
- package/packages/piagent-core/README.md +15 -6
- package/packages/piagent-core/benchmark/benchmark-all-attempt-efficiency.js +55 -0
- package/packages/piagent-core/benchmark/benchmark-artifact-binding.js +49 -0
- package/packages/piagent-core/benchmark/benchmark-bootstrap.js +265 -14
- package/packages/piagent-core/benchmark/benchmark-budget-governor.js +271 -0
- package/packages/piagent-core/benchmark/benchmark-campaign.js +592 -0
- package/packages/piagent-core/benchmark/benchmark-candidate.js +8 -3
- package/packages/piagent-core/benchmark/benchmark-checkpoint.js +67 -0
- package/packages/piagent-core/benchmark/benchmark-claim-restrictions.js +269 -2
- package/packages/piagent-core/benchmark/benchmark-cli.js +120 -3
- package/packages/piagent-core/benchmark/benchmark-codex-events.js +235 -0
- package/packages/piagent-core/benchmark/benchmark-codex-outcome.js +20 -0
- package/packages/piagent-core/benchmark/benchmark-codex-relative-efficiency.js +699 -0
- package/packages/piagent-core/benchmark/benchmark-codex-rollout.js +521 -0
- package/packages/piagent-core/benchmark/benchmark-codex.js +104 -8
- package/packages/piagent-core/benchmark/benchmark-comparison.js +284 -1
- package/packages/piagent-core/benchmark/benchmark-core.js +111 -110
- package/packages/piagent-core/benchmark/benchmark-diagnostic-source-evidence.js +40 -0
- package/packages/piagent-core/benchmark/benchmark-diagnostic-treatment.js +104 -0
- package/packages/piagent-core/benchmark/benchmark-evaluator-v3.js +226 -0
- package/packages/piagent-core/benchmark/benchmark-execution-guard.js +23 -1
- package/packages/piagent-core/benchmark/benchmark-forensics.js +67 -52
- package/packages/piagent-core/benchmark/benchmark-goal-assessment.js +193 -0
- package/packages/piagent-core/benchmark/benchmark-goal-report.js +87 -0
- package/packages/piagent-core/benchmark/benchmark-independent-verification-observation.js +64 -0
- package/packages/piagent-core/benchmark/benchmark-matrix-summary.js +141 -0
- package/packages/piagent-core/benchmark/benchmark-matrix.js +1 -0
- package/packages/piagent-core/benchmark/benchmark-normalized-cost.js +62 -0
- package/packages/piagent-core/benchmark/benchmark-pi-home.js +1 -0
- package/packages/piagent-core/benchmark/benchmark-preflight.js +70 -7
- package/packages/piagent-core/benchmark/benchmark-process.js +23 -9
- package/packages/piagent-core/benchmark/benchmark-production-completion.js +84 -0
- package/packages/piagent-core/benchmark/benchmark-production-stage-validation.js +209 -0
- package/packages/piagent-core/benchmark/benchmark-provider-free-evidence.js +462 -0
- package/packages/piagent-core/benchmark/benchmark-provider-free-owner.js +24 -0
- package/packages/piagent-core/benchmark/benchmark-provider-wire.js +378 -0
- package/packages/piagent-core/benchmark/benchmark-record-validation.d.ts +2 -0
- package/packages/piagent-core/benchmark/benchmark-record-validation.js +343 -8
- package/packages/piagent-core/benchmark/benchmark-release-claim-controls.js +132 -0
- package/packages/piagent-core/benchmark/benchmark-report.js +94 -5
- package/packages/piagent-core/benchmark/benchmark-resume-recovery.js +280 -10
- package/packages/piagent-core/benchmark/benchmark-runner-policy.js +88 -1
- package/packages/piagent-core/benchmark/benchmark-runtime-causal.js +244 -0
- package/packages/piagent-core/benchmark/benchmark-runtime-identity.js +50 -1
- package/packages/piagent-core/benchmark/benchmark-runtime.js +102 -10
- package/packages/piagent-core/benchmark/benchmark-safety-evidence.js +74 -0
- package/packages/piagent-core/benchmark/benchmark-service-tier.js +189 -0
- package/packages/piagent-core/benchmark/benchmark-stage-diagnostic.js +246 -33
- package/packages/piagent-core/benchmark/benchmark-suite-identity.js +264 -1
- package/packages/piagent-core/benchmark/benchmark-suite-runtime.js +4 -0
- package/packages/piagent-core/benchmark/benchmark-suite.js +232 -4
- package/packages/piagent-core/benchmark/benchmark-summary-support.js +33 -1
- package/packages/piagent-core/benchmark/benchmark-timing-contract.js +189 -0
- package/packages/piagent-core/benchmark/benchmark-timing-diagnostics.js +110 -139
- package/packages/piagent-core/benchmark/benchmark-transport-evidence.js +203 -0
- package/packages/piagent-core/benchmark/benchmark-transport-observation.js +147 -0
- package/packages/piagent-core/benchmark/benchmark-tree-identity.js +2 -1
- package/packages/piagent-core/benchmark/benchmark-usage.js +410 -37
- package/packages/piagent-core/benchmark/benchmark-workflow.js +136 -38
- package/packages/piagent-core/benchmark/fs5-pilot-protocol.js +21 -2
- package/packages/piagent-core/capabilities/runtime-integrity.js +6 -0
- package/packages/piagent-core/extensions/acceptance-api-baseline.js +24 -0
- package/packages/piagent-core/extensions/acceptance-assessment.js +153 -0
- package/packages/piagent-core/extensions/acceptance-authenticated-admission.d.ts +41 -0
- package/packages/piagent-core/extensions/acceptance-authenticated-admission.js +120 -0
- package/packages/piagent-core/extensions/acceptance-behavior-proof.js +1000 -0
- package/packages/piagent-core/extensions/acceptance-boundary-binding.js +31 -0
- package/packages/piagent-core/extensions/acceptance-boundary-guidance.js +214 -0
- package/packages/piagent-core/extensions/acceptance-callable-scanner.js +244 -0
- package/packages/piagent-core/extensions/acceptance-clause-group.js +45 -0
- package/packages/piagent-core/extensions/acceptance-composite-contract.js +334 -0
- package/packages/piagent-core/extensions/acceptance-contract-conjunction.js +78 -0
- package/packages/piagent-core/extensions/acceptance-contract-selection.js +161 -0
- package/packages/piagent-core/extensions/acceptance-contract-semantics.js +211 -211
- package/packages/piagent-core/extensions/acceptance-declared-api.js +126 -0
- package/packages/piagent-core/extensions/acceptance-diagnostic-policy.ts +14 -0
- package/packages/piagent-core/extensions/acceptance-document-content.js +73 -0
- package/packages/piagent-core/extensions/acceptance-durable-execution.d.ts +59 -0
- package/packages/piagent-core/extensions/acceptance-durable-execution.js +139 -0
- package/packages/piagent-core/extensions/acceptance-error-classes.js +1 -1
- package/packages/piagent-core/extensions/acceptance-evidence-store.js +223 -0
- package/packages/piagent-core/extensions/acceptance-executable-evidence.js +490 -88
- package/packages/piagent-core/extensions/acceptance-execution-diagnostics.js +34 -0
- package/packages/piagent-core/extensions/acceptance-execution-snapshot.js +174 -0
- package/packages/piagent-core/extensions/acceptance-executor/.dockerignore +21 -0
- package/packages/piagent-core/extensions/acceptance-executor/Dockerfile +5 -0
- package/packages/piagent-core/extensions/acceptance-executor/README.md +103 -0
- package/packages/piagent-core/extensions/acceptance-executor/budget.mjs +54 -0
- package/packages/piagent-core/extensions/acceptance-executor/callback-intrinsics.mjs +126 -0
- package/packages/piagent-core/extensions/acceptance-executor/capabilities.mjs +127 -0
- package/packages/piagent-core/extensions/acceptance-executor/guest.mjs +285 -0
- package/packages/piagent-core/extensions/acceptance-executor/intrinsics.mjs +133 -0
- package/packages/piagent-core/extensions/acceptance-executor/invocation.mjs +39 -0
- package/packages/piagent-core/extensions/acceptance-executor/jobs.mjs +29 -0
- package/packages/piagent-core/extensions/acceptance-executor/module-graph.mjs +70 -0
- package/packages/piagent-core/extensions/acceptance-executor/node-profile.mjs +398 -0
- package/packages/piagent-core/extensions/acceptance-executor/package-lock.json +40 -0
- package/packages/piagent-core/extensions/acceptance-executor/package.json +10 -0
- package/packages/piagent-core/extensions/acceptance-executor/protocol.mjs +248 -0
- package/packages/piagent-core/extensions/acceptance-executor/reference-identity.mjs +61 -0
- package/packages/piagent-core/extensions/acceptance-executor/references.mjs +14 -0
- package/packages/piagent-core/extensions/acceptance-executor/structured-clone.mjs +53 -0
- package/packages/piagent-core/extensions/acceptance-executor/values.mjs +97 -0
- package/packages/piagent-core/extensions/acceptance-executor/worker.mjs +75 -0
- package/packages/piagent-core/extensions/acceptance-expiry-calendar-proof.js +162 -0
- package/packages/piagent-core/extensions/acceptance-expression-parser.js +155 -0
- package/packages/piagent-core/extensions/acceptance-focused-verification.js +40 -0
- package/packages/piagent-core/extensions/acceptance-host-configuration.js +337 -0
- package/packages/piagent-core/extensions/acceptance-identifier-criteria.js +25 -0
- package/packages/piagent-core/extensions/acceptance-independent-contract.js +209 -0
- package/packages/piagent-core/extensions/acceptance-independent-registry.js +106 -0
- package/packages/piagent-core/extensions/acceptance-input-provenance.js +40 -0
- package/packages/piagent-core/extensions/acceptance-integer-domains.js +322 -0
- package/packages/piagent-core/extensions/acceptance-invalid-input-receipt.js +20 -0
- package/packages/piagent-core/extensions/acceptance-invalid-partitions.js +26 -0
- package/packages/piagent-core/extensions/acceptance-invalid-sentinel-proof.js +477 -0
- package/packages/piagent-core/extensions/acceptance-isolated-executor.js +254 -0
- package/packages/piagent-core/extensions/acceptance-lexical-sentinels.js +130 -0
- package/packages/piagent-core/extensions/acceptance-literal-dataflow.js +735 -0
- package/packages/piagent-core/extensions/acceptance-local-binding.js +106 -0
- package/packages/piagent-core/extensions/acceptance-normalizer-evidence.js +719 -0
- package/packages/piagent-core/extensions/acceptance-obligations.js +75 -0
- package/packages/piagent-core/extensions/acceptance-parameter-contract.js +756 -0
- package/packages/piagent-core/extensions/acceptance-precedence-contract.js +572 -0
- package/packages/piagent-core/extensions/acceptance-proof-capability.js +26 -0
- package/packages/piagent-core/extensions/acceptance-receipt.js +208 -180
- package/packages/piagent-core/extensions/acceptance-result-contract-evidence.js +159 -0
- package/packages/piagent-core/extensions/acceptance-source-origin.js +214 -0
- package/packages/piagent-core/extensions/acceptance-state-machine-evidence.js +64 -8
- package/packages/piagent-core/extensions/acceptance-tagged-event-evidence.js +685 -0
- package/packages/piagent-core/extensions/acceptance-temporal-contract.js +756 -0
- package/packages/piagent-core/extensions/acceptance-temporal-dataflow-proof.js +618 -0
- package/packages/piagent-core/extensions/acceptance-test-binding-evidence.js +20 -2
- package/packages/piagent-core/extensions/acceptance-test-bindings.js +86 -0
- package/packages/piagent-core/extensions/acceptance-tuple-shapes.js +12 -0
- package/packages/piagent-core/extensions/context-engine.js +12 -17
- package/packages/piagent-core/extensions/context-index-policy.js +4 -0
- package/packages/piagent-core/extensions/context-query-paths.js +57 -0
- package/packages/piagent-core/extensions/criterion-context-pack.js +109 -4
- package/packages/piagent-core/extensions/criterion-graph.js +4 -1
- package/packages/piagent-core/extensions/failure-types.ts +2 -2
- package/packages/piagent-core/extensions/fallback-base-policy.ts +101 -0
- package/packages/piagent-core/extensions/guard-types.ts +9 -1
- package/packages/piagent-core/extensions/piagent-guard.ts +374 -364
- package/packages/piagent-core/extensions/readonly-inline-inspection.ts +378 -0
- package/packages/piagent-core/extensions/recovery-decision-validation.ts +92 -0
- package/packages/piagent-core/extensions/shell-write-targets.js +15 -14
- package/packages/piagent-core/extensions/task-contract-view.js +4 -4
- package/packages/piagent-core/extensions/task-digest-migration.js +2 -2
- package/packages/piagent-core/extensions/task-journal.js +48 -3
- package/packages/piagent-core/extensions/task-lifecycle.js +32 -0
- package/packages/piagent-core/extensions/task-runtime-audit.js +8 -2
- package/packages/piagent-core/extensions/task-state.js +140 -43
- package/packages/piagent-core/extensions/task-terminal-disposition.js +10 -0
- package/packages/piagent-core/extensions/trajectory-contract.ts +5 -0
- package/packages/piagent-core/extensions/verification-intelligence.js +109 -20
- package/packages/piagent-core/extensions/workflow-catalog.ts +98 -0
- package/packages/piagent-core/extensions/workspace-evidence-roots.js +52 -16
- package/packages/piagent-core/extensions/workspace-revision.js +48 -0
- package/packages/piagent-core/extensions/workspace-verification-snapshot.js +13 -0
- package/packages/piagent-core/package.json +3 -3
- package/packages/piagent-core/policies/base-policy.json +43 -2
- package/packages/piagent-core/policy/authority-manifest.v1.json +3 -3
- package/packages/piagent-core/prompts/be-to-fe.md +2 -8
- package/packages/piagent-core/prompts/plan.md +1 -1
- package/packages/piagent-core/prompts/platform-improve.md +2 -6
- package/packages/piagent-core/prompts/review.md +2 -7
- package/packages/piagent-core/prompts/scout.md +1 -1
- package/packages/piagent-core/prompts/task.md +4 -3
- package/packages/piagent-core/runtime/context/adaptive-planner.ts +7 -3
- package/packages/piagent-core/runtime/hooks/agent-start-hook.ts +60 -59
- package/packages/piagent-core/runtime/hooks/agent-start-types.ts +48 -0
- package/packages/piagent-core/runtime/hooks/completion-hook.ts +83 -89
- package/packages/piagent-core/runtime/hooks/input-hook.ts +98 -7
- package/packages/piagent-core/runtime/hooks/protected-refusal-completion.ts +86 -0
- package/packages/piagent-core/runtime/hooks/session-hooks.ts +5 -2
- package/packages/piagent-core/runtime/hooks/session-start-hook.ts +150 -19
- package/packages/piagent-core/runtime/hooks/tool-result-hook.ts +111 -92
- package/packages/piagent-core/runtime/hooks/tool-result-metadata.ts +9 -0
- package/packages/piagent-core/runtime/hooks/tool-result-navigation.ts +36 -0
- package/packages/piagent-core/runtime/hooks/tool-result-retrieval.ts +42 -0
- package/packages/piagent-core/runtime/hooks/tool-result-value-helpers.ts +66 -0
- package/packages/piagent-core/runtime/input/chat-images.ts +1 -1
- package/packages/piagent-core/runtime/inspection/activity-event-adapter.ts +1 -1
- package/packages/piagent-core/runtime/inspection/bounded-emission-guard.ts +286 -0
- package/packages/piagent-core/runtime/inspection/runtime-event-store.ts +37 -7
- package/packages/piagent-core/runtime/inspection/same-process-bridge-proof.ts +1 -1
- package/packages/piagent-core/runtime/inspection/task-handoff-history.ts +2 -2
- package/packages/piagent-core/runtime/inspection/task-subagent-tree.ts +27 -4
- package/packages/piagent-core/runtime/inspection/tool-failure-classification.ts +69 -11
- package/packages/piagent-core/runtime/inspection/webui-snapshot.ts +104 -22
- package/packages/piagent-core/runtime/inspection/workspace-file-reader.ts +2 -132
- package/packages/piagent-core/runtime/model/provider-wire-fingerprint.ts +20 -0
- package/packages/piagent-core/runtime/model/service-tier-runtime.ts +242 -0
- package/packages/piagent-core/runtime/orchestration/helper-lifecycle.ts +16 -12
- package/packages/piagent-core/runtime/orchestration/minimal-delegation-policy.ts +71 -0
- package/packages/piagent-core/runtime/orchestration/owned-work-budget.ts +28 -20
- package/packages/piagent-core/runtime/orchestration/role-policy.ts +27 -9
- package/packages/piagent-core/runtime/orchestration/subagent-tool-policy.ts +329 -0
- package/packages/piagent-core/runtime/policy/block-remedy.ts +0 -4
- package/packages/piagent-core/runtime/policy/source-worktree-transaction.ts +75 -14
- package/packages/piagent-core/runtime/product/activity-inspector.ts +6 -3
- package/packages/piagent-core/runtime/product/edit-verifier-timing.ts +26 -0
- package/packages/piagent-core/runtime/product/efficiency-metrics.ts +15 -7
- package/packages/piagent-core/runtime/product/operator-projections.ts +8 -3
- package/packages/piagent-core/runtime/product/task-usage-hooks.ts +78 -0
- package/packages/piagent-core/runtime/product/task-usage.ts +104 -0
- package/packages/piagent-core/runtime/quality/edit-freshness-guard.ts +102 -0
- package/packages/piagent-core/runtime/quality/exact-output-contract.ts +20 -10
- package/packages/piagent-core/runtime/quality/performance-assurance.ts +3 -3
- package/packages/piagent-core/runtime/quality/protected-refusal-handoff.ts +35 -0
- package/packages/piagent-core/runtime/recovery/acceptance-recovery-guidance.ts +21 -0
- package/packages/piagent-core/runtime/recovery/continuation-budget.ts +12 -3
- package/packages/piagent-core/runtime/recovery/diagnostic-delivery.ts +61 -0
- package/packages/piagent-core/runtime/recovery/handoff-projection.ts +196 -58
- package/packages/piagent-core/runtime/recovery/handoff-verifier-binding.ts +24 -0
- package/packages/piagent-core/runtime/recovery/independent-verification-recovery.ts +79 -0
- package/packages/piagent-core/runtime/recovery/pristine-task-policy-refresh.ts +91 -0
- package/packages/piagent-core/runtime/recovery/recovery-policy.ts +31 -40
- package/packages/piagent-core/runtime/recovery/resume-state.ts +120 -19
- package/packages/piagent-core/runtime/recovery/semantic-repair-handshake.ts +7 -13
- package/packages/piagent-core/runtime/recovery/task-evidence-coverage-refresh.ts +217 -0
- package/packages/piagent-core/runtime/registration/activity-inspector-command.ts +2 -1
- package/packages/piagent-core/runtime/registration/context-commands.ts +28 -10
- package/packages/piagent-core/runtime/registration/knowledge-tools.ts +9 -5
- package/packages/piagent-core/runtime/registration/operator-catalogs.ts +4 -9
- package/packages/piagent-core/runtime/registration/operator-request-intake.ts +49 -0
- package/packages/piagent-core/runtime/registration/policy-tools.ts +8 -6
- package/packages/piagent-core/runtime/registration/session-commands.ts +10 -8
- package/packages/piagent-core/runtime/registration/session-wait-tool.ts +54 -0
- package/packages/piagent-core/runtime/registration/task-completion-tools.ts +39 -20
- package/packages/piagent-core/runtime/registration/task-evidence-tools.ts +21 -12
- package/packages/piagent-core/runtime/registration/task-start-conditional-mutation.ts +45 -0
- package/packages/piagent-core/runtime/registration/task-start-guidance.ts +24 -15
- package/packages/piagent-core/runtime/registration/task-start-manifest.ts +54 -0
- package/packages/piagent-core/runtime/registration/task-start-tool.ts +79 -79
- package/packages/piagent-core/runtime/registration/workflow-commands.ts +64 -93
- package/packages/piagent-core/runtime/runtime-limits.ts +16 -2
- package/packages/piagent-core/runtime/session/adaptive-context-analysis.ts +461 -0
- package/packages/piagent-core/runtime/session/adaptive-context-governor.ts +464 -0
- package/packages/piagent-core/runtime/session/adaptive-context-ledger.ts +265 -0
- package/packages/piagent-core/runtime/session/completion-signals.ts +23 -0
- package/packages/piagent-core/runtime/session/message-signals.ts +6 -18
- package/packages/piagent-core/runtime/session/operator-request-carry.ts +44 -0
- package/packages/piagent-core/runtime/session/retrieval-evidence-runtime.ts +188 -0
- package/packages/piagent-core/runtime/session/runtime-state.ts +37 -39
- package/packages/piagent-core/runtime/session/source-checkout-read-grants.ts +35 -0
- package/packages/piagent-core/runtime/session/system-prompt.ts +76 -14
- package/packages/piagent-core/runtime/session/task-contract-presentation.ts +39 -0
- package/packages/piagent-core/runtime/session/uncertain-send-continuation.ts +231 -0
- package/packages/piagent-core/runtime/session/usage.ts +4 -3
- package/packages/piagent-core/runtime/tools/apply-patch-tool.ts +6 -6
- package/packages/piagent-core/runtime/tools/phase-tool-runtime.ts +1 -1
- package/packages/piagent-core/runtime/tools/phase-tools.ts +10 -9
- package/packages/piagent-core/runtime/tools/session-wait.ts +42 -0
- package/packages/piagent-core/runtime/tools/tool-groups.ts +22 -5
- package/packages/piagent-core/runtime/trajectory/trajectory-runtime.ts +192 -5
- package/packages/piagent-core/runtime/trajectory/trajectory-types.ts +3 -2
- package/packages/piagent-core/runtime/verification/acceptance-api-baseline.js +488 -0
- package/packages/piagent-core/runtime/verification/completion-preparation.ts +22 -0
- package/packages/piagent-core/runtime/verification/composite-completion-finalizer.ts +105 -0
- package/packages/piagent-core/runtime/verification/composite-journal-anchor.ts +181 -0
- package/packages/piagent-core/runtime/verification/composite-runtime-binding.ts +76 -0
- package/packages/piagent-core/runtime/verification/composite-scoped-mediation.ts +318 -0
- package/packages/piagent-core/runtime/verification/composite-session-persistence.ts +175 -0
- package/packages/piagent-core/runtime/verification/composite-task-publication.ts +273 -0
- package/packages/piagent-core/runtime/verification/exact-verifier-reuse.ts +101 -0
- package/packages/piagent-core/runtime/verification/host-project-verification.ts +71 -0
- package/packages/piagent-core/runtime/verification/independent-acceptance-runtime.ts +500 -0
- package/packages/piagent-core/runtime/verification/runtime-assurance-facts.ts +500 -0
- package/packages/piagent-core/runtime/verification/runtime-contract-runner.ts +107 -0
- package/packages/piagent-core/runtime/verification/shell-verification-snapshots.ts +56 -0
- package/packages/piagent-core/runtime/workflows/change-clarification.ts +61 -0
- package/packages/piagent-core/runtime/workflows/input-routing.ts +21 -14
- package/packages/piagent-core/runtime/workflows/runtime-intake-compaction.ts +201 -0
- package/packages/piagent-core/runtime/workflows/task-followup-policy.ts +163 -0
- package/packages/piagent-core/runtime/workflows/task-intake.ts +276 -169
- package/packages/piagent-core/runtime/workflows/task-repair-intent.ts +67 -0
- package/packages/piagent-core/runtime/workflows/task-scope-resolution.ts +83 -0
- package/packages/piagent-core/runtime/workflows/webui-runtime-command.ts +5 -2
- package/packages/piagent-core/runtime/workflows/webui-workflow.ts +39 -32
- package/packages/piagent-core/runtime/workflows/workflow-follow-up.ts +33 -0
- package/packages/piagent-core/security/workspace-file-reader.ts +132 -0
- package/packages/piagent-core/subagents/piagent-oracle.md +5 -3
- package/packages/piagent-core/subagents/piagent-planner.md +6 -4
- package/packages/piagent-core/subagents/piagent-reviewer.md +5 -3
- package/packages/piagent-core/subagents/piagent-scout.md +4 -2
- package/packages/piagent-core/subagents/piagent-worker.md +6 -4
- package/packages/piagent-webui/dist/client/assets/{MarkdownMessage-CxeZqTte.js → MarkdownMessage-DGk34zJT.js} +1 -1
- package/packages/piagent-webui/dist/client/assets/{index-BV-_03yl.css → index-DVahUVWy.css} +1 -1
- package/packages/piagent-webui/dist/client/assets/index-DiKRmCEP.js +176 -0
- package/packages/piagent-webui/dist/client/index.html +2 -2
- package/packages/piagent-webui/extension/dispatch-user-entry.ts +13 -0
- package/packages/piagent-webui/extension/piagent-webui.ts +13 -3
- package/packages/piagent-webui/extension/review-controller.ts +29 -6
- package/packages/piagent-webui/extension/same-session-bridge.ts +7 -8
- package/packages/piagent-webui/extension/session-stream-adapter.ts +88 -16
- package/packages/piagent-webui/extension/source-mutation-controller.ts +29 -3
- package/packages/piagent-webui/extension/source-open-controller.ts +29 -7
- package/packages/piagent-webui/extension/source-revert-controller.ts +26 -3
- package/packages/piagent-webui/gateway/gateway-events.ts +22 -5
- package/packages/piagent-webui/gateway/gateway-service.ts +7 -2
- package/packages/piagent-webui/gateway/gateway-session-stream.ts +170 -32
- package/packages/piagent-webui/gateway/rpc-ui-context.ts +34 -9
- package/packages/piagent-webui/gateway/runtime-command-controller.ts +46 -6
- package/packages/piagent-webui/gateway/runtime-session-controls.ts +17 -2
- package/packages/piagent-webui/gateway/session-catalog.ts +9 -3
- package/packages/piagent-webui/gateway/session-command-controller.ts +29 -9
- package/packages/piagent-webui/gateway/session-effective-options.ts +2 -9
- package/packages/piagent-webui/gateway/session-inspection-registry.ts +11 -2
- package/packages/piagent-webui/gateway/session-operation-lifecycle.ts +237 -0
- package/packages/piagent-webui/gateway/session-operation-retry-control.ts +38 -0
- package/packages/piagent-webui/gateway/session-operation-settlement.ts +28 -0
- package/packages/piagent-webui/gateway/session-operation-watchdog.ts +9 -2
- package/packages/piagent-webui/gateway/session-prompt-dispatch.ts +37 -0
- package/packages/piagent-webui/gateway/session-runtime-close.ts +36 -0
- package/packages/piagent-webui/gateway/session-runtime-factory.ts +183 -6
- package/packages/piagent-webui/gateway/session-runtime-ownership.ts +48 -0
- package/packages/piagent-webui/gateway/session-runtime-state.ts +24 -0
- package/packages/piagent-webui/gateway/session-runtime-supervisor.ts +118 -117
- package/packages/piagent-webui/ownership/session-lease-store.ts +5 -2
- package/packages/piagent-webui/server/core-inspection-provider.ts +75 -15
- package/packages/piagent-webui/server/loopback-server.ts +9 -7
- package/packages/piagent-webui/server/terminal-delivery-receipt.ts +144 -0
- package/packages/piagent-webui/server/transcript-projection.ts +150 -11
- package/packages/piagent-webui/shared/message-correlation.ts +25 -0
- package/schemas/approved-host-contracts.schema.json +973 -0
- package/schemas/benchmark-attempt-outcome.schema.json +303 -0
- package/schemas/benchmark-independent-verification-plan.schema.json +34 -0
- package/schemas/codex-relative-efficiency-v1.schema.json +155 -0
- package/schemas/composite-criterion.schema.json +788 -0
- package/schemas/contract-family-library.schema.json +28 -0
- package/schemas/contract-selection-recipe.schema.json +31 -0
- package/schemas/failure-evidence.schema.json +2 -2
- package/schemas/helper-request.schema.json +16 -4
- package/schemas/host-contract-plan.schema.json +25 -0
- package/schemas/piagent-webui/gateway-protocol-v1.schema.json +16 -2
- package/schemas/piagent-webui/runtime-command-v1.schema.json +26 -3
- package/schemas/piagent-webui/runtime-event-v2.schema.json +46 -5
- package/schemas/piagent-webui/session-live-state-v1.schema.json +2 -0
- package/schemas/piagent-webui/snapshot-v1.schema.json +3 -0
- package/schemas/piagent-webui/source-change-v1.schema.json +12 -0
- package/schemas/piagent-webui/subagent-tree-v1.schema.json +11 -1
- package/schemas/piagent-webui/transcript-v1.schema.json +2 -1
- package/schemas/project-profile.schema.json +1 -1
- package/schemas/public-contracts/codex-mcp-metadata-v1.schema.json +206 -0
- package/schemas/public-contracts/codex-mcp-metadata-v2.schema.json +228 -0
- package/schemas/public-contracts/codex-mcp-metadata-v3.schema.json +233 -0
- package/schemas/public-contracts/revocation-v1.schema.json +87 -0
- package/schemas/public-contracts/subscription-contract-v1.schema.json +76 -0
- package/schemas/scoped-project-verification-receipt-v2.schema.json +83 -0
- package/schemas/scoped-project-verification-receipt-v3.schema.json +295 -0
- package/schemas/scoped-verification-receipt-v1.schema.json +76 -0
- package/schemas/task-contract.schema.json +45 -0
- package/scripts/approve-independent-verification.mjs +57 -0
- package/scripts/benchmark-arm-observer.mjs +320 -0
- package/scripts/benchmark-budget-ipc.mjs +34 -0
- package/scripts/benchmark-budget-launcher.mjs +91 -0
- package/scripts/benchmark-budget-processes.mjs +133 -0
- package/scripts/benchmark-budget-publication.mjs +228 -0
- package/scripts/benchmark-budget-runtime.mjs +136 -0
- package/scripts/benchmark-candidate-ablation.mjs +265 -0
- package/scripts/benchmark-codex-journey.mjs +406 -0
- package/scripts/benchmark-independent-verification.mjs +628 -0
- package/scripts/benchmark-journey-outcome.mjs +92 -0
- package/scripts/benchmark-production-v3-human-review.mjs +192 -0
- package/scripts/benchmark-public-input-catalog.mjs +158 -0
- package/scripts/benchmark-registered-plan-author.mjs +355 -0
- package/scripts/benchmark-registered-plan-recipe-support.mjs +85 -0
- package/scripts/benchmark-registered-plan-recipes-backend.mjs +165 -0
- package/scripts/benchmark-registered-plan-recipes-data.mjs +164 -0
- package/scripts/benchmark-registered-plan-recipes-platform.mjs +165 -0
- package/scripts/benchmark-runner-completion.mjs +133 -0
- package/scripts/benchmark-runner-configuration.mjs +159 -0
- package/scripts/benchmark-runner-core.mjs +224 -387
- package/scripts/benchmark-runner-finalization.mjs +144 -27
- package/scripts/benchmark-runner-provider-boundary.mjs +44 -0
- package/scripts/benchmark-runner-schedule.mjs +256 -0
- package/scripts/benchmark-runner-support.mjs +136 -4
- package/scripts/benchmark-runner.mjs +95 -18
- package/scripts/benchmark-scoped-broker-custody.mjs +483 -0
- package/scripts/benchmark-scoped-docs-verifier.mjs +203 -0
- package/scripts/benchmark-scoped-frozen-qualification.mjs +676 -0
- package/scripts/benchmark-scoped-pi-router.mjs +196 -0
- package/scripts/benchmark-scoped-project-verification-receipt.mjs +49 -0
- package/scripts/benchmark-scoped-project-verifier.mjs +461 -0
- package/scripts/benchmark-scoped-session-custody.mjs +599 -0
- package/scripts/benchmark-scoped-session-factory.mjs +342 -0
- package/scripts/benchmark-scoped-tool-broker.mjs +523 -0
- package/scripts/benchmark-scoped-verification-supervisor.mjs +773 -0
- package/scripts/benchmark-session-evaluator.mjs +169 -0
- package/scripts/benchmark-session-provider-boundary.mjs +62 -0
- package/scripts/benchmark-session-usage.mjs +28 -0
- package/scripts/benchmark-session.mjs +343 -50
- package/scripts/benchmark-webui-journey.mjs +678 -0
- package/scripts/check-public-wording.mjs +46 -0
- package/scripts/configure-subagents.sh +42 -34
- package/scripts/fs4-readiness-evaluation.mjs +7 -1
- package/scripts/helper-evaluation.mjs +1 -1
- package/scripts/phase-tools-evaluation.mjs +1 -0
- package/scripts/pi-auto.sh +7 -1
- package/scripts/pi-usage-history.mjs +201 -11
- package/scripts/piagent-cli.mjs +8 -0
- package/scripts/private-holdout-readiness.mjs +7 -1
- package/scripts/public-evaluation-exposure.mjs +140 -0
- package/scripts/select-independent-verification.mjs +62 -0
- package/scripts/team-doctor.sh +1 -1
- package/scripts/typescript-loader.mjs +135 -1
- package/scripts/update-global.mjs +6 -7
- package/scripts/verify-local.sh +41 -55
- package/scripts/verify-release-identity.mjs +5 -3
- package/packages/piagent-webui/dist/client/assets/index-DynIMe8I.js +0 -176
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
<meta name="csp-nonce" content="__PIAGENT_CSP_NONCE__" />
|
|
8
8
|
<meta name="piagent-webui-mode" content="__PIAGENT_WEBUI_MODE__" />
|
|
9
9
|
<title>Piagent WebUI</title>
|
|
10
|
-
<script type="module" crossorigin src="/assets/index-
|
|
11
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
10
|
+
<script type="module" crossorigin src="/assets/index-DiKRmCEP.js"></script>
|
|
11
|
+
<link rel="stylesheet" crossorigin href="/assets/index-DVahUVWy.css">
|
|
12
12
|
</head>
|
|
13
13
|
<body>
|
|
14
14
|
<div id="root"></div>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
type BranchEntry = { id: string; parentId: string | null; type: string; message?: { role: string } };
|
|
2
|
+
|
|
3
|
+
// Pi may persist system prompt updates before the user message in the same dispatch.
|
|
4
|
+
// Do not cross any other entry kind or another user's/assistant's message.
|
|
5
|
+
export function firstUserEntryAfter<T extends BranchEntry>(branch: readonly T[], parentId: string | null): T | null {
|
|
6
|
+
for (const entry of branch) {
|
|
7
|
+
if (entry.parentId !== parentId) continue;
|
|
8
|
+
if (entry.type !== "message") return null;
|
|
9
|
+
if (entry.message?.role === "system") { parentId = entry.id; continue; }
|
|
10
|
+
return entry.message?.role === "user" ? entry : null;
|
|
11
|
+
}
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
@@ -313,6 +313,7 @@ export default function piagentWebUiExtension(pi: ExtensionAPI): void {
|
|
|
313
313
|
task: () => activeSessionTask(ctx.cwd, ctx.sessionManager.getSessionId()),
|
|
314
314
|
activityEvents: () => readContextTelemetry(ctx.cwd, { limit: 5_000 }) as unknown[],
|
|
315
315
|
currentActivity: () => [], sessionEntries: () => ctx.sessionManager.getBranch(), protectedPaths: () => protectedPaths(ctx),
|
|
316
|
+
sessionFile: () => ctx.sessionManager.getSessionFile(),
|
|
316
317
|
documentReadRoots: () => documentReadRoots(ctx),
|
|
317
318
|
contextUsage: () => ctx.getContextUsage(), model: () => ctx.model,
|
|
318
319
|
thinkingLevel: () => ctx.thinkingLevel ?? pi.getThinkingLevel(),
|
|
@@ -446,15 +447,23 @@ export default function piagentWebUiExtension(pi: ExtensionAPI): void {
|
|
|
446
447
|
pi.on("tool_execution_end", (event, ctx) => { publishDrafts(ctx, stream.toolEnded(event, bridge.snapshot())); bridgeSoft(() => lifecycle.observeToolEnd(ctx)); });
|
|
447
448
|
pi.on("turn_end", (event, ctx) => publishDrafts(ctx, stream.turnEnded(event, bridge.snapshot())));
|
|
448
449
|
pi.on("agent_settled", (_event, ctx) => {
|
|
449
|
-
|
|
450
|
+
const hasPendingMessages = typeof ctx.hasPendingMessages === "function" ? ctx.hasPendingMessages() : null;
|
|
451
|
+
publishDrafts(ctx, stream.agentSettled(bridge.snapshot(), hasPendingMessages));
|
|
452
|
+
if (hasPendingMessages === true) { publishPersisted(ctx); return; }
|
|
450
453
|
const operationId = bridge.snapshot().identity?.agentOperationId ?? null;
|
|
451
454
|
bridgeSoft(() => bridge.observeAgentSettled(ctx)); bridgeSoft(() => lifecycle.observeAgentSettled(ctx, operationId)); publishPersisted(ctx);
|
|
452
455
|
});
|
|
453
456
|
pi.on("session_info_changed", (_event, ctx) => { currentContext = ctx; bridgeSoft(() => bridge.refresh(ctx)); });
|
|
454
457
|
pi.on("model_select", (_event, ctx) => { currentContext = ctx; bridgeSoft(() => sessionOptions.observeHostOptionChange(ctx)); currentManager(ctx)?.provider.invalidate(); });
|
|
455
458
|
pi.on("thinking_level_select", (_event, ctx) => { currentContext = ctx; bridgeSoft(() => sessionOptions.observeHostOptionChange(ctx)); currentManager(ctx)?.provider.invalidate(); });
|
|
456
|
-
pi.on("session_before_switch", () => {
|
|
457
|
-
|
|
459
|
+
pi.on("session_before_switch", (_event, ctx) => {
|
|
460
|
+
publishDrafts(ctx, stream.operationInterrupted(bridge.snapshot(), "session-replaced-before-tool-result"));
|
|
461
|
+
lifecycle.replacementPending(); bridgeSoft(() => bridge.replacementPending());
|
|
462
|
+
});
|
|
463
|
+
pi.on("session_before_fork", (_event, ctx) => {
|
|
464
|
+
publishDrafts(ctx, stream.operationInterrupted(bridge.snapshot(), "session-forked-before-tool-result"));
|
|
465
|
+
lifecycle.replacementPending(); bridgeSoft(() => bridge.replacementPending());
|
|
466
|
+
});
|
|
458
467
|
pi.on("session_start", async (_event, ctx) => {
|
|
459
468
|
currentContext = ctx; stream.reset(); queue.reset(); sessionOptions.reset(); attachments?.reset();
|
|
460
469
|
if (!isGatewayRuntimeContext(ctx)) {
|
|
@@ -471,6 +480,7 @@ export default function piagentWebUiExtension(pi: ExtensionAPI): void {
|
|
|
471
480
|
catch (error) { ctx.ui.notify(error instanceof Error ? error.message : "Piagent WebUI could not start", "error"); }
|
|
472
481
|
});
|
|
473
482
|
pi.on("session_shutdown", async (_event, ctx) => {
|
|
483
|
+
publishDrafts(ctx, stream.operationInterrupted(bridge.snapshot(), "session-shutdown-before-tool-result"));
|
|
474
484
|
stream.reset(); queue.reset(); sessionOptions.reset(); attachments?.close(); eventReaders.delete(key(ctx));
|
|
475
485
|
if (approvalBinding?.key === key(ctx)) { approvalBinding.unsubscribe(); approvalBinding.unbind(); approvalBinding = null; }
|
|
476
486
|
lifecycle.shutdown();
|
|
@@ -33,11 +33,19 @@ function exactKeys(value: unknown, keys: string[]): boolean { return Boolean(val
|
|
|
33
33
|
&& same(Object.keys(value as object).sort(), [...keys].sort())); }
|
|
34
34
|
function timestamp(value: unknown): value is string { if (typeof value !== "string" || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(value)) return false;
|
|
35
35
|
const parsed = Date.parse(value); return Number.isFinite(parsed) && new Date(parsed).toISOString() === value; }
|
|
36
|
+
function nullableRevision(value: unknown): value is string | null { return value === null || typeof value === "string" && REVISION.test(value); }
|
|
36
37
|
function wireIdentity(value: BridgeIdentity): BridgeIdentity { return { projectRef: value.projectRef, runtimeInstanceId: value.runtimeInstanceId,
|
|
37
38
|
sessionRef: value.sessionRef, taskId: value.taskId, taskRunId: value.taskRunId, agentOperationId: null, toolCallId: null }; }
|
|
38
39
|
function wireRevisions(value: BridgeRevisions): BridgeRevisions { return { runtimeRevision: value.runtimeRevision, taskRevision: value.taskRevision,
|
|
39
40
|
controlRevision: value.controlRevision, workspaceRevision: value.workspaceRevision, indexRevision: value.indexRevision,
|
|
40
41
|
approvalRevision: value.approvalRevision, sessionOptionRevision: value.sessionOptionRevision, queueRevision: value.queueRevision }; }
|
|
42
|
+
function replayIdentityDisposition(record: Pick<ReviewEvidenceRecord, "projectRef" | "runtimeInstanceId" | "sessionRef" | "taskId" | "taskRunId">,
|
|
43
|
+
identity: BridgeIdentity): "task-identity-mismatch" | "runtime-or-session-replaced" | null {
|
|
44
|
+
if (record.taskId !== identity.taskId || record.taskRunId !== identity.taskRunId) return "task-identity-mismatch";
|
|
45
|
+
if (record.projectRef !== identity.projectRef || record.runtimeInstanceId !== identity.runtimeInstanceId || record.sessionRef !== identity.sessionRef)
|
|
46
|
+
return "runtime-or-session-replaced";
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
41
49
|
|
|
42
50
|
function receiptFromRecord(record: ReviewEvidenceRecord, deduplicated: boolean): ReviewReceipt {
|
|
43
51
|
return { schemaVersion: 1, version: "piagent-webui-control-v1", messageType: "receipt", commandId: record.commandId,
|
|
@@ -82,19 +90,32 @@ export class ReviewController {
|
|
|
82
90
|
if (old) {
|
|
83
91
|
if (old.commandId !== command.commandId || old.idempotencyKeyDigest !== keyDigest || old.actionDigest !== command.actionDigest)
|
|
84
92
|
return this.#reject(command, "idempotency-payload-mismatch", "idempotency-payload-mismatch", false);
|
|
85
|
-
|
|
86
|
-
|
|
93
|
+
const disposition = replayIdentityDisposition(old, identity);
|
|
94
|
+
if (disposition) return this.#reject(command, "identity-mismatch", disposition, false);
|
|
87
95
|
return receiptFromRecord(old, true);
|
|
88
96
|
}
|
|
89
97
|
const now = this.#now().getTime();
|
|
90
98
|
if (Date.parse(command.requestedAt) > now + 30_000) return this.#reject(command, "invalid-command", "requested-at-in-future", false);
|
|
91
99
|
if (now > Date.parse(command.expiresAt)) return this.#reject(command, "expired", "command-expired", false);
|
|
92
100
|
if (!same(command.identity, identity)) return this.#reject(command, "identity-mismatch", "identity-mismatch", false);
|
|
93
|
-
if (command.expectedRevisions.runtimeRevision !== revisions.runtimeRevision || command.expectedRevisions.taskRevision !== revisions.taskRevision
|
|
94
|
-
|
|
101
|
+
if (command.expectedRevisions.runtimeRevision !== revisions.runtimeRevision || command.expectedRevisions.taskRevision !== revisions.taskRevision
|
|
102
|
+
|| command.expectedRevisions.controlRevision !== revisions.controlRevision)
|
|
103
|
+
return this.#reject(command, "stale-revision", "stale-task-control-revision", true);
|
|
95
104
|
let projection: ReviewStateProjection;
|
|
96
105
|
try { projection = await this.#resolve(command.payload.view, command.payload.fileRef); }
|
|
97
106
|
catch { return this.#reject(command, "capability-unavailable", "review-target-unavailable", true); }
|
|
107
|
+
const rebound = this.#bridge.snapshot();
|
|
108
|
+
if (rebound.state !== "ready" || !rebound.identity || !rebound.revisions)
|
|
109
|
+
return this.#reject(command, "resync-required", "review-binding-unavailable-after-target-resolution", true);
|
|
110
|
+
const reboundIdentity = wireIdentity(rebound.identity), reboundRevisions = wireRevisions(rebound.revisions);
|
|
111
|
+
if (!same(reboundIdentity, identity)) {
|
|
112
|
+
const taskChanged = reboundIdentity.taskId !== identity.taskId || reboundIdentity.taskRunId !== identity.taskRunId;
|
|
113
|
+
return this.#reject(command, "identity-mismatch", taskChanged ? "task-identity-mismatch" : "runtime-or-session-replaced", false);
|
|
114
|
+
}
|
|
115
|
+
if (command.expectedRevisions.runtimeRevision !== reboundRevisions.runtimeRevision
|
|
116
|
+
|| command.expectedRevisions.taskRevision !== reboundRevisions.taskRevision
|
|
117
|
+
|| command.expectedRevisions.controlRevision !== reboundRevisions.controlRevision)
|
|
118
|
+
return this.#reject(command, "stale-revision", "stale-task-control-revision-after-target-resolution", true);
|
|
98
119
|
const target = projection.target;
|
|
99
120
|
if (!target || projection.state === "unavailable") return this.#reject(command, "capability-unavailable", projection.reasonCode ?? "review-target-unavailable", true);
|
|
100
121
|
if (!this.#matchesTarget(command, target)) return this.#reject(command, "stale-revision", "review-target-changed", true);
|
|
@@ -130,8 +151,10 @@ export class ReviewController {
|
|
|
130
151
|
const revisionKeys = ["runtimeRevision", "taskRevision", "controlRevision", "workspaceRevision", "indexRevision", "approvalRevision",
|
|
131
152
|
"sessionOptionRevision", "queueRevision", "workspacePreimage", "indexPreimage", "patchPreimage"];
|
|
132
153
|
if (!exactKeys(command.expectedRevisions, revisionKeys) || !REVISION.test(command.expectedRevisions.runtimeRevision)
|
|
133
|
-
|| !REVISION.test(command.expectedRevisions.taskRevision ?? "") || !REVISION.test(command.expectedRevisions.
|
|
134
|
-
||
|
|
154
|
+
|| !REVISION.test(command.expectedRevisions.taskRevision ?? "") || !REVISION.test(command.expectedRevisions.controlRevision ?? "")
|
|
155
|
+
|| !REVISION.test(command.expectedRevisions.workspaceRevision ?? "")
|
|
156
|
+
|| ![command.expectedRevisions.indexRevision, command.expectedRevisions.approvalRevision,
|
|
157
|
+
command.expectedRevisions.sessionOptionRevision, command.expectedRevisions.queueRevision].every(nullableRevision)
|
|
135
158
|
|| command.expectedRevisions.workspacePreimage !== null || command.expectedRevisions.indexPreimage !== null
|
|
136
159
|
|| !DIGEST.test(command.expectedRevisions.patchPreimage)) return "invalid-review-authority";
|
|
137
160
|
if (!exactKeys(command.payload, ["view", "fileRef", "diffRef", "reviewState", "contentDigest"])
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { firstUserEntryAfter } from "./dispatch-user-entry.ts";
|
|
1
2
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
3
|
import { createHash, randomBytes } from "node:crypto";
|
|
3
4
|
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
@@ -98,8 +99,8 @@ function messageText(message: any): string {
|
|
|
98
99
|
}
|
|
99
100
|
function firstMessageText(message: any): string { return Array.isArray(message?.content) ? String(message.content.find((item: any) => item?.type === "text")?.text ?? "") : String(message?.content ?? ""); }
|
|
100
101
|
function dispatchEntry(pending: PendingDispatch, ctx: ExtensionContext): any | null {
|
|
101
|
-
|
|
102
|
-
|
|
102
|
+
const entry = firstUserEntryAfter(ctx.sessionManager.getBranch(), pending.leafBefore) as any;
|
|
103
|
+
return entry && messageText(entry.message) === pending.observedText ? entry : null;
|
|
103
104
|
}
|
|
104
105
|
export function chatContentDigest(payload: Pick<NewOperationChatCommand["payload"], "text" | "attachmentRefs">): string {
|
|
105
106
|
return sha(canonical({ text: payload.text, attachmentRefs: payload.attachmentRefs }));
|
|
@@ -168,7 +169,6 @@ export class SameSessionPiBridge {
|
|
|
168
169
|
const branch = ctx.sessionManager.getBranch();
|
|
169
170
|
if (!Array.isArray(branch) || branch.length > MAX_SESSION_ENTRIES) throw new Error("webui-bridge-receipt-history-unavailable");
|
|
170
171
|
const requested = new Map<string, { receipt: ChatReceipt; messageRequestId: string; contentDigest: string; attachmentRefs: string[]; entryId: string }>();
|
|
171
|
-
const entriesById = new Map(branch.map((entry: any) => [entry?.id, entry]));
|
|
172
172
|
for (const entry of branch) {
|
|
173
173
|
if (entry?.type !== "custom" || entry.customType !== WEBUI_CONTROL_ENTRY_TYPE) continue;
|
|
174
174
|
if (!exactKeys(entry.data, ["receipt"]) && !exactKeys(entry.data, ["receipt", "messageRequestId", "contentDigest"])
|
|
@@ -193,8 +193,8 @@ export class SameSessionPiBridge {
|
|
|
193
193
|
|| receipt.requestedAt !== prior.receipt.requestedAt || !same(receipt.observedRevisionsBefore, prior.receipt.observedRevisionsBefore)
|
|
194
194
|
|| !same(receipt.identity, prior.receipt.identity) || !same(attachmentRefs, prior.attachmentRefs)) throw new Error("webui-bridge-receipt-store-corrupt");
|
|
195
195
|
if (receipt.resultCode === "dispatch-observed") {
|
|
196
|
-
const evidence =
|
|
197
|
-
if (!evidence || evidence.
|
|
196
|
+
const evidence = firstUserEntryAfter(branch, prior.entryId) as any;
|
|
197
|
+
if (!evidence || evidence.id !== receipt.settlementEvidenceRef
|
|
198
198
|
|| chatContentDigest({ text: firstMessageText(evidence.message), attachmentRefs: prior.attachmentRefs }) !== prior.contentDigest) throw new Error("webui-bridge-receipt-store-corrupt");
|
|
199
199
|
}
|
|
200
200
|
}
|
|
@@ -310,14 +310,13 @@ export class SameSessionPiBridge {
|
|
|
310
310
|
observeMessageStart(event: { message?: unknown }, ctx: ExtensionContext): void {
|
|
311
311
|
if (!this.refresh(ctx) || this.#binding?.state !== "ready") return; const pending = this.#pending, message = event.message as any;
|
|
312
312
|
const leaf = pending ? ctx.sessionManager.getLeafEntry?.() : null;
|
|
313
|
-
const leafObserved = Boolean(pending && leaf?.
|
|
314
|
-
&& messageText(leaf.message) === pending.observedText);
|
|
313
|
+
const leafObserved = Boolean(pending && leaf?.id && dispatchEntry(pending, ctx)?.id === leaf.id);
|
|
315
314
|
if (pending && pending.inputObserved && leafObserved && message?.role === "user" && messageText(message) === pending.observedText)
|
|
316
315
|
this.#settlePending("dispatch-observed", "settled", null, true, leaf.id);
|
|
317
316
|
}
|
|
318
317
|
observeAgentStart(ctx: ExtensionContext): void {
|
|
319
318
|
if (!this.refresh(ctx) || !this.#binding || this.#binding.state !== "ready") return;
|
|
320
|
-
const pending = this.#pending;
|
|
319
|
+
const pending = this.#pending; if (this.#binding.identity.agentOperationId && !pending) return;
|
|
321
320
|
const operationId = pending?.operationId ?? this.#revision("operation", ++this.#operationCounter, "external");
|
|
322
321
|
this.#binding.identity.agentOperationId = operationId; this.#refresh(); this.#event("operation.started", { operationRef: operationId, commandId: pending?.command.commandId });
|
|
323
322
|
const observedEntry = pending ? dispatchEntry(pending, ctx) : null;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
|
|
3
3
|
import { redactSensitiveText } from "../../piagent-core/extensions/redaction-core.js";
|
|
4
|
+
import { classifyToolFailure, handledToolFailure } from "../../piagent-core/runtime/inspection/tool-failure-classification.ts";
|
|
4
5
|
import type { RuntimeEventDraft, RuntimeEventRevision } from "../../piagent-core/runtime/inspection/runtime-event-store.ts";
|
|
5
6
|
import type { BridgeIdentity, BridgeSnapshot } from "./same-session-bridge.ts";
|
|
6
7
|
|
|
@@ -9,13 +10,37 @@ const MAX_DELTA = 16_384;
|
|
|
9
10
|
const MAX_MESSAGE_STREAM_EVENTS = 128;
|
|
10
11
|
const STREAM_FLUSH_CHARS = 1_024;
|
|
11
12
|
const STREAM_FLUSH_INTERVAL_MS = 100;
|
|
13
|
+
const MAX_OBSERVED_UPDATES = 100_000;
|
|
14
|
+
const UPDATE_KINDS = new Set(["start", "text_start", "text_delta", "text_end", "thinking_start", "thinking_delta",
|
|
15
|
+
"thinking_end", "toolcall_start", "toolcall_delta", "toolcall_end", "done", "error"]);
|
|
12
16
|
const ANSI = /\u001b(?:[@-_]|\[[0-?]*[ -/]*[@-~])/g;
|
|
13
17
|
const PRIVATE_KEY_BEGIN = /-----BEGIN [A-Z ]*PRIVATE KEY-----/;
|
|
14
18
|
const PRIVATE_KEY_END = /-----END [A-Z ]*PRIVATE KEY-----/;
|
|
15
19
|
|
|
16
20
|
type MessageRole = "user" | "assistant" | "tool-result";
|
|
21
|
+
type StreamActivity = { schemaVersion: 1; boundary: "pi-message-update-hook"; observedUpdates: number;
|
|
22
|
+
textUpdates: number; thinkingUpdates: number; toolCallUpdates: number; otherUpdates: number;
|
|
23
|
+
lastUpdateKind: string | null; lastObservedAt: string | null; countersCapped: boolean };
|
|
17
24
|
type ActiveMessage = { ref: string; role: MessageRole; rawBuffer: string; chunkSequence: number; truncated: boolean;
|
|
18
|
-
emittedEvents: number; lastFlushAt: number; thinking: Set<number>; thinkingStreaming: Set<number>; thinkingCompleted: Set<number
|
|
25
|
+
emittedEvents: number; lastFlushAt: number; thinking: Set<number>; thinkingStreaming: Set<number>; thinkingCompleted: Set<number>;
|
|
26
|
+
streamActivity: StreamActivity };
|
|
27
|
+
|
|
28
|
+
function newStreamActivity(): StreamActivity {
|
|
29
|
+
return { schemaVersion: 1, boundary: "pi-message-update-hook", observedUpdates: 0, textUpdates: 0, thinkingUpdates: 0,
|
|
30
|
+
toolCallUpdates: 0, otherUpdates: 0, lastUpdateKind: null, lastObservedAt: null, countersCapped: false };
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// This observes delivery to the Pi hook, not network traffic or provider usage.
|
|
34
|
+
// Count before projection filtering; never retain an update payload or its text.
|
|
35
|
+
function observeStreamActivity(activity: StreamActivity, kind: unknown, now: Date): void {
|
|
36
|
+
const known = typeof kind === "string" && UPDATE_KINDS.has(kind) ? kind : "other";
|
|
37
|
+
activity.lastUpdateKind = known; activity.lastObservedAt = now.toISOString();
|
|
38
|
+
if (activity.observedUpdates >= MAX_OBSERVED_UPDATES) { activity.countersCapped = true; return; }
|
|
39
|
+
activity.observedUpdates++;
|
|
40
|
+
const category = known.startsWith("text_") ? "textUpdates" : known.startsWith("thinking_") ? "thinkingUpdates"
|
|
41
|
+
: known.startsWith("toolcall_") ? "toolCallUpdates" : "otherUpdates";
|
|
42
|
+
activity[category]++;
|
|
43
|
+
}
|
|
19
44
|
|
|
20
45
|
function hash(value: string): string { return createHash("sha256").update(value).digest("hex"); }
|
|
21
46
|
function opaque(prefix: string, value: unknown): string { return `${prefix}.${hash(JSON.stringify(value))}`; }
|
|
@@ -35,6 +60,13 @@ function safeToolName(value: unknown): string {
|
|
|
35
60
|
if (projected.redacted) return "redacted-tool";
|
|
36
61
|
return projected.text.replace(/[^A-Za-z0-9._:-]/g, "-").replace(/^[^A-Za-z0-9]+/, "").slice(0, 128) || "tool";
|
|
37
62
|
}
|
|
63
|
+
function toolClassificationInput(value: unknown): { command: string } | undefined {
|
|
64
|
+
if (!value || typeof value !== "object") return undefined;
|
|
65
|
+
const direct = (value as { command?: unknown }).command;
|
|
66
|
+
const nested = (value as { args?: { command?: unknown } }).args?.command;
|
|
67
|
+
const command = typeof direct === "string" ? direct : typeof nested === "string" ? nested : null;
|
|
68
|
+
return command === null ? undefined : { command: command.slice(0, 8_192) };
|
|
69
|
+
}
|
|
38
70
|
function role(message: any): MessageRole | null {
|
|
39
71
|
return message?.role === "user" ? "user" : message?.role === "assistant" ? "assistant" : message?.role === "toolResult" ? "tool-result" : null;
|
|
40
72
|
}
|
|
@@ -68,10 +100,11 @@ function redaction(applied = false, truncated = false) { return { applied, value
|
|
|
68
100
|
function identityReady(identity: BridgeIdentity | null): identity is BridgeIdentity & { agentOperationId: string } {
|
|
69
101
|
return Boolean(identity?.agentOperationId);
|
|
70
102
|
}
|
|
71
|
-
function activityPayload(state: "started" | "progress" | "finished" | "failed", activityRef: string, toolName: string
|
|
103
|
+
function activityPayload(state: "started" | "progress" | "finished" | "failed" | "aborted", activityRef: string, toolName: string,
|
|
104
|
+
reasonCode: string | null = null) {
|
|
72
105
|
return { state, activityType: "tool", activityRef, toolName, inputDigest: null, outputDigest: null, preview: null, previewKind: "none",
|
|
73
106
|
outputBytes: null, outputLines: null, exitCode: null, isError: state === "finished" ? false : state === "failed" ? true : null,
|
|
74
|
-
affectedFileRefs: [], criterionIds: [], verifierAttemptIds: [], reasonCode
|
|
107
|
+
affectedFileRefs: [], criterionIds: [], verifierAttemptIds: [], reasonCode };
|
|
75
108
|
}
|
|
76
109
|
|
|
77
110
|
export class PiSessionStreamAdapter {
|
|
@@ -81,12 +114,14 @@ export class PiSessionStreamAdapter {
|
|
|
81
114
|
#activeByRole = new Map<MessageRole, ActiveMessage>();
|
|
82
115
|
#lastMessageRef: string | null = null;
|
|
83
116
|
#toolRefs = new Map<string, string>();
|
|
117
|
+
#toolNames = new Map<string, string>();
|
|
118
|
+
#toolInputs = new Map<string, { command: string } | undefined>();
|
|
84
119
|
#lastToolProgress = new Map<string, number>();
|
|
85
120
|
|
|
86
121
|
constructor(options: { now?: () => Date } = {}) { this.#now = options.now ?? (() => new Date()); }
|
|
87
122
|
reset(): void {
|
|
88
123
|
this.#turnIndex = null; this.#messageCounter = 0; this.#activeByRole.clear(); this.#lastMessageRef = null;
|
|
89
|
-
this.#toolRefs.clear(); this.#lastToolProgress.clear();
|
|
124
|
+
this.#toolRefs.clear(); this.#toolNames.clear(); this.#toolInputs.clear(); this.#lastToolProgress.clear();
|
|
90
125
|
}
|
|
91
126
|
|
|
92
127
|
#base(snapshot: BridgeSnapshot, sourceObservedAt?: unknown): Omit<RuntimeEventDraft, "kind" | "payload" | "evidence" | "redaction"> | null {
|
|
@@ -120,7 +155,7 @@ export class PiSessionStreamAdapter {
|
|
|
120
155
|
const source = messageRole === "tool-result" ? "" : safe(text(message), MAX_STREAM_BUFFER).text;
|
|
121
156
|
this.#activeByRole.set(messageRole, { ref: messageRef, role: messageRole, rawBuffer: "", chunkSequence: 0, truncated: false,
|
|
122
157
|
emittedEvents: 0, lastFlushAt: this.#now().getTime(),
|
|
123
|
-
thinking: new Set(), thinkingStreaming: new Set(), thinkingCompleted: new Set() });
|
|
158
|
+
thinking: new Set(), thinkingStreaming: new Set(), thinkingCompleted: new Set(), streamActivity: newStreamActivity() });
|
|
124
159
|
this.#lastMessageRef = messageRef;
|
|
125
160
|
const draft = this.#draft(snapshot, "message.started", { role: messageRole, contentDigest: source ? digest(source) : null,
|
|
126
161
|
textChars: source ? source.length : null, imageCount: imageCount(message) }, { sourceObservedAt: message?.timestamp, messageRef });
|
|
@@ -157,6 +192,7 @@ export class PiSessionStreamAdapter {
|
|
|
157
192
|
}
|
|
158
193
|
messageUpdated(event: { assistantMessageEvent?: any }, snapshot: BridgeSnapshot): RuntimeEventDraft[] {
|
|
159
194
|
const update = event.assistantMessageEvent, active = this.#activeByRole.get("assistant"); if (!active || !update) return [];
|
|
195
|
+
observeStreamActivity(active.streamActivity, update.type, this.#now());
|
|
160
196
|
if (update.type === "text_delta" && typeof update.delta === "string") {
|
|
161
197
|
if (active.emittedEvents >= MAX_MESSAGE_STREAM_EVENTS) { active.truncated = true; return []; }
|
|
162
198
|
const remaining = MAX_STREAM_BUFFER - active.rawBuffer.length;
|
|
@@ -195,28 +231,34 @@ export class PiSessionStreamAdapter {
|
|
|
195
231
|
if (messageRole === "assistant" && (reason === "error" || reason === "aborted")) {
|
|
196
232
|
const error = safe(message?.errorMessage, 500);
|
|
197
233
|
const failed = this.#draft(snapshot, "message.failed", { role: "assistant", reason, errorCode: reason === "error" ? "assistant-message-error" : "assistant-message-aborted",
|
|
198
|
-
message: error.text || null, contentDigest: finalText.text ? digest(finalText.text) : null
|
|
234
|
+
message: error.text || null, contentDigest: finalText.text ? digest(finalText.text) : null,
|
|
235
|
+
streamActivity: { ...active.streamActivity } },
|
|
199
236
|
{ sourceObservedAt: message?.timestamp, messageRef: active.ref, redacted: finalText.redacted || error.redacted, truncated: finalText.truncated || error.truncated });
|
|
200
237
|
if (failed) drafts.push(failed); return drafts;
|
|
201
238
|
}
|
|
202
239
|
const completed = this.#draft(snapshot, "message.completed", { role: messageRole, contentDigest: finalText.text ? digest(finalText.text) : null,
|
|
203
240
|
contentRef: null, textPreview: messageRole === "tool-result" ? null : finalText.text.slice(0, 4_000), textChars: messageRole === "tool-result" ? null : finalText.text.length,
|
|
204
|
-
blockCount: Math.min(10_000, Array.isArray(message?.content) ? message.content.length : finalText.text ? 1 : 0), stopReason: reason, usage: usage(message)
|
|
241
|
+
blockCount: Math.min(10_000, Array.isArray(message?.content) ? message.content.length : finalText.text ? 1 : 0), stopReason: reason, usage: usage(message),
|
|
242
|
+
...(messageRole === "assistant" ? { streamActivity: { ...active.streamActivity } } : {}) },
|
|
205
243
|
{ sourceObservedAt: message?.timestamp, messageRef: active.ref, redacted: finalText.redacted, truncated: finalText.truncated || active.truncated });
|
|
206
244
|
if (completed) drafts.push(completed); return drafts;
|
|
207
245
|
}
|
|
208
246
|
turnEnded(event: { message?: unknown; toolResults?: unknown[] }, snapshot: BridgeSnapshot): RuntimeEventDraft[] {
|
|
209
247
|
const reason = stopReason(event.message), count = Array.isArray(event.toolResults) ? Math.min(10_000, event.toolResults.length) : 0;
|
|
248
|
+
const drafts = this.#settleActiveTools(snapshot, "turn-ended-before-tool-result");
|
|
210
249
|
const draft = this.#draft(snapshot, "turn.ended", { phase: "ended", finalMessageRef: this.#lastMessageRef, toolResultCount: count, stopReason: reason });
|
|
211
|
-
|
|
250
|
+
if (draft) drafts.push(draft);
|
|
251
|
+
return drafts;
|
|
212
252
|
}
|
|
213
|
-
toolStarted(event: { toolCallId?: unknown; toolName?: unknown }, snapshot: BridgeSnapshot): RuntimeEventDraft[] {
|
|
253
|
+
toolStarted(event: { toolCallId?: unknown; toolName?: unknown; args?: unknown }, snapshot: BridgeSnapshot): RuntimeEventDraft[] {
|
|
214
254
|
if (typeof event.toolCallId !== "string" || !event.toolCallId) return [];
|
|
215
255
|
const drafts = this.#activeByRole.get("assistant")
|
|
216
256
|
? this.#drainLines(snapshot, this.#activeByRole.get("assistant") as ActiveMessage, false) : [];
|
|
217
257
|
const name = safeToolName(event.toolName);
|
|
218
258
|
const ref = opaque("tool", [snapshot.identity?.sessionRef, event.toolCallId]), activityRef = opaque("activity", [snapshot.identity?.sessionRef, event.toolCallId]);
|
|
219
|
-
this.#toolRefs.set(event.toolCallId, ref); this.#
|
|
259
|
+
this.#toolRefs.set(event.toolCallId, ref); this.#toolNames.set(event.toolCallId, name);
|
|
260
|
+
this.#toolInputs.set(event.toolCallId, toolClassificationInput(event.args));
|
|
261
|
+
this.#lastToolProgress.set(event.toolCallId, 0);
|
|
220
262
|
const draft = this.#draft(snapshot, "activity.started", activityPayload("started", activityRef, name), { toolCallId: ref });
|
|
221
263
|
if (draft) drafts.push(draft);
|
|
222
264
|
return drafts;
|
|
@@ -231,19 +273,49 @@ export class PiSessionStreamAdapter {
|
|
|
231
273
|
const draft = this.#draft(snapshot, "activity.progress", activityPayload("progress", activityRef, name), { toolCallId: ref });
|
|
232
274
|
return draft ? [draft] : [];
|
|
233
275
|
}
|
|
234
|
-
toolEnded(event: { toolCallId?: unknown; toolName?: unknown; isError?: unknown }, snapshot: BridgeSnapshot): RuntimeEventDraft[] {
|
|
276
|
+
toolEnded(event: { toolCallId?: unknown; toolName?: unknown; result?: unknown; isError?: unknown }, snapshot: BridgeSnapshot): RuntimeEventDraft[] {
|
|
235
277
|
if (typeof event.toolCallId !== "string") return [];
|
|
236
278
|
const ref = this.#toolRefs.get(event.toolCallId); if (!ref) return [];
|
|
237
279
|
const name = safeToolName(event.toolName);
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
const
|
|
280
|
+
const reasonCode = classifyToolFailure(name, event.isError === true, event.result, this.#toolInputs.get(event.toolCallId));
|
|
281
|
+
const state = (event.isError === true || reasonCode !== null) && !handledToolFailure(reasonCode, name) ? "failed" : "finished";
|
|
282
|
+
const activityRef = opaque("activity", [snapshot.identity?.sessionRef, event.toolCallId]);
|
|
283
|
+
this.#toolRefs.delete(event.toolCallId); this.#toolNames.delete(event.toolCallId);
|
|
284
|
+
this.#toolInputs.delete(event.toolCallId); this.#lastToolProgress.delete(event.toolCallId);
|
|
285
|
+
const draft = this.#draft(snapshot, `activity.${state}`, activityPayload(state, activityRef, name, reasonCode), { toolCallId: ref });
|
|
241
286
|
return draft ? [draft] : [];
|
|
242
287
|
}
|
|
288
|
+
#settleActiveTools(snapshot: BridgeSnapshot, reasonCode: string): RuntimeEventDraft[] {
|
|
289
|
+
const drafts: RuntimeEventDraft[] = [];
|
|
290
|
+
for (const [rawToolCallId, ref] of this.#toolRefs) {
|
|
291
|
+
const toolName = this.#toolNames.get(rawToolCallId) ?? "tool";
|
|
292
|
+
const activityRef = opaque("activity", [snapshot.identity?.sessionRef, rawToolCallId]);
|
|
293
|
+
const draft = this.#draft(snapshot, "activity.aborted", activityPayload("aborted", activityRef, toolName, reasonCode),
|
|
294
|
+
{ toolCallId: ref, evidence: "derived" });
|
|
295
|
+
if (draft) drafts.push(draft);
|
|
296
|
+
}
|
|
297
|
+
this.#toolRefs.clear(); this.#toolNames.clear(); this.#toolInputs.clear(); this.#lastToolProgress.clear();
|
|
298
|
+
return drafts;
|
|
299
|
+
}
|
|
300
|
+
operationInterrupted(snapshot: BridgeSnapshot, reasonCode = "session-replaced-before-tool-result"): RuntimeEventDraft[] {
|
|
301
|
+
return this.#settleActiveTools(snapshot, reasonCode);
|
|
302
|
+
}
|
|
243
303
|
agentSettled(snapshot: BridgeSnapshot, hasPendingMessages: boolean | null): RuntimeEventDraft[] {
|
|
304
|
+
// A queued follow-up belongs to the same logical operation. Do not emit a
|
|
305
|
+
// terminal edge or clear stream identity between recovery turns.
|
|
306
|
+
if (hasPendingMessages === true) return [];
|
|
244
307
|
const value = hasPendingMessages === null ? { state: "unknown", value: null, reasonCode: "queue-fact-unavailable" }
|
|
245
308
|
: { state: "known", value: hasPendingMessages, reasonCode: null };
|
|
246
|
-
|
|
247
|
-
|
|
309
|
+
// Host-idle only proves that this agent operation stopped producing turns.
|
|
310
|
+
// A governed task is successful only after its durable contract is terminal.
|
|
311
|
+
// Fail closed here so a missed/late completion hook cannot paint an open
|
|
312
|
+
// task as completed in the WebUI.
|
|
313
|
+
const governedTaskOpen = Boolean(snapshot.identity?.taskRunId) && snapshot.taskState !== "terminal";
|
|
314
|
+
const drafts = this.#settleActiveTools(snapshot, "operation-settled-before-tool-result");
|
|
315
|
+
const draft = this.#draft(snapshot, "agent-operation.settled", {
|
|
316
|
+
settlement: governedTaskOpen ? "unknown" : "completed", lastStopReason: null, hasPendingMessages: value
|
|
317
|
+
});
|
|
318
|
+
if (draft) drafts.push(draft);
|
|
319
|
+
this.reset(); return drafts;
|
|
248
320
|
}
|
|
249
321
|
}
|
|
@@ -35,11 +35,19 @@ function timestamp(value: unknown): value is string {
|
|
|
35
35
|
if (typeof value !== "string" || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/.test(value)) return false;
|
|
36
36
|
const parsed = Date.parse(value); return Number.isFinite(parsed) && new Date(parsed).toISOString() === value;
|
|
37
37
|
}
|
|
38
|
+
function nullableRevision(value: unknown): value is string | null { return value === null || typeof value === "string" && REVISION.test(value); }
|
|
38
39
|
function wireIdentity(value: BridgeIdentity): BridgeIdentity { return { projectRef: value.projectRef, runtimeInstanceId: value.runtimeInstanceId,
|
|
39
40
|
sessionRef: value.sessionRef, taskId: value.taskId, taskRunId: value.taskRunId, agentOperationId: null, toolCallId: null }; }
|
|
40
41
|
function wireRevisions(value: Record<string, any>): BridgeRevisions { return { runtimeRevision: value.runtimeRevision, taskRevision: value.taskRevision,
|
|
41
42
|
controlRevision: value.controlRevision, workspaceRevision: value.workspaceRevision, indexRevision: value.indexRevision,
|
|
42
43
|
approvalRevision: value.approvalRevision, sessionOptionRevision: value.sessionOptionRevision, queueRevision: value.queueRevision }; }
|
|
44
|
+
function replayIdentityDisposition(record: Pick<SourceMutationEvidenceRecord, "projectRef" | "runtimeInstanceId" | "sessionRef" | "taskId" | "taskRunId">,
|
|
45
|
+
identity: BridgeIdentity): "task-identity-mismatch" | "runtime-or-session-replaced" | null {
|
|
46
|
+
if (record.taskId !== identity.taskId || record.taskRunId !== identity.taskRunId) return "task-identity-mismatch";
|
|
47
|
+
if (record.projectRef !== identity.projectRef || record.runtimeInstanceId !== identity.runtimeInstanceId || record.sessionRef !== identity.sessionRef)
|
|
48
|
+
return "runtime-or-session-replaced";
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
43
51
|
|
|
44
52
|
function receiptFromRecord(record: SourceMutationEvidenceRecord, deduplicated: boolean): SourceMutationReceipt {
|
|
45
53
|
if (record.action === "source.revert") throw new Error("source-mutation-evidence-action-mismatch");
|
|
@@ -109,8 +117,9 @@ export class SourceMutationController {
|
|
|
109
117
|
if (prior.length) {
|
|
110
118
|
if (prior.some((record) => record.commandId !== command.commandId || record.idempotencyKeyDigest !== keyDigest || record.actionDigest !== command.actionDigest
|
|
111
119
|
|| record.action !== command.action)) return this.#reject(command, "idempotency-payload-mismatch", "idempotency-payload-mismatch", false);
|
|
112
|
-
|
|
113
|
-
|
|
120
|
+
const dispositions = prior.map((record) => replayIdentityDisposition(record, identity)).filter(Boolean);
|
|
121
|
+
if (dispositions.length) return this.#reject(command, "identity-mismatch",
|
|
122
|
+
dispositions.includes("task-identity-mismatch") ? "task-identity-mismatch" : "runtime-or-session-replaced", false);
|
|
114
123
|
return receiptFromRecord(prior.at(-1)!, true);
|
|
115
124
|
}
|
|
116
125
|
const now = this.#now().getTime();
|
|
@@ -122,6 +131,20 @@ export class SourceMutationController {
|
|
|
122
131
|
let resolved: { projection: SourceMutationProjection; authority: SourceMutationAuthority | null };
|
|
123
132
|
try { resolved = await this.#resolve(command.action, command.payload.fileRef); }
|
|
124
133
|
catch { return this.#reject(command, "capability-unavailable", "mutation-preview-unavailable", true); }
|
|
134
|
+
const rebound = this.#bridge.snapshot();
|
|
135
|
+
if (rebound.state !== "ready" || !rebound.identity || !rebound.revisions)
|
|
136
|
+
return this.#reject(command, "resync-required", "mutation-binding-unavailable-after-preview", true);
|
|
137
|
+
const reboundIdentity = wireIdentity(rebound.identity), reboundRevisions = wireRevisions(rebound.revisions);
|
|
138
|
+
if (!same(reboundIdentity, identity)) {
|
|
139
|
+
const taskChanged = reboundIdentity.taskId !== identity.taskId || reboundIdentity.taskRunId !== identity.taskRunId;
|
|
140
|
+
return this.#reject(command, "identity-mismatch", taskChanged ? "task-identity-mismatch" : "runtime-or-session-replaced", false);
|
|
141
|
+
}
|
|
142
|
+
if (rebound.taskState === "terminal") return this.#reject(command, "terminal-task", "task-terminal-after-preview", false);
|
|
143
|
+
if (rebound.liveness !== "idle") return this.#reject(command, "capability-unavailable", "agent-not-idle-after-preview", true);
|
|
144
|
+
if (command.expectedRevisions.runtimeRevision !== reboundRevisions.runtimeRevision
|
|
145
|
+
|| command.expectedRevisions.taskRevision !== reboundRevisions.taskRevision
|
|
146
|
+
|| command.expectedRevisions.controlRevision !== reboundRevisions.controlRevision)
|
|
147
|
+
return this.#reject(command, "stale-revision", "stale-task-control-revision-after-preview", true);
|
|
125
148
|
if (!resolved.authority || resolved.projection.state !== "ready" || !resolved.projection.target)
|
|
126
149
|
return this.#reject(command, "capability-unavailable", resolved.projection.reasonCode ?? "mutation-preview-unavailable", true);
|
|
127
150
|
const target = resolved.projection.target;
|
|
@@ -185,8 +208,11 @@ export class SourceMutationController {
|
|
|
185
208
|
|| command.identity.agentOperationId !== null || command.identity.toolCallId !== null) return "invalid-command-identity";
|
|
186
209
|
const preimageKeys = [...REVISION_KEYS, "workspacePreimage", "indexPreimage", "patchPreimage"];
|
|
187
210
|
if (!exactKeys(command.expectedRevisions, preimageKeys) || !REVISION.test(command.expectedRevisions.runtimeRevision)
|
|
188
|
-
|| !REVISION.test(command.expectedRevisions.taskRevision ?? "") || !REVISION.test(command.expectedRevisions.
|
|
211
|
+
|| !REVISION.test(command.expectedRevisions.taskRevision ?? "") || !REVISION.test(command.expectedRevisions.controlRevision ?? "")
|
|
212
|
+
|| !REVISION.test(command.expectedRevisions.workspaceRevision ?? "")
|
|
189
213
|
|| !REVISION.test(command.expectedRevisions.indexRevision ?? "") || !WORKSPACE.test(command.expectedRevisions.workspacePreimage)
|
|
214
|
+
|| ![command.expectedRevisions.approvalRevision, command.expectedRevisions.sessionOptionRevision,
|
|
215
|
+
command.expectedRevisions.queueRevision].every(nullableRevision)
|
|
190
216
|
|| !DIGEST.test(command.expectedRevisions.indexPreimage) || !DIGEST.test(command.expectedRevisions.patchPreimage)) return "invalid-mutation-authority";
|
|
191
217
|
if (!exactKeys(command.payload, ["fileRef", "hunkRefs", "contentDigest"]) || !REF.test(command.payload.fileRef)
|
|
192
218
|
|| !Array.isArray(command.payload.hunkRefs) || command.payload.hunkRefs.length > 128
|
|
@@ -33,6 +33,13 @@ function revisions(value: Record<string, any>, record?: SourceHandoffRecord): Br
|
|
|
33
33
|
taskRevision: record?.taskRevision ?? value.taskRevision, controlRevision: value.controlRevision,
|
|
34
34
|
workspaceRevision: record?.workspaceRevision ?? value.workspaceRevision, indexRevision: value.indexRevision,
|
|
35
35
|
approvalRevision: value.approvalRevision, sessionOptionRevision: value.sessionOptionRevision, queueRevision: value.queueRevision }; }
|
|
36
|
+
function replayIdentityDisposition(record: Pick<SourceHandoffRecord, "projectRef" | "runtimeInstanceId" | "sessionRef" | "taskId" | "taskRunId">,
|
|
37
|
+
current: BridgeIdentity): "task-identity-mismatch" | "runtime-or-session-replaced" | null {
|
|
38
|
+
if (record.taskId !== current.taskId || record.taskRunId !== current.taskRunId) return "task-identity-mismatch";
|
|
39
|
+
if (record.projectRef !== current.projectRef || record.runtimeInstanceId !== current.runtimeInstanceId || record.sessionRef !== current.sessionRef)
|
|
40
|
+
return "runtime-or-session-replaced";
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
36
43
|
|
|
37
44
|
export class SourceOpenController {
|
|
38
45
|
readonly #bridge: SameSessionPiBridge; readonly #root: string; readonly #resolve: (fileRef: string) => Promise<SourceOpenAuthority | null>;
|
|
@@ -55,8 +62,9 @@ export class SourceOpenController {
|
|
|
55
62
|
if (prior.length) {
|
|
56
63
|
if (prior.some((record) => record.commandId !== command.commandId || record.idempotencyKeyDigest !== keyDigest || record.actionDigest !== command.actionDigest))
|
|
57
64
|
return this.#reject(command, "idempotency-payload-mismatch", "idempotency-payload-mismatch", false);
|
|
58
|
-
|
|
59
|
-
|
|
65
|
+
const dispositions = prior.map((record) => replayIdentityDisposition(record, currentIdentity)).filter(Boolean);
|
|
66
|
+
if (dispositions.length) return this.#reject(command, "identity-mismatch",
|
|
67
|
+
dispositions.includes("task-identity-mismatch") ? "task-identity-mismatch" : "runtime-or-session-replaced", false);
|
|
60
68
|
const last = prior.at(-1)!; if (last.phase !== "requested") return this.#receipt(last, currentRevisions, true);
|
|
61
69
|
const uncertain = this.#append(command, currentIdentity, keyDigest, last, "uncertain", "effect-unknown", "source-open-outcome-unknown");
|
|
62
70
|
return this.#receipt(uncertain, currentRevisions, true);
|
|
@@ -64,9 +72,22 @@ export class SourceOpenController {
|
|
|
64
72
|
const now = this.#now().getTime(); if (Date.parse(command.requestedAt) > now + 30_000) return this.#reject(command, "invalid-command", "requested-at-in-future", false);
|
|
65
73
|
if (now > Date.parse(command.expiresAt)) return this.#reject(command, "expired", "command-expired", false);
|
|
66
74
|
if (!same(command.identity, currentIdentity)) return this.#reject(command, "identity-mismatch", "identity-mismatch", false);
|
|
67
|
-
if (command.expectedRevisions.runtimeRevision !== currentRevisions.runtimeRevision || command.expectedRevisions.taskRevision !== currentRevisions.taskRevision
|
|
68
|
-
|
|
75
|
+
if (command.expectedRevisions.runtimeRevision !== currentRevisions.runtimeRevision || command.expectedRevisions.taskRevision !== currentRevisions.taskRevision
|
|
76
|
+
|| command.expectedRevisions.controlRevision !== currentRevisions.controlRevision)
|
|
77
|
+
return this.#reject(command, "stale-revision", "stale-task-control-revision", true);
|
|
69
78
|
let authority: SourceOpenAuthority | null; try { authority = await this.#resolve(command.payload.fileRef); } catch { authority = null; }
|
|
79
|
+
const rebound = this.#bridge.snapshot();
|
|
80
|
+
if (rebound.state !== "ready" || !rebound.identity || !rebound.revisions)
|
|
81
|
+
return this.#reject(command, "resync-required", "source-open-binding-unavailable-after-target-resolution", true);
|
|
82
|
+
const reboundIdentity = identity(rebound.identity), reboundRevisions = revisions(rebound.revisions);
|
|
83
|
+
if (!same(reboundIdentity, currentIdentity)) {
|
|
84
|
+
const taskChanged = reboundIdentity.taskId !== currentIdentity.taskId || reboundIdentity.taskRunId !== currentIdentity.taskRunId;
|
|
85
|
+
return this.#reject(command, "identity-mismatch", taskChanged ? "task-identity-mismatch" : "runtime-or-session-replaced", false);
|
|
86
|
+
}
|
|
87
|
+
if (command.expectedRevisions.runtimeRevision !== reboundRevisions.runtimeRevision
|
|
88
|
+
|| command.expectedRevisions.taskRevision !== reboundRevisions.taskRevision
|
|
89
|
+
|| command.expectedRevisions.controlRevision !== reboundRevisions.controlRevision)
|
|
90
|
+
return this.#reject(command, "stale-revision", "stale-task-control-revision-after-target-resolution", true);
|
|
70
91
|
if (!authority) return this.#reject(command, "capability-unavailable", "source-open-target-unavailable", true);
|
|
71
92
|
if (authority.target.taskRevision !== command.expectedRevisions.taskRevision || authority.target.workspaceRevision !== command.expectedRevisions.workspaceRevision)
|
|
72
93
|
return this.#reject(command, "stale-revision", "source-open-target-stale", true);
|
|
@@ -110,9 +131,10 @@ export class SourceOpenController {
|
|
|
110
131
|
|| command.identity.agentOperationId !== null || command.identity.toolCallId !== null) return "invalid-command-identity";
|
|
111
132
|
if (!exact(command.expectedRevisions, [...REVISION_KEYS, "workspacePreimage", "indexPreimage", "patchPreimage"])
|
|
112
133
|
|| !REVISION.test(command.expectedRevisions.runtimeRevision) || !REVISION.test(command.expectedRevisions.taskRevision ?? "")
|
|
113
|
-
|| !REVISION.test(command.expectedRevisions.
|
|
114
|
-
||
|
|
115
|
-
|
|
134
|
+
|| !REVISION.test(command.expectedRevisions.controlRevision ?? "") || !REVISION.test(command.expectedRevisions.workspaceRevision ?? "")
|
|
135
|
+
|| command.expectedRevisions.workspacePreimage !== null
|
|
136
|
+
|| ![command.expectedRevisions.indexRevision, command.expectedRevisions.approvalRevision, command.expectedRevisions.sessionOptionRevision,
|
|
137
|
+
command.expectedRevisions.queueRevision].every(nullableRevision)
|
|
116
138
|
|| command.expectedRevisions.indexPreimage !== null || command.expectedRevisions.patchPreimage !== null) return "invalid-source-open-authority";
|
|
117
139
|
if (!exact(command.payload, ["fileRef", "line", "column"]) || !REF.test(command.payload.fileRef)
|
|
118
140
|
|| command.payload.line !== null && (!Number.isInteger(command.payload.line) || command.payload.line < 1 || command.payload.line > 100_000_000)
|
|
@@ -38,6 +38,13 @@ function wireIdentity(value: BridgeIdentity): BridgeIdentity { return { projectR
|
|
|
38
38
|
function wireRevisions(value: Record<string, any>): BridgeRevisions { return { runtimeRevision: value.runtimeRevision, taskRevision: value.taskRevision,
|
|
39
39
|
controlRevision: value.controlRevision, workspaceRevision: value.workspaceRevision, indexRevision: value.indexRevision,
|
|
40
40
|
approvalRevision: value.approvalRevision, sessionOptionRevision: value.sessionOptionRevision, queueRevision: value.queueRevision }; }
|
|
41
|
+
function replayIdentityDisposition(record: Pick<SourceMutationEvidenceRecord, "projectRef" | "runtimeInstanceId" | "sessionRef" | "taskId" | "taskRunId">,
|
|
42
|
+
identity: BridgeIdentity): "task-identity-mismatch" | "runtime-or-session-replaced" | null {
|
|
43
|
+
if (record.taskId !== identity.taskId || record.taskRunId !== identity.taskRunId) return "task-identity-mismatch";
|
|
44
|
+
if (record.projectRef !== identity.projectRef || record.runtimeInstanceId !== identity.runtimeInstanceId || record.sessionRef !== identity.sessionRef)
|
|
45
|
+
return "runtime-or-session-replaced";
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
41
48
|
function receipt(record: SourceMutationEvidenceRecord, deduplicated: boolean): SourceRevertReceipt {
|
|
42
49
|
const identity = { projectRef: record.projectRef, runtimeInstanceId: record.runtimeInstanceId, sessionRef: record.sessionRef,
|
|
43
50
|
taskId: record.taskId, taskRunId: record.taskRunId, agentOperationId: null, toolCallId: null } as BridgeIdentity;
|
|
@@ -90,8 +97,9 @@ export class SourceRevertController {
|
|
|
90
97
|
if (prior.length) {
|
|
91
98
|
if (prior.some((record) => record.commandId !== command.commandId || record.idempotencyKeyDigest !== keyDigest || record.actionDigest !== command.actionDigest
|
|
92
99
|
|| record.action !== command.action)) return this.#reject(command, "idempotency-payload-mismatch", "idempotency-payload-mismatch", false);
|
|
93
|
-
|
|
94
|
-
|
|
100
|
+
const dispositions = prior.map((record) => replayIdentityDisposition(record, identity)).filter(Boolean);
|
|
101
|
+
if (dispositions.length) return this.#reject(command, "identity-mismatch",
|
|
102
|
+
dispositions.includes("task-identity-mismatch") ? "task-identity-mismatch" : "runtime-or-session-replaced", false);
|
|
95
103
|
return receipt(prior.at(-1)!, true);
|
|
96
104
|
}
|
|
97
105
|
const now = this.#now().getTime();
|
|
@@ -103,10 +111,25 @@ export class SourceRevertController {
|
|
|
103
111
|
let resolved: { projection: SourceRevertProjection; authority: SourceRevertAuthority | null };
|
|
104
112
|
try { resolved = await this.#resolve(command.payload.fileRef, command.payload.hunkRefs); }
|
|
105
113
|
catch { return this.#reject(command, "capability-unavailable", "revert-preview-unavailable", true); }
|
|
114
|
+
const rebound = this.#bridge.snapshot();
|
|
115
|
+
if (rebound.state !== "ready" || !rebound.identity || !rebound.revisions)
|
|
116
|
+
return this.#reject(command, "resync-required", "revert-binding-unavailable-after-preview", true);
|
|
117
|
+
const reboundIdentity = wireIdentity(rebound.identity), reboundRevisions = wireRevisions(rebound.revisions);
|
|
118
|
+
if (!same(reboundIdentity, identity)) {
|
|
119
|
+
const taskChanged = reboundIdentity.taskId !== identity.taskId || reboundIdentity.taskRunId !== identity.taskRunId;
|
|
120
|
+
return this.#reject(command, "identity-mismatch", taskChanged ? "task-identity-mismatch" : "runtime-or-session-replaced", false);
|
|
121
|
+
}
|
|
122
|
+
if (rebound.taskState === "terminal") return this.#reject(command, "terminal-task", "task-terminal-after-preview", false);
|
|
123
|
+
if (rebound.liveness !== "idle") return this.#reject(command, "capability-unavailable", "agent-not-idle-after-preview", true);
|
|
124
|
+
if (command.expectedRevisions.runtimeRevision !== reboundRevisions.runtimeRevision
|
|
125
|
+
|| command.expectedRevisions.taskRevision !== reboundRevisions.taskRevision
|
|
126
|
+
|| command.expectedRevisions.controlRevision !== reboundRevisions.controlRevision)
|
|
127
|
+
return this.#reject(command, "stale-revision", "stale-task-control-revision-after-preview", true);
|
|
106
128
|
if (!resolved.authority || resolved.projection.state !== "ready" || !resolved.projection.target)
|
|
107
129
|
return this.#reject(command, "capability-unavailable", resolved.projection.reasonCode ?? "revert-preview-unavailable", true);
|
|
108
130
|
const target = resolved.projection.target;
|
|
109
|
-
if (!this.#matches(command, target) || now > Date.parse(target.expiresAt))
|
|
131
|
+
if (!this.#matches(command, target) || this.#now().getTime() > Date.parse(target.expiresAt))
|
|
132
|
+
return this.#reject(command, "stale-revision", "revert-preview-stale", true);
|
|
110
133
|
const before = { ...bridgeRevisions, workspaceRevision: target.workspaceRevision, indexRevision: target.indexRevision };
|
|
111
134
|
let requested: SourceMutationEvidenceRecord;
|
|
112
135
|
try { requested = appendSourceMutationEvidence({ projectRoot: this.#projectRoot, projectRef: identity.projectRef, runtimeInstanceId: identity.runtimeInstanceId,
|