@retaw106/mmc-oc 0.0.0-stage → 1.2.2
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/dist/agents/historian.d.ts +4 -0
- package/dist/agents/historian.d.ts.map +1 -0
- package/dist/agents/language-directive.d.ts +26 -0
- package/dist/agents/language-directive.d.ts.map +1 -0
- package/dist/agents/magic-context-prompt.d.ts +5 -0
- package/dist/agents/magic-context-prompt.d.ts.map +1 -0
- package/dist/agents/memory-maintainer.d.ts +96 -0
- package/dist/agents/memory-maintainer.d.ts.map +1 -0
- package/dist/config/agent-disable.d.ts +29 -0
- package/dist/config/agent-disable.d.ts.map +1 -0
- package/dist/config/config-paths.d.ts +7 -0
- package/dist/config/config-paths.d.ts.map +1 -0
- package/dist/config/index.d.ts +69 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/live-run-config.d.ts +11 -0
- package/dist/config/live-run-config.d.ts.map +1 -0
- package/dist/config/live-snapshot.d.ts +32 -0
- package/dist/config/live-snapshot.d.ts.map +1 -0
- package/dist/config/migrate-experimental.d.ts +26 -0
- package/dist/config/migrate-experimental.d.ts.map +1 -0
- package/dist/config/profiles.d.ts +22 -0
- package/dist/config/profiles.d.ts.map +1 -0
- package/dist/config/project-security.d.ts +124 -0
- package/dist/config/project-security.d.ts.map +1 -0
- package/dist/config/prune-config-leaf.d.ts +26 -0
- package/dist/config/prune-config-leaf.d.ts.map +1 -0
- package/dist/config/raw-loader.d.ts +42 -0
- package/dist/config/raw-loader.d.ts.map +1 -0
- package/dist/config/removed-agent-config.d.ts +8 -0
- package/dist/config/removed-agent-config.d.ts.map +1 -0
- package/dist/config/schema/agent-overrides.d.ts +52 -0
- package/dist/config/schema/agent-overrides.d.ts.map +1 -0
- package/dist/config/schema/magic-context.d.ts +805 -0
- package/dist/config/schema/magic-context.d.ts.map +1 -0
- package/dist/config/variable.d.ts +48 -0
- package/dist/config/variable.d.ts.map +1 -0
- package/dist/context-a6px04s0.js +23932 -0
- package/dist/derive-budgets-fhk00zv8.js +18 -0
- package/dist/features/magic-context/compaction-marker.d.ts +211 -0
- package/dist/features/magic-context/compaction-marker.d.ts.map +1 -0
- package/dist/features/magic-context/compaction.d.ts +7 -0
- package/dist/features/magic-context/compaction.d.ts.map +1 -0
- package/dist/features/magic-context/compartment-events.d.ts +50 -0
- package/dist/features/magic-context/compartment-events.d.ts.map +1 -0
- package/dist/features/magic-context/compartment-lease.d.ts +28 -0
- package/dist/features/magic-context/compartment-lease.d.ts.map +1 -0
- package/dist/features/magic-context/compartment-storage.d.ts +178 -0
- package/dist/features/magic-context/compartment-storage.d.ts.map +1 -0
- package/dist/features/magic-context/compression-depth-storage.d.ts +14 -0
- package/dist/features/magic-context/compression-depth-storage.d.ts.map +1 -0
- package/dist/features/magic-context/context-authority.d.ts +15 -0
- package/dist/features/magic-context/context-authority.d.ts.map +1 -0
- package/dist/features/magic-context/fail-closed-block.d.ts +117 -0
- package/dist/features/magic-context/fail-closed-block.d.ts.map +1 -0
- package/dist/features/magic-context/index.d.ts +10 -0
- package/dist/features/magic-context/index.d.ts.map +1 -0
- package/dist/features/magic-context/literal-probes.d.ts +24 -0
- package/dist/features/magic-context/literal-probes.d.ts.map +1 -0
- package/dist/features/magic-context/lkg-prefix-chunks.d.ts +53 -0
- package/dist/features/magic-context/lkg-prefix-chunks.d.ts.map +1 -0
- package/dist/features/magic-context/memory/constants.d.ts +16 -0
- package/dist/features/magic-context/memory/constants.d.ts.map +1 -0
- package/dist/features/magic-context/memory/index.d.ts +11 -0
- package/dist/features/magic-context/memory/index.d.ts.map +1 -0
- package/dist/features/magic-context/memory/memory-diagnostics.d.ts +6 -0
- package/dist/features/magic-context/memory/memory-diagnostics.d.ts.map +1 -0
- package/dist/features/magic-context/memory/memory-selection.d.ts +12 -0
- package/dist/features/magic-context/memory/memory-selection.d.ts.map +1 -0
- package/dist/features/magic-context/memory/memory-visibility.d.ts +46 -0
- package/dist/features/magic-context/memory/memory-visibility.d.ts.map +1 -0
- package/dist/features/magic-context/memory/normalize-hash.d.ts +3 -0
- package/dist/features/magic-context/memory/normalize-hash.d.ts.map +1 -0
- package/dist/features/magic-context/memory/project-identity-cache.d.ts +7 -0
- package/dist/features/magic-context/memory/project-identity-cache.d.ts.map +1 -0
- package/dist/features/magic-context/memory/project-identity.d.ts +97 -0
- package/dist/features/magic-context/memory/project-identity.d.ts.map +1 -0
- package/dist/features/magic-context/memory/promotion.d.ts +26 -0
- package/dist/features/magic-context/memory/promotion.d.ts.map +1 -0
- package/dist/features/magic-context/memory/relocate-memory.d.ts +58 -0
- package/dist/features/magic-context/memory/relocate-memory.d.ts.map +1 -0
- package/dist/features/magic-context/memory/storage-memory-fts.d.ts +11 -0
- package/dist/features/magic-context/memory/storage-memory-fts.d.ts.map +1 -0
- package/dist/features/magic-context/memory/storage-memory-verifications.d.ts +35 -0
- package/dist/features/magic-context/memory/storage-memory-verifications.d.ts.map +1 -0
- package/dist/features/magic-context/memory/storage-memory.d.ts +89 -0
- package/dist/features/magic-context/memory/storage-memory.d.ts.map +1 -0
- package/dist/features/magic-context/memory/types.d.ts +59 -0
- package/dist/features/magic-context/memory/types.d.ts.map +1 -0
- package/dist/features/magic-context/memory/verification-paths.d.ts +48 -0
- package/dist/features/magic-context/memory/verification-paths.d.ts.map +1 -0
- package/dist/features/magic-context/memory/visibility.d.ts +6 -0
- package/dist/features/magic-context/memory/visibility.d.ts.map +1 -0
- package/dist/features/magic-context/memory-maintainer/apply.d.ts +65 -0
- package/dist/features/magic-context/memory-maintainer/apply.d.ts.map +1 -0
- package/dist/features/magic-context/memory-maintainer/budget.d.ts +75 -0
- package/dist/features/magic-context/memory-maintainer/budget.d.ts.map +1 -0
- package/dist/features/magic-context/memory-maintainer/coverage.d.ts +91 -0
- package/dist/features/magic-context/memory-maintainer/coverage.d.ts.map +1 -0
- package/dist/features/magic-context/memory-maintainer/dream-state.d.ts +18 -0
- package/dist/features/magic-context/memory-maintainer/dream-state.d.ts.map +1 -0
- package/dist/features/magic-context/memory-maintainer/launcher.d.ts +119 -0
- package/dist/features/magic-context/memory-maintainer/launcher.d.ts.map +1 -0
- package/dist/features/magic-context/memory-maintainer/lease.d.ts +56 -0
- package/dist/features/magic-context/memory-maintainer/lease.d.ts.map +1 -0
- package/dist/features/magic-context/memory-maintainer/manifest.d.ts +127 -0
- package/dist/features/magic-context/memory-maintainer/manifest.d.ts.map +1 -0
- package/dist/features/magic-context/memory-maintainer/manual-commands.d.ts +46 -0
- package/dist/features/magic-context/memory-maintainer/manual-commands.d.ts.map +1 -0
- package/dist/features/magic-context/memory-maintainer/oc2-adapter.d.ts +79 -0
- package/dist/features/magic-context/memory-maintainer/oc2-adapter.d.ts.map +1 -0
- package/dist/features/magic-context/memory-maintainer/pause-report.d.ts +37 -0
- package/dist/features/magic-context/memory-maintainer/pause-report.d.ts.map +1 -0
- package/dist/features/magic-context/memory-maintainer/pipeline.d.ts +199 -0
- package/dist/features/magic-context/memory-maintainer/pipeline.d.ts.map +1 -0
- package/dist/features/magic-context/memory-maintainer/provider-output-failure.d.ts +15 -0
- package/dist/features/magic-context/memory-maintainer/provider-output-failure.d.ts.map +1 -0
- package/dist/features/magic-context/memory-maintainer/schedule-storage.d.ts +76 -0
- package/dist/features/magic-context/memory-maintainer/schedule-storage.d.ts.map +1 -0
- package/dist/features/magic-context/memory-maintainer/schedule.d.ts +90 -0
- package/dist/features/magic-context/memory-maintainer/schedule.d.ts.map +1 -0
- package/dist/features/magic-context/merged-reasoning-decisions.d.ts +6 -0
- package/dist/features/magic-context/merged-reasoning-decisions.d.ts.map +1 -0
- package/dist/features/magic-context/message-fts-rowid-map.d.ts +50 -0
- package/dist/features/magic-context/message-fts-rowid-map.d.ts.map +1 -0
- package/dist/features/magic-context/message-fts-session-filter.d.ts +14 -0
- package/dist/features/magic-context/message-fts-session-filter.d.ts.map +1 -0
- package/dist/features/magic-context/message-index-async.d.ts +33 -0
- package/dist/features/magic-context/message-index-async.d.ts.map +1 -0
- package/dist/features/magic-context/message-index-sweep.d.ts +11 -0
- package/dist/features/magic-context/message-index-sweep.d.ts.map +1 -0
- package/dist/features/magic-context/message-index.d.ts +88 -0
- package/dist/features/magic-context/message-index.d.ts.map +1 -0
- package/dist/features/magic-context/message-time-backfill.d.ts +19 -0
- package/dist/features/magic-context/message-time-backfill.d.ts.map +1 -0
- package/dist/features/magic-context/migration-v2-write-split.d.ts +62 -0
- package/dist/features/magic-context/migration-v2-write-split.d.ts.map +1 -0
- package/dist/features/magic-context/migrations.d.ts +73 -0
- package/dist/features/magic-context/migrations.d.ts.map +1 -0
- package/dist/features/magic-context/mock-database.d.ts +3 -0
- package/dist/features/magic-context/mock-database.d.ts.map +1 -0
- package/dist/features/magic-context/mural/storage-mural-cues.d.ts +65 -0
- package/dist/features/magic-context/mural/storage-mural-cues.d.ts.map +1 -0
- package/dist/features/magic-context/no-content-compartment.d.ts +12 -0
- package/dist/features/magic-context/no-content-compartment.d.ts.map +1 -0
- package/dist/features/magic-context/opencode2-relabel.d.ts +132 -0
- package/dist/features/magic-context/opencode2-relabel.d.ts.map +1 -0
- package/dist/features/magic-context/overflow-detection.d.ts +108 -0
- package/dist/features/magic-context/overflow-detection.d.ts.map +1 -0
- package/dist/features/magic-context/pi-content-decisions.d.ts +9 -0
- package/dist/features/magic-context/pi-content-decisions.d.ts.map +1 -0
- package/dist/features/magic-context/project-identity.d.ts +2 -0
- package/dist/features/magic-context/project-identity.d.ts.map +1 -0
- package/dist/features/magic-context/protection-window.d.ts +79 -0
- package/dist/features/magic-context/protection-window.d.ts.map +1 -0
- package/dist/features/magic-context/range-parser.d.ts +18 -0
- package/dist/features/magic-context/range-parser.d.ts.map +1 -0
- package/dist/features/magic-context/reclaim-protection.d.ts +13 -0
- package/dist/features/magic-context/reclaim-protection.d.ts.map +1 -0
- package/dist/features/magic-context/resolve-subagent-fallback.d.ts +42 -0
- package/dist/features/magic-context/resolve-subagent-fallback.d.ts.map +1 -0
- package/dist/features/magic-context/scheduler.d.ts +20 -0
- package/dist/features/magic-context/scheduler.d.ts.map +1 -0
- package/dist/features/magic-context/schema-fence-probe.d.ts +29 -0
- package/dist/features/magic-context/schema-fence-probe.d.ts.map +1 -0
- package/dist/features/magic-context/search.d.ts +118 -0
- package/dist/features/magic-context/search.d.ts.map +1 -0
- package/dist/features/magic-context/session-cache-ttl.d.ts +10 -0
- package/dist/features/magic-context/session-cache-ttl.d.ts.map +1 -0
- package/dist/features/magic-context/session-decision-calibration.d.ts +31 -0
- package/dist/features/magic-context/session-decision-calibration.d.ts.map +1 -0
- package/dist/features/magic-context/session-project-backfill.d.ts +37 -0
- package/dist/features/magic-context/session-project-backfill.d.ts.map +1 -0
- package/dist/features/magic-context/session-project-storage.d.ts +23 -0
- package/dist/features/magic-context/session-project-storage.d.ts.map +1 -0
- package/dist/features/magic-context/storage-caveman-rules.d.ts +21 -0
- package/dist/features/magic-context/storage-caveman-rules.d.ts.map +1 -0
- package/dist/features/magic-context/storage-clone.d.ts +44 -0
- package/dist/features/magic-context/storage-clone.d.ts.map +1 -0
- package/dist/features/magic-context/storage-db.d.ts +183 -0
- package/dist/features/magic-context/storage-db.d.ts.map +1 -0
- package/dist/features/magic-context/storage-historian-runs.d.ts +79 -0
- package/dist/features/magic-context/storage-historian-runs.d.ts.map +1 -0
- package/dist/features/magic-context/storage-identity-merge.d.ts +26 -0
- package/dist/features/magic-context/storage-identity-merge.d.ts.map +1 -0
- package/dist/features/magic-context/storage-identity-rekey-map.d.ts +11 -0
- package/dist/features/magic-context/storage-identity-rekey-map.d.ts.map +1 -0
- package/dist/features/magic-context/storage-m0-mutation-log.d.ts +22 -0
- package/dist/features/magic-context/storage-m0-mutation-log.d.ts.map +1 -0
- package/dist/features/magic-context/storage-memory-mutation-log.d.ts +29 -0
- package/dist/features/magic-context/storage-memory-mutation-log.d.ts.map +1 -0
- package/dist/features/magic-context/storage-meta-persisted.d.ts +623 -0
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -0
- package/dist/features/magic-context/storage-meta-session.d.ts +14 -0
- package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -0
- package/dist/features/magic-context/storage-meta-shared.d.ts +102 -0
- package/dist/features/magic-context/storage-meta-shared.d.ts.map +1 -0
- package/dist/features/magic-context/storage-meta.d.ts +4 -0
- package/dist/features/magic-context/storage-meta.d.ts.map +1 -0
- package/dist/features/magic-context/storage-native-replay.d.ts +29 -0
- package/dist/features/magic-context/storage-native-replay.d.ts.map +1 -0
- package/dist/features/magic-context/storage-notes.d.ts +80 -0
- package/dist/features/magic-context/storage-notes.d.ts.map +1 -0
- package/dist/features/magic-context/storage-ops.d.ts +14 -0
- package/dist/features/magic-context/storage-ops.d.ts.map +1 -0
- package/dist/features/magic-context/storage-primers.d.ts +96 -0
- package/dist/features/magic-context/storage-primers.d.ts.map +1 -0
- package/dist/features/magic-context/storage-project-state.d.ts +19 -0
- package/dist/features/magic-context/storage-project-state.d.ts.map +1 -0
- package/dist/features/magic-context/storage-reasoning-removal.d.ts +30 -0
- package/dist/features/magic-context/storage-reasoning-removal.d.ts.map +1 -0
- package/dist/features/magic-context/storage-replay-document.d.ts +72 -0
- package/dist/features/magic-context/storage-replay-document.d.ts.map +1 -0
- package/dist/features/magic-context/storage-schema-helpers.d.ts +31 -0
- package/dist/features/magic-context/storage-schema-helpers.d.ts.map +1 -0
- package/dist/features/magic-context/storage-session-tables.d.ts +18 -0
- package/dist/features/magic-context/storage-session-tables.d.ts.map +1 -0
- package/dist/features/magic-context/storage-source.d.ts +5 -0
- package/dist/features/magic-context/storage-source.d.ts.map +1 -0
- package/dist/features/magic-context/storage-subagent-invocations.d.ts +62 -0
- package/dist/features/magic-context/storage-subagent-invocations.d.ts.map +1 -0
- package/dist/features/magic-context/storage-tags.d.ts +542 -0
- package/dist/features/magic-context/storage-tags.d.ts.map +1 -0
- package/dist/features/magic-context/storage-unavailable-reason.d.ts +17 -0
- package/dist/features/magic-context/storage-unavailable-reason.d.ts.map +1 -0
- package/dist/features/magic-context/storage-v22-backfill-failures.d.ts +26 -0
- package/dist/features/magic-context/storage-v22-backfill-failures.d.ts.map +1 -0
- package/dist/features/magic-context/storage.d.ts +23 -0
- package/dist/features/magic-context/storage.d.ts.map +1 -0
- package/dist/features/magic-context/store-generation-rebase.d.ts +188 -0
- package/dist/features/magic-context/store-generation-rebase.d.ts.map +1 -0
- package/dist/features/magic-context/subagent-token-capture.d.ts +35 -0
- package/dist/features/magic-context/subagent-token-capture.d.ts.map +1 -0
- package/dist/features/magic-context/tag-input.d.ts +4 -0
- package/dist/features/magic-context/tag-input.d.ts.map +1 -0
- package/dist/features/magic-context/tagger.d.ts +119 -0
- package/dist/features/magic-context/tagger.d.ts.map +1 -0
- package/dist/features/magic-context/tool-definition-tokens.d.ts +90 -0
- package/dist/features/magic-context/tool-definition-tokens.d.ts.map +1 -0
- package/dist/features/magic-context/tool-owner-backfill.d.ts +93 -0
- package/dist/features/magic-context/tool-owner-backfill.d.ts.map +1 -0
- package/dist/features/magic-context/transform-decision-log.d.ts +110 -0
- package/dist/features/magic-context/transform-decision-log.d.ts.map +1 -0
- package/dist/features/magic-context/types.d.ts +133 -0
- package/dist/features/magic-context/types.d.ts.map +1 -0
- package/dist/features/magic-context/window-report-ledger.d.ts +70 -0
- package/dist/features/magic-context/window-report-ledger.d.ts.map +1 -0
- package/dist/features/magic-context/work-metrics.d.ts +79 -0
- package/dist/features/magic-context/work-metrics.d.ts.map +1 -0
- package/dist/features/magic-context/workspaces.d.ts +28 -0
- package/dist/features/magic-context/workspaces.d.ts.map +1 -0
- package/dist/hooks/auto-update-checker/semver.d.ts +26 -0
- package/dist/hooks/auto-update-checker/semver.d.ts.map +1 -0
- package/dist/hooks/magic-context/apply-operations.d.ts +158 -0
- package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -0
- package/dist/hooks/magic-context/auto-search-deadline.d.ts +10 -0
- package/dist/hooks/magic-context/auto-search-deadline.d.ts.map +1 -0
- package/dist/hooks/magic-context/auto-search-hint.d.ts +36 -0
- package/dist/hooks/magic-context/auto-search-hint.d.ts.map +1 -0
- package/dist/hooks/magic-context/auto-search-runner.d.ts +60 -0
- package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -0
- package/dist/hooks/magic-context/cache-busting-signals.d.ts +42 -0
- package/dist/hooks/magic-context/cache-busting-signals.d.ts.map +1 -0
- package/dist/hooks/magic-context/caveman-cleanup.d.ts +98 -0
- package/dist/hooks/magic-context/caveman-cleanup.d.ts.map +1 -0
- package/dist/hooks/magic-context/caveman.d.ts +90 -0
- package/dist/hooks/magic-context/caveman.d.ts.map +1 -0
- package/dist/hooks/magic-context/channel2-cycle.d.ts +16 -0
- package/dist/hooks/magic-context/channel2-cycle.d.ts.map +1 -0
- package/dist/hooks/magic-context/channel2-delivery.d.ts +32 -0
- package/dist/hooks/magic-context/channel2-delivery.d.ts.map +1 -0
- package/dist/hooks/magic-context/child-session-spawn.d.ts +27 -0
- package/dist/hooks/magic-context/child-session-spawn.d.ts.map +1 -0
- package/dist/hooks/magic-context/compaction-marker-manager.d.ts +154 -0
- package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -0
- package/dist/hooks/magic-context/compaction-off-transition.d.ts +97 -0
- package/dist/hooks/magic-context/compaction-off-transition.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-parser.d.ts +66 -0
- package/dist/hooks/magic-context/compartment-parser.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-prompt.d.ts +33 -0
- package/dist/hooks/magic-context/compartment-prompt.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-render-epoch.d.ts +27 -0
- package/dist/hooks/magic-context/compartment-render-epoch.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts +29 -0
- package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts +43 -0
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts +31 -0
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner-mapping.d.ts +25 -0
- package/dist/hooks/magic-context/compartment-runner-mapping.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts +29 -0
- package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner-recomp.d.ts +11 -0
- package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner-types.d.ts +295 -0
- package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts +83 -0
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner.d.ts +59 -0
- package/dist/hooks/magic-context/compartment-runner.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-trigger.d.ts +77 -0
- package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -0
- package/dist/hooks/magic-context/ctx-reduce-availability.d.ts +170 -0
- package/dist/hooks/magic-context/ctx-reduce-availability.d.ts.map +1 -0
- package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts +104 -0
- package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts.map +1 -0
- package/dist/hooks/magic-context/decay-curve.d.ts +84 -0
- package/dist/hooks/magic-context/decay-curve.d.ts.map +1 -0
- package/dist/hooks/magic-context/decay-render.d.ts +80 -0
- package/dist/hooks/magic-context/decay-render.d.ts.map +1 -0
- package/dist/hooks/magic-context/decision-calibration.d.ts +24 -0
- package/dist/hooks/magic-context/decision-calibration.d.ts.map +1 -0
- package/dist/hooks/magic-context/degraded-pass-refusal.d.ts +35 -0
- package/dist/hooks/magic-context/degraded-pass-refusal.d.ts.map +1 -0
- package/dist/hooks/magic-context/derive-budgets.d.ts +60 -0
- package/dist/hooks/magic-context/derive-budgets.d.ts.map +1 -0
- package/dist/hooks/magic-context/drop-stale-reduce-calls.d.ts +39 -0
- package/dist/hooks/magic-context/drop-stale-reduce-calls.d.ts.map +1 -0
- package/dist/hooks/magic-context/dropped-input-guard.d.ts +55 -0
- package/dist/hooks/magic-context/dropped-input-guard.d.ts.map +1 -0
- package/dist/hooks/magic-context/dropped-token-estimate.d.ts +20 -0
- package/dist/hooks/magic-context/dropped-token-estimate.d.ts.map +1 -0
- package/dist/hooks/magic-context/edit-marker.d.ts +11 -0
- package/dist/hooks/magic-context/edit-marker.d.ts.map +1 -0
- package/dist/hooks/magic-context/emergency-drop.d.ts +112 -0
- package/dist/hooks/magic-context/emergency-drop.d.ts.map +1 -0
- package/dist/hooks/magic-context/emergency-fail-closed.d.ts +14 -0
- package/dist/hooks/magic-context/emergency-fail-closed.d.ts.map +1 -0
- package/dist/hooks/magic-context/empty-task-output.d.ts +16 -0
- package/dist/hooks/magic-context/empty-task-output.d.ts.map +1 -0
- package/dist/hooks/magic-context/event-payloads.d.ts +73 -0
- package/dist/hooks/magic-context/event-payloads.d.ts.map +1 -0
- package/dist/hooks/magic-context/event-resolvers.d.ts +114 -0
- package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -0
- package/dist/hooks/magic-context/execute-flush.d.ts +3 -0
- package/dist/hooks/magic-context/execute-flush.d.ts.map +1 -0
- package/dist/hooks/magic-context/final-wire-token-estimate.d.ts +56 -0
- package/dist/hooks/magic-context/final-wire-token-estimate.d.ts.map +1 -0
- package/dist/hooks/magic-context/fold-execution-gate.d.ts +2 -0
- package/dist/hooks/magic-context/fold-execution-gate.d.ts.map +1 -0
- package/dist/hooks/magic-context/format-bytes.d.ts +2 -0
- package/dist/hooks/magic-context/format-bytes.d.ts.map +1 -0
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts +48 -0
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -0
- package/dist/hooks/magic-context/historian-no-fire-cause.d.ts +5 -0
- package/dist/hooks/magic-context/historian-no-fire-cause.d.ts.map +1 -0
- package/dist/hooks/magic-context/historian-prompt-fit.d.ts +112 -0
- package/dist/hooks/magic-context/historian-prompt-fit.d.ts.map +1 -0
- package/dist/hooks/magic-context/historian-prompt.generated.d.ts +2 -0
- package/dist/hooks/magic-context/historian-prompt.generated.d.ts.map +1 -0
- package/dist/hooks/magic-context/historian-publish-stage-logger.d.ts +3 -0
- package/dist/hooks/magic-context/historian-publish-stage-logger.d.ts.map +1 -0
- package/dist/hooks/magic-context/historian-state-file.d.ts +43 -0
- package/dist/hooks/magic-context/historian-state-file.d.ts.map +1 -0
- package/dist/hooks/magic-context/history-boundary-repair.d.ts +44 -0
- package/dist/hooks/magic-context/history-boundary-repair.d.ts.map +1 -0
- package/dist/hooks/magic-context/hook-handlers.d.ts +177 -0
- package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -0
- package/dist/hooks/magic-context/host-served-rows.d.ts +58 -0
- package/dist/hooks/magic-context/host-served-rows.d.ts.map +1 -0
- package/dist/hooks/magic-context/image-token-estimate.d.ts +15 -0
- package/dist/hooks/magic-context/image-token-estimate.d.ts.map +1 -0
- package/dist/hooks/magic-context/inject-compartments.d.ts +389 -0
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -0
- package/dist/hooks/magic-context/issue-135-wire-fixtures.d.ts +8 -0
- package/dist/hooks/magic-context/issue-135-wire-fixtures.d.ts.map +1 -0
- package/dist/hooks/magic-context/issue-423-fixture.d.ts +37 -0
- package/dist/hooks/magic-context/issue-423-fixture.d.ts.map +1 -0
- package/dist/hooks/magic-context/issue-424-fixture.d.ts +11 -0
- package/dist/hooks/magic-context/issue-424-fixture.d.ts.map +1 -0
- package/dist/hooks/magic-context/legacy-compartments.d.ts +20 -0
- package/dist/hooks/magic-context/legacy-compartments.d.ts.map +1 -0
- package/dist/hooks/magic-context/live-session-state.d.ts +68 -0
- package/dist/hooks/magic-context/live-session-state.d.ts.map +1 -0
- package/dist/hooks/magic-context/lkg-persist.d.ts +22 -0
- package/dist/hooks/magic-context/lkg-persist.d.ts.map +1 -0
- package/dist/hooks/magic-context/lkg-replay.d.ts +71 -0
- package/dist/hooks/magic-context/lkg-replay.d.ts.map +1 -0
- package/dist/hooks/magic-context/lkg-slot.d.ts +119 -0
- package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -0
- package/dist/hooks/magic-context/m0-token-breakdown.d.ts +44 -0
- package/dist/hooks/magic-context/m0-token-breakdown.d.ts.map +1 -0
- package/dist/hooks/magic-context/maintenance-authority.d.ts +2 -0
- package/dist/hooks/magic-context/maintenance-authority.d.ts.map +1 -0
- package/dist/hooks/magic-context/openai-compat-adjacency.d.ts +38 -0
- package/dist/hooks/magic-context/openai-compat-adjacency.d.ts.map +1 -0
- package/dist/hooks/magic-context/opencode-v1-store-fixture.d.ts +12 -0
- package/dist/hooks/magic-context/opencode-v1-store-fixture.d.ts.map +1 -0
- package/dist/hooks/magic-context/pass-outcome.d.ts +70 -0
- package/dist/hooks/magic-context/pass-outcome.d.ts.map +1 -0
- package/dist/hooks/magic-context/persist-filtered-noise.d.ts +5 -0
- package/dist/hooks/magic-context/persist-filtered-noise.d.ts.map +1 -0
- package/dist/hooks/magic-context/postprocess-read-cache.d.ts +8 -0
- package/dist/hooks/magic-context/postprocess-read-cache.d.ts.map +1 -0
- package/dist/hooks/magic-context/producer-window-guard.d.ts +63 -0
- package/dist/hooks/magic-context/producer-window-guard.d.ts.map +1 -0
- package/dist/hooks/magic-context/producer-window-test-support.d.ts +14 -0
- package/dist/hooks/magic-context/producer-window-test-support.d.ts.map +1 -0
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts +234 -0
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -0
- package/dist/hooks/magic-context/raw-fallback-context-limit.d.ts +10 -0
- package/dist/hooks/magic-context/raw-fallback-context-limit.d.ts.map +1 -0
- package/dist/hooks/magic-context/read-session-chunk.d.ts +271 -0
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -0
- package/dist/hooks/magic-context/read-session-db.d.ts +66 -0
- package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -0
- package/dist/hooks/magic-context/read-session-formatting.d.ts +65 -0
- package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -0
- package/dist/hooks/magic-context/read-session-raw.d.ts +164 -0
- package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -0
- package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts +82 -0
- package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts.map +1 -0
- package/dist/hooks/magic-context/reasoning-removal.d.ts +60 -0
- package/dist/hooks/magic-context/reasoning-removal.d.ts.map +1 -0
- package/dist/hooks/magic-context/recomp-orchestrator.d.ts +93 -0
- package/dist/hooks/magic-context/recomp-orchestrator.d.ts.map +1 -0
- package/dist/hooks/magic-context/reference-retrieval.d.ts +72 -0
- package/dist/hooks/magic-context/reference-retrieval.d.ts.map +1 -0
- package/dist/hooks/magic-context/reference-seeds.generated.d.ts +8 -0
- package/dist/hooks/magic-context/reference-seeds.generated.d.ts.map +1 -0
- package/dist/hooks/magic-context/send-session-notification.d.ts +43 -0
- package/dist/hooks/magic-context/send-session-notification.d.ts.map +1 -0
- package/dist/hooks/magic-context/sentinel.d.ts +146 -0
- package/dist/hooks/magic-context/sentinel.d.ts.map +1 -0
- package/dist/hooks/magic-context/storage-busy-refusal.d.ts +20 -0
- package/dist/hooks/magic-context/storage-busy-refusal.d.ts.map +1 -0
- package/dist/hooks/magic-context/strip-content.d.ts +216 -0
- package/dist/hooks/magic-context/strip-content.d.ts.map +1 -0
- package/dist/hooks/magic-context/strip-structural-noise.d.ts +15 -0
- package/dist/hooks/magic-context/strip-structural-noise.d.ts.map +1 -0
- package/dist/hooks/magic-context/stripped-command.d.ts +56 -0
- package/dist/hooks/magic-context/stripped-command.d.ts.map +1 -0
- package/dist/hooks/magic-context/supersession-reclaim.d.ts +58 -0
- package/dist/hooks/magic-context/supersession-reclaim.d.ts.map +1 -0
- package/dist/hooks/magic-context/system-injection-stripper.d.ts +2 -0
- package/dist/hooks/magic-context/system-injection-stripper.d.ts.map +1 -0
- package/dist/hooks/magic-context/system-prompt-hash.d.ts +129 -0
- package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -0
- package/dist/hooks/magic-context/tag-content-primitives.d.ts +31 -0
- package/dist/hooks/magic-context/tag-content-primitives.d.ts.map +1 -0
- package/dist/hooks/magic-context/tag-id-fallback.d.ts +11 -0
- package/dist/hooks/magic-context/tag-id-fallback.d.ts.map +1 -0
- package/dist/hooks/magic-context/tag-messages.d.ts +145 -0
- package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -0
- package/dist/hooks/magic-context/tag-part-guards.d.ts +23 -0
- package/dist/hooks/magic-context/tag-part-guards.d.ts.map +1 -0
- package/dist/hooks/magic-context/tail-hygiene-walk.d.ts +178 -0
- package/dist/hooks/magic-context/tail-hygiene-walk.d.ts.map +1 -0
- package/dist/hooks/magic-context/temporal-awareness.d.ts +73 -0
- package/dist/hooks/magic-context/temporal-awareness.d.ts.map +1 -0
- package/dist/hooks/magic-context/text-complete.d.ts +31 -0
- package/dist/hooks/magic-context/text-complete.d.ts.map +1 -0
- package/dist/hooks/magic-context/todo-view.d.ts +127 -0
- package/dist/hooks/magic-context/todo-view.d.ts.map +1 -0
- package/dist/hooks/magic-context/tokenizer-calibration.d.ts +92 -0
- package/dist/hooks/magic-context/tokenizer-calibration.d.ts.map +1 -0
- package/dist/hooks/magic-context/tool-drop-target.d.ts +144 -0
- package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -0
- package/dist/hooks/magic-context/tool-input-size.d.ts +21 -0
- package/dist/hooks/magic-context/tool-input-size.d.ts.map +1 -0
- package/dist/hooks/magic-context/tool-reclaim.d.ts +12 -0
- package/dist/hooks/magic-context/tool-reclaim.d.ts.map +1 -0
- package/dist/hooks/magic-context/tool-sweep-policy.d.ts +50 -0
- package/dist/hooks/magic-context/tool-sweep-policy.d.ts.map +1 -0
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts +133 -0
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -0
- package/dist/hooks/magic-context/transform-context-state.d.ts +28 -0
- package/dist/hooks/magic-context/transform-context-state.d.ts.map +1 -0
- package/dist/hooks/magic-context/transform-message-helpers.d.ts +32 -0
- package/dist/hooks/magic-context/transform-message-helpers.d.ts.map +1 -0
- package/dist/hooks/magic-context/transform-operations.d.ts +5 -0
- package/dist/hooks/magic-context/transform-operations.d.ts.map +1 -0
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +350 -0
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -0
- package/dist/hooks/magic-context/transform-stage-logger.d.ts +2 -0
- package/dist/hooks/magic-context/transform-stage-logger.d.ts.map +1 -0
- package/dist/hooks/magic-context/transform.d.ts +334 -0
- package/dist/hooks/magic-context/transform.d.ts.map +1 -0
- package/dist/hooks/magic-context/unmanaged-over-window.d.ts +36 -0
- package/dist/hooks/magic-context/unmanaged-over-window.d.ts.map +1 -0
- package/dist/hooks/magic-context/unresolved-history-boundary.d.ts +15 -0
- package/dist/hooks/magic-context/unresolved-history-boundary.d.ts.map +1 -0
- package/dist/hooks/magic-context/wrapup-orchestrator.d.ts +14 -0
- package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -0
- package/dist/index-1vs6anwz.js +126 -0
- package/dist/index-3wagyrnj.js +670 -0
- package/dist/index-53g38ggt.js +40 -0
- package/dist/index-5pg0acf7.js +410 -0
- package/dist/index-977gxfz0.js +514 -0
- package/dist/index-by6h2pav.js +27883 -0
- package/dist/index-e1q8002h.js +16 -0
- package/dist/index-fg34g6a5.js +584 -0
- package/dist/index-jdxxq8cz.js +99 -0
- package/dist/index-me3zcj5t.js +69 -0
- package/dist/index-qbkzdkk0.js +496 -0
- package/dist/index-wgt4gamw.js +6388 -0
- package/dist/index-zx63j2e2.js +907 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -0
- package/dist/message-time-backfill-5ewk0axe.js +116 -0
- package/dist/model-resolution-5haaxnpt.js +6 -0
- package/dist/plugin/boot-deadline.d.ts +47 -0
- package/dist/plugin/boot-deadline.d.ts.map +1 -0
- package/dist/plugin/boot-quiet.d.ts +12 -0
- package/dist/plugin/boot-quiet.d.ts.map +1 -0
- package/dist/plugin/normalize-tool-arg-schemas.d.ts +7 -0
- package/dist/plugin/normalize-tool-arg-schemas.d.ts.map +1 -0
- package/dist/plugin/rpc-handlers.d.ts +52 -0
- package/dist/plugin/rpc-handlers.d.ts.map +1 -0
- package/dist/plugin/sidebar-snapshot-cache.d.ts +19 -0
- package/dist/plugin/sidebar-snapshot-cache.d.ts.map +1 -0
- package/dist/plugin/subagent-tool-policy.d.ts +9 -0
- package/dist/plugin/subagent-tool-policy.d.ts.map +1 -0
- package/dist/plugin/types.d.ts +3 -0
- package/dist/plugin/types.d.ts.map +1 -0
- package/dist/prompt-context-ffa5xcfx.js +76 -0
- package/dist/read-session-chunk-apjwrttc.js +56 -0
- package/dist/recomp-orchestrator-gyeevxaw.js +21 -0
- package/dist/rpc-notifications-4amf6mf4.js +14 -0
- package/dist/safe-notification-target-ph3xd1ve.js +9 -0
- package/dist/send-session-notification-y29y9fsr.js +18 -0
- package/dist/shared/announcement.d.ts +69 -0
- package/dist/shared/announcement.d.ts.map +1 -0
- package/dist/shared/assistant-message-extractor.d.ts +13 -0
- package/dist/shared/assistant-message-extractor.d.ts.map +1 -0
- package/dist/shared/auto-update-provenance.d.ts +9 -0
- package/dist/shared/auto-update-provenance.d.ts.map +1 -0
- package/dist/shared/bounded-session-map.d.ts +45 -0
- package/dist/shared/bounded-session-map.d.ts.map +1 -0
- package/dist/shared/builtin-commands.d.ts +24 -0
- package/dist/shared/builtin-commands.d.ts.map +1 -0
- package/dist/shared/cache-ttl-display.d.ts +25 -0
- package/dist/shared/cache-ttl-display.d.ts.map +1 -0
- package/dist/shared/cache-ttl-seed.d.ts +10 -0
- package/dist/shared/cache-ttl-seed.d.ts.map +1 -0
- package/dist/shared/child-session-teardown.d.ts +34 -0
- package/dist/shared/child-session-teardown.d.ts.map +1 -0
- package/dist/shared/commit-detection.d.ts +29 -0
- package/dist/shared/commit-detection.d.ts.map +1 -0
- package/dist/shared/config-diagnostics.d.ts +30 -0
- package/dist/shared/config-diagnostics.d.ts.map +1 -0
- package/dist/shared/conflict-detector.d.ts +139 -0
- package/dist/shared/conflict-detector.d.ts.map +1 -0
- package/dist/shared/conflict-fixer.d.ts +20 -0
- package/dist/shared/conflict-fixer.d.ts.map +1 -0
- package/dist/shared/context-limit-provenance.d.ts +3 -0
- package/dist/shared/context-limit-provenance.d.ts.map +1 -0
- package/dist/shared/data-path.d.ts +176 -0
- package/dist/shared/data-path.d.ts.map +1 -0
- package/dist/shared/error-message.d.ts +32 -0
- package/dist/shared/error-message.d.ts.map +1 -0
- package/dist/shared/escalation-bands.d.ts +9 -0
- package/dist/shared/escalation-bands.d.ts.map +1 -0
- package/dist/shared/format-bytes.d.ts +2 -0
- package/dist/shared/format-bytes.d.ts.map +1 -0
- package/dist/shared/format-threshold.d.ts +43 -0
- package/dist/shared/format-threshold.d.ts.map +1 -0
- package/dist/shared/harness-provider-map.d.ts +64 -0
- package/dist/shared/harness-provider-map.d.ts.map +1 -0
- package/dist/shared/harness.d.ts +55 -0
- package/dist/shared/harness.d.ts.map +1 -0
- package/dist/shared/hidden-variant-warnings.d.ts +5 -0
- package/dist/shared/hidden-variant-warnings.d.ts.map +1 -0
- package/dist/shared/historian-tool-expansions.d.ts +5 -0
- package/dist/shared/historian-tool-expansions.d.ts.map +1 -0
- package/dist/shared/historian-tool-template.d.ts +5 -0
- package/dist/shared/historian-tool-template.d.ts.map +1 -0
- package/dist/shared/historian-transient-error.d.ts +2 -0
- package/dist/shared/historian-transient-error.d.ts.map +1 -0
- package/dist/shared/host-limitations.d.ts +14 -0
- package/dist/shared/host-limitations.d.ts.map +1 -0
- package/dist/shared/index.d.ts +8 -0
- package/dist/shared/index.d.ts.map +1 -0
- package/dist/shared/internal-initiator-marker.d.ts +2 -0
- package/dist/shared/internal-initiator-marker.d.ts.map +1 -0
- package/dist/shared/jsonc-edit.d.ts +23 -0
- package/dist/shared/jsonc-edit.d.ts.map +1 -0
- package/dist/shared/jsonc-parser.d.ts +30 -0
- package/dist/shared/jsonc-parser.d.ts.map +1 -0
- package/dist/shared/keep-subagents.d.ts +7 -0
- package/dist/shared/keep-subagents.d.ts.map +1 -0
- package/dist/shared/logger.d.ts +18 -0
- package/dist/shared/logger.d.ts.map +1 -0
- package/dist/shared/model-cache-ttl.d.ts +9 -0
- package/dist/shared/model-cache-ttl.d.ts.map +1 -0
- package/dist/shared/model-resolution.d.ts +35 -0
- package/dist/shared/model-resolution.d.ts.map +1 -0
- package/dist/shared/model-suggestion-retry.d.ts +138 -0
- package/dist/shared/model-suggestion-retry.d.ts.map +1 -0
- package/dist/shared/models-dev-cache.d.ts +156 -0
- package/dist/shared/models-dev-cache.d.ts.map +1 -0
- package/dist/shared/normalize-sdk-response.d.ts +5 -0
- package/dist/shared/normalize-sdk-response.d.ts.map +1 -0
- package/dist/shared/opencode-config-dir-types.d.ts +14 -0
- package/dist/shared/opencode-config-dir-types.d.ts.map +1 -0
- package/dist/shared/opencode-config-dir.d.ts +57 -0
- package/dist/shared/opencode-config-dir.d.ts.map +1 -0
- package/dist/shared/opencode-db-path.d.ts +68 -0
- package/dist/shared/opencode-db-path.d.ts.map +1 -0
- package/dist/shared/pi-executable.d.ts +6 -0
- package/dist/shared/pi-executable.d.ts.map +1 -0
- package/dist/shared/plugin-package-version.d.ts +14 -0
- package/dist/shared/plugin-package-version.d.ts.map +1 -0
- package/dist/shared/project-directory-key.d.ts +26 -0
- package/dist/shared/project-directory-key.d.ts.map +1 -0
- package/dist/shared/prompt-context.d.ts +31 -0
- package/dist/shared/prompt-context.d.ts.map +1 -0
- package/dist/shared/prompt-surface-a1-golden.d.ts +28 -0
- package/dist/shared/prompt-surface-a1-golden.d.ts.map +1 -0
- package/dist/shared/prompt-surface-runtime.d.ts +62 -0
- package/dist/shared/prompt-surface-runtime.d.ts.map +1 -0
- package/dist/shared/prompt-surface.d.ts +53 -0
- package/dist/shared/prompt-surface.d.ts.map +1 -0
- package/dist/shared/provider-response-completion.d.ts +12 -0
- package/dist/shared/provider-response-completion.d.ts.map +1 -0
- package/dist/shared/record-type-guard.d.ts +2 -0
- package/dist/shared/record-type-guard.d.ts.map +1 -0
- package/dist/shared/redaction.d.ts +7 -0
- package/dist/shared/redaction.d.ts.map +1 -0
- package/dist/shared/resolve-fallbacks.d.ts +48 -0
- package/dist/shared/resolve-fallbacks.d.ts.map +1 -0
- package/dist/shared/rpc-client.d.ts +28 -0
- package/dist/shared/rpc-client.d.ts.map +1 -0
- package/dist/shared/rpc-notifications.d.ts +74 -0
- package/dist/shared/rpc-notifications.d.ts.map +1 -0
- package/dist/shared/rpc-server.d.ts +52 -0
- package/dist/shared/rpc-server.d.ts.map +1 -0
- package/dist/shared/rpc-types.d.ts +385 -0
- package/dist/shared/rpc-types.d.ts.map +1 -0
- package/dist/shared/rpc-utils.d.ts +162 -0
- package/dist/shared/rpc-utils.d.ts.map +1 -0
- package/dist/shared/run-token-log.d.ts +13 -0
- package/dist/shared/run-token-log.d.ts.map +1 -0
- package/dist/shared/safe-notification-target.d.ts +23 -0
- package/dist/shared/safe-notification-target.d.ts.map +1 -0
- package/dist/shared/sqlite-context-pragmas.d.ts +12 -0
- package/dist/shared/sqlite-context-pragmas.d.ts.map +1 -0
- package/dist/shared/sqlite-helpers.d.ts +25 -0
- package/dist/shared/sqlite-helpers.d.ts.map +1 -0
- package/dist/shared/sqlite-write-locker-test-support.d.ts +7 -0
- package/dist/shared/sqlite-write-locker-test-support.d.ts.map +1 -0
- package/dist/shared/sqlite.d.ts +163 -0
- package/dist/shared/sqlite.d.ts.map +1 -0
- package/dist/shared/stable-json.d.ts +21 -0
- package/dist/shared/stable-json.d.ts.map +1 -0
- package/dist/shared/status-detail-text.d.ts +4 -0
- package/dist/shared/status-detail-text.d.ts.map +1 -0
- package/dist/shared/status-summary.d.ts +54 -0
- package/dist/shared/status-summary.d.ts.map +1 -0
- package/dist/shared/status-view-check.d.ts +130 -0
- package/dist/shared/status-view-check.d.ts.map +1 -0
- package/dist/shared/status-view.d.ts +230 -0
- package/dist/shared/status-view.d.ts.map +1 -0
- package/dist/shared/storage-permissions.d.ts +29 -0
- package/dist/shared/storage-permissions.d.ts.map +1 -0
- package/dist/shared/subagent-runner.d.ts +231 -0
- package/dist/shared/subagent-runner.d.ts.map +1 -0
- package/dist/shared/summarize-child-stderr.d.ts +2 -0
- package/dist/shared/summarize-child-stderr.d.ts.map +1 -0
- package/dist/shared/system-directive.d.ts +3 -0
- package/dist/shared/system-directive.d.ts.map +1 -0
- package/dist/shared/tag-owner-id.d.ts +19 -0
- package/dist/shared/tag-owner-id.d.ts.map +1 -0
- package/dist/shared/tag-transcript.d.ts +103 -0
- package/dist/shared/tag-transcript.d.ts.map +1 -0
- package/dist/shared/tail-hygiene-status.d.ts +24 -0
- package/dist/shared/tail-hygiene-status.d.ts.map +1 -0
- package/dist/shared/test-temp-dir.d.ts +46 -0
- package/dist/shared/test-temp-dir.d.ts.map +1 -0
- package/dist/shared/transcript.d.ts +251 -0
- package/dist/shared/transcript.d.ts.map +1 -0
- package/dist/shared/user-answer.d.ts +4 -0
- package/dist/shared/user-answer.d.ts.map +1 -0
- package/dist/shared/user-facing-codes.d.ts +135 -0
- package/dist/shared/user-facing-codes.d.ts.map +1 -0
- package/dist/shared/window-geometry.d.ts +121 -0
- package/dist/shared/window-geometry.d.ts.map +1 -0
- package/dist/shared/write-transaction-timing.d.ts +11 -0
- package/dist/shared/write-transaction-timing.d.ts.map +1 -0
- package/dist/shared/xml-unescape.d.ts +9 -0
- package/dist/shared/xml-unescape.d.ts.map +1 -0
- package/dist/tools/ctx-expand/constants.d.ts +3 -0
- package/dist/tools/ctx-expand/constants.d.ts.map +1 -0
- package/dist/tools/ctx-expand/index.d.ts +2 -0
- package/dist/tools/ctx-expand/index.d.ts.map +1 -0
- package/dist/tools/ctx-expand/mode.d.ts +35 -0
- package/dist/tools/ctx-expand/mode.d.ts.map +1 -0
- package/dist/tools/ctx-expand/render.d.ts +47 -0
- package/dist/tools/ctx-expand/render.d.ts.map +1 -0
- package/dist/tools/ctx-expand/tools.d.ts +10 -0
- package/dist/tools/ctx-expand/tools.d.ts.map +1 -0
- package/dist/tools/ctx-expand/types.d.ts +11 -0
- package/dist/tools/ctx-expand/types.d.ts.map +1 -0
- package/dist/tools/ctx-memory/constants.d.ts +3 -0
- package/dist/tools/ctx-memory/constants.d.ts.map +1 -0
- package/dist/tools/ctx-memory/index.d.ts +4 -0
- package/dist/tools/ctx-memory/index.d.ts.map +1 -0
- package/dist/tools/ctx-memory/tools.d.ts +5 -0
- package/dist/tools/ctx-memory/tools.d.ts.map +1 -0
- package/dist/tools/ctx-memory/types.d.ts +38 -0
- package/dist/tools/ctx-memory/types.d.ts.map +1 -0
- package/dist/tools/ctx-memory/verification-recording.d.ts +8 -0
- package/dist/tools/ctx-memory/verification-recording.d.ts.map +1 -0
- package/dist/tools/ctx-note/constants.d.ts +2 -0
- package/dist/tools/ctx-note/constants.d.ts.map +1 -0
- package/dist/tools/ctx-note/index.d.ts +4 -0
- package/dist/tools/ctx-note/index.d.ts.map +1 -0
- package/dist/tools/ctx-note/render.d.ts +67 -0
- package/dist/tools/ctx-note/render.d.ts.map +1 -0
- package/dist/tools/ctx-note/tools.d.ts +13 -0
- package/dist/tools/ctx-note/tools.d.ts.map +1 -0
- package/dist/tools/ctx-note/types.d.ts +14 -0
- package/dist/tools/ctx-note/types.d.ts.map +1 -0
- package/dist/tools/ctx-reduce/constants.d.ts +4 -0
- package/dist/tools/ctx-reduce/constants.d.ts.map +1 -0
- package/dist/tools/ctx-reduce/index.d.ts +4 -0
- package/dist/tools/ctx-reduce/index.d.ts.map +1 -0
- package/dist/tools/ctx-reduce/tools.d.ts +19 -0
- package/dist/tools/ctx-reduce/tools.d.ts.map +1 -0
- package/dist/tools/ctx-reduce/types.d.ts +5 -0
- package/dist/tools/ctx-reduce/types.d.ts.map +1 -0
- package/dist/tools/ctx-search/constants.d.ts +4 -0
- package/dist/tools/ctx-search/constants.d.ts.map +1 -0
- package/dist/tools/ctx-search/date-range.d.ts +9 -0
- package/dist/tools/ctx-search/date-range.d.ts.map +1 -0
- package/dist/tools/ctx-search/index.d.ts +4 -0
- package/dist/tools/ctx-search/index.d.ts.map +1 -0
- package/dist/tools/ctx-search/tools.d.ts +5 -0
- package/dist/tools/ctx-search/tools.d.ts.map +1 -0
- package/dist/tools/ctx-search/types.d.ts +34 -0
- package/dist/tools/ctx-search/types.d.ts.map +1 -0
- package/dist/tools/light-descriptions.d.ts +6 -0
- package/dist/tools/light-descriptions.d.ts.map +1 -0
- package/dist/tools/parameter-descriptions.d.ts +75 -0
- package/dist/tools/parameter-descriptions.d.ts.map +1 -0
- package/dist/tools/unwrap-imitated-reduced-args.d.ts +21 -0
- package/dist/tools/unwrap-imitated-reduced-args.d.ts.map +1 -0
- package/dist/v2/fold/boundary.d.ts +61 -0
- package/dist/v2/fold/boundary.d.ts.map +1 -0
- package/dist/v2/fold/host-media.d.ts +36 -0
- package/dist/v2/fold/host-media.d.ts.map +1 -0
- package/dist/v2/fold/markers.d.ts +7 -0
- package/dist/v2/fold/markers.d.ts.map +1 -0
- package/dist/v2/fold/owner.d.ts +40 -0
- package/dist/v2/fold/owner.d.ts.map +1 -0
- package/dist/v2/fold/restore.d.ts +31 -0
- package/dist/v2/fold/restore.d.ts.map +1 -0
- package/dist/v2/fork-inheritance.d.ts +101 -0
- package/dist/v2/fork-inheritance.d.ts.map +1 -0
- package/dist/v2/hidden-child-cleanup.d.ts +11 -0
- package/dist/v2/hidden-child-cleanup.d.ts.map +1 -0
- package/dist/v2/hidden-child-native.d.ts +29 -0
- package/dist/v2/hidden-child-native.d.ts.map +1 -0
- package/dist/v2/hidden-child-record.d.ts +137 -0
- package/dist/v2/hidden-child-record.d.ts.map +1 -0
- package/dist/v2/hidden-completion.d.ts +57 -0
- package/dist/v2/hidden-completion.d.ts.map +1 -0
- package/dist/v2/hooks/channel2.d.ts +10 -0
- package/dist/v2/hooks/channel2.d.ts.map +1 -0
- package/dist/v2/hooks/commands.d.ts +29 -0
- package/dist/v2/hooks/commands.d.ts.map +1 -0
- package/dist/v2/hooks/context.d.ts +112 -0
- package/dist/v2/hooks/context.d.ts.map +1 -0
- package/dist/v2/hooks/deleted-session-tombstones.d.ts +10 -0
- package/dist/v2/hooks/deleted-session-tombstones.d.ts.map +1 -0
- package/dist/v2/hooks/generate.d.ts +10 -0
- package/dist/v2/hooks/generate.d.ts.map +1 -0
- package/dist/v2/hooks/hidden-child.d.ts +76 -0
- package/dist/v2/hooks/hidden-child.d.ts.map +1 -0
- package/dist/v2/hooks/hidden-terminal-error.d.ts +8 -0
- package/dist/v2/hooks/hidden-terminal-error.d.ts.map +1 -0
- package/dist/v2/hooks/lkg-system.d.ts +11 -0
- package/dist/v2/hooks/lkg-system.d.ts.map +1 -0
- package/dist/v2/hooks/model-limit-cache.d.ts +19 -0
- package/dist/v2/hooks/model-limit-cache.d.ts.map +1 -0
- package/dist/v2/hooks/payload.d.ts +15 -0
- package/dist/v2/hooks/payload.d.ts.map +1 -0
- package/dist/v2/hooks/refusal.d.ts +15 -0
- package/dist/v2/hooks/refusal.d.ts.map +1 -0
- package/dist/v2/hooks/restore-rows.d.ts +29 -0
- package/dist/v2/hooks/restore-rows.d.ts.map +1 -0
- package/dist/v2/hooks/rpc-live-state.d.ts +9 -0
- package/dist/v2/hooks/rpc-live-state.d.ts.map +1 -0
- package/dist/v2/hooks/session-api-gate.d.ts +4 -0
- package/dist/v2/hooks/session-api-gate.d.ts.map +1 -0
- package/dist/v2/hooks/session-project-backfill.d.ts +15 -0
- package/dist/v2/hooks/session-project-backfill.d.ts.map +1 -0
- package/dist/v2/hooks/storage-gate.d.ts +48 -0
- package/dist/v2/hooks/storage-gate.d.ts.map +1 -0
- package/dist/v2/hooks/storage-notice.d.ts +29 -0
- package/dist/v2/hooks/storage-notice.d.ts.map +1 -0
- package/dist/v2/hooks/store.d.ts +58 -0
- package/dist/v2/hooks/store.d.ts.map +1 -0
- package/dist/v2/hooks/tools.d.ts +8 -0
- package/dist/v2/hooks/tools.d.ts.map +1 -0
- package/dist/v2/hooks/types.d.ts +250 -0
- package/dist/v2/hooks/types.d.ts.map +1 -0
- package/dist/v2/hooks/usage-persist.d.ts +31 -0
- package/dist/v2/hooks/usage-persist.d.ts.map +1 -0
- package/dist/v2/hooks/usage-reading.d.ts +46 -0
- package/dist/v2/hooks/usage-reading.d.ts.map +1 -0
- package/dist/v2/server.d.ts +27 -0
- package/dist/v2/server.d.ts.map +1 -0
- package/dist/v2/server.js +76235 -0
- package/dist/v2/store-reader.d.ts +218 -0
- package/dist/v2/store-reader.d.ts.map +1 -0
- package/dist/web/api.d.ts +40 -0
- package/dist/web/api.d.ts.map +1 -0
- package/dist/web/context-store.d.ts +74 -0
- package/dist/web/context-store.d.ts.map +1 -0
- package/dist/web/fixtures.d.ts +53 -0
- package/dist/web/fixtures.d.ts.map +1 -0
- package/dist/web/host-opencode.d.ts +56 -0
- package/dist/web/host-opencode.d.ts.map +1 -0
- package/dist/web/host-pi.d.ts +116 -0
- package/dist/web/host-pi.d.ts.map +1 -0
- package/dist/web/main.d.ts +24 -0
- package/dist/web/main.d.ts.map +1 -0
- package/dist/web/main.js +6071 -0
- package/dist/web/memories.d.ts +67 -0
- package/dist/web/memories.d.ts.map +1 -0
- package/dist/web/server.d.ts +42 -0
- package/dist/web/server.d.ts.map +1 -0
- package/dist/web/types.d.ts +52 -0
- package/dist/web/types.d.ts.map +1 -0
- package/dist/web/ui/favicon.svg +4 -0
- package/dist/web/ui/index.html +36 -0
- package/dist/web/ui/panel.css +8 -0
- package/dist/web/ui/panel.js +373 -0
- package/dist/web/views.d.ts +155 -0
- package/dist/web/views.d.ts.map +1 -0
- package/dist/web/writes.d.ts +86 -0
- package/dist/web/writes.d.ts.map +1 -0
- package/dist/wrapup-orchestrator-z9sqpqjf.js +420 -0
- package/index.js +1 -0
- package/package.json +84 -4
- package/src/agents/historian.ts +3 -0
- package/src/agents/language-directive.test.ts +129 -0
- package/src/agents/language-directive.ts +113 -0
- package/src/agents/magic-context-prompt.language.test.ts +37 -0
- package/src/agents/magic-context-prompt.test.ts +520 -0
- package/src/agents/magic-context-prompt.ts +196 -0
- package/src/agents/memory-maintainer.test.ts +249 -0
- package/src/agents/memory-maintainer.ts +374 -0
- package/src/config/agent-disable.ts +58 -0
- package/src/config/compaction-accessor-guard.test.ts +81 -0
- package/src/config/compaction-backcompat.test.ts +52 -0
- package/src/config/config-paths.ts +42 -0
- package/src/config/index.test.ts +1252 -0
- package/src/config/index.ts +762 -0
- package/src/config/latch-permanence-guard.test.ts +218 -0
- package/src/config/live-run-config.test.ts +139 -0
- package/src/config/live-run-config.ts +79 -0
- package/src/config/live-schema-drift.test.ts +67 -0
- package/src/config/live-snapshot.test.ts +86 -0
- package/src/config/live-snapshot.ts +187 -0
- package/src/config/migrate-experimental.ts +92 -0
- package/src/config/misplaced-agent-model.test.ts +55 -0
- package/src/config/profiles.ts +106 -0
- package/src/config/project-config-trust-boundary.test.ts +185 -0
- package/src/config/project-security.hostile-matrix.test.ts +281 -0
- package/src/config/project-security.test.ts +329 -0
- package/src/config/project-security.ts +940 -0
- package/src/config/protected-tokens.test.ts +229 -0
- package/src/config/prune-config-leaf.test.ts +78 -0
- package/src/config/prune-config-leaf.ts +67 -0
- package/src/config/raw-loader.test.ts +389 -0
- package/src/config/raw-loader.ts +435 -0
- package/src/config/removed-agent-config.ts +45 -0
- package/src/config/removed-agent-source-fence.test.ts +53 -0
- package/src/config/removed-config-keys.test.ts +106 -0
- package/src/config/schema/agent-overrides.ts +45 -0
- package/src/config/schema/magic-context.test.ts +434 -0
- package/src/config/schema/magic-context.ts +1019 -0
- package/src/config/variable.test.ts +324 -0
- package/src/config/variable.ts +192 -0
- package/src/shared/__fixtures__/window-overlay.v1.json +337 -0
- package/src/shared/announcement.test.ts +198 -0
- package/src/shared/announcement.ts +145 -0
- package/src/shared/assistant-message-extractor.test.ts +47 -0
- package/src/shared/assistant-message-extractor.ts +156 -0
- package/src/shared/auto-update-provenance.ts +42 -0
- package/src/shared/bounded-session-map.test.ts +97 -0
- package/src/shared/bounded-session-map.ts +84 -0
- package/src/shared/builtin-commands.ts +46 -0
- package/src/shared/cache-ttl-display.test.ts +84 -0
- package/src/shared/cache-ttl-display.ts +58 -0
- package/src/shared/cache-ttl-seed.ts +23 -0
- package/src/shared/child-session-teardown.test.ts +241 -0
- package/src/shared/child-session-teardown.ts +66 -0
- package/src/shared/commit-detection.test.ts +63 -0
- package/src/shared/commit-detection.ts +53 -0
- package/src/shared/config-diagnostics.test.ts +29 -0
- package/src/shared/config-diagnostics.ts +64 -0
- package/src/shared/conflict-detector.test.ts +780 -0
- package/src/shared/conflict-detector.ts +596 -0
- package/src/shared/conflict-fixer.test.ts +608 -0
- package/src/shared/conflict-fixer.ts +295 -0
- package/src/shared/context-limit-provenance.ts +6 -0
- package/src/shared/data-path.test.ts +352 -0
- package/src/shared/data-path.ts +310 -0
- package/src/shared/error-message.test.ts +94 -0
- package/src/shared/error-message.ts +115 -0
- package/src/shared/escalation-bands.test.ts +23 -0
- package/src/shared/escalation-bands.ts +18 -0
- package/src/shared/format-bytes.ts +5 -0
- package/src/shared/format-threshold.ts +54 -0
- package/src/shared/harness-provider-map.test.ts +176 -0
- package/src/shared/harness-provider-map.ts +130 -0
- package/src/shared/harness.ts +76 -0
- package/src/shared/hidden-variant-warnings.ts +21 -0
- package/src/shared/historian-tool-defaults.json +13 -0
- package/src/shared/historian-tool-expansions.ts +18 -0
- package/src/shared/historian-tool-template.ts +248 -0
- package/src/shared/historian-transient-error.test.ts +36 -0
- package/src/shared/historian-transient-error.ts +22 -0
- package/src/shared/host-limitations.ts +43 -0
- package/src/shared/index.ts +7 -0
- package/src/shared/internal-initiator-marker.ts +1 -0
- package/src/shared/jsonc-edit.ts +387 -0
- package/src/shared/jsonc-parser.test.ts +46 -0
- package/src/shared/jsonc-parser.ts +283 -0
- package/src/shared/keep-subagents.test.ts +39 -0
- package/src/shared/keep-subagents.ts +28 -0
- package/src/shared/logger.test.ts +292 -0
- package/src/shared/logger.ts +248 -0
- package/src/shared/model-cache-ttl.test.ts +40 -0
- package/src/shared/model-cache-ttl.ts +58 -0
- package/src/shared/model-resolution.test.ts +132 -0
- package/src/shared/model-resolution.ts +158 -0
- package/src/shared/model-suggestion-retry.test.ts +698 -0
- package/src/shared/model-suggestion-retry.ts +838 -0
- package/src/shared/models-dev-cache.test.ts +720 -0
- package/src/shared/models-dev-cache.ts +661 -0
- package/src/shared/normalize-sdk-response.ts +40 -0
- package/src/shared/opencode-config-dir-types.ts +15 -0
- package/src/shared/opencode-config-dir.ts +111 -0
- package/src/shared/opencode-db-path.test.ts +389 -0
- package/src/shared/opencode-db-path.ts +396 -0
- package/src/shared/opencode-host-generation.test.ts +29 -0
- package/src/shared/pi-executable.ts +20 -0
- package/src/shared/plugin-package-version.ts +52 -0
- package/src/shared/project-directory-key.test.ts +111 -0
- package/src/shared/project-directory-key.ts +54 -0
- package/src/shared/prompt-context.ts +135 -0
- package/src/shared/prompt-surface-a1-golden.md +407 -0
- package/src/shared/prompt-surface-a1-golden.ts +41 -0
- package/src/shared/prompt-surface-runtime.test.ts +190 -0
- package/src/shared/prompt-surface-runtime.ts +263 -0
- package/src/shared/prompt-surface.test.ts +195 -0
- package/src/shared/prompt-surface.ts +162 -0
- package/src/shared/provider-response-completion.ts +23 -0
- package/src/shared/record-type-guard.ts +3 -0
- package/src/shared/redaction.test.ts +134 -0
- package/src/shared/redaction.ts +298 -0
- package/src/shared/resolve-fallbacks.test.ts +114 -0
- package/src/shared/resolve-fallbacks.ts +95 -0
- package/src/shared/rpc-async-probes.test.ts +320 -0
- package/src/shared/rpc-client.test.ts +576 -0
- package/src/shared/rpc-client.ts +218 -0
- package/src/shared/rpc-notifications.test.ts +151 -0
- package/src/shared/rpc-notifications.ts +222 -0
- package/src/shared/rpc-server.ts +431 -0
- package/src/shared/rpc-types.ts +386 -0
- package/src/shared/rpc-utils.test.ts +822 -0
- package/src/shared/rpc-utils.ts +1146 -0
- package/src/shared/run-token-log.test.ts +65 -0
- package/src/shared/run-token-log.ts +39 -0
- package/src/shared/safe-notification-target.test.ts +97 -0
- package/src/shared/safe-notification-target.ts +102 -0
- package/src/shared/session-messages-bounded.test.ts +112 -0
- package/src/shared/sqlite-acquisition-fence.test.ts +133 -0
- package/src/shared/sqlite-acquisition-routing.test.ts +145 -0
- package/src/shared/sqlite-bind-style.test.ts +80 -0
- package/src/shared/sqlite-context-pragmas.ts +24 -0
- package/src/shared/sqlite-helpers.ts +44 -0
- package/src/shared/sqlite-import-fence.test.ts +19 -0
- package/src/shared/sqlite-pass-scope.test.ts +154 -0
- package/src/shared/sqlite-transaction-mode-guard.test.ts +234 -0
- package/src/shared/sqlite-write-locker-test-support.ts +63 -0
- package/src/shared/sqlite.test.ts +58 -0
- package/src/shared/sqlite.ts +988 -0
- package/src/shared/stable-json.test.ts +87 -0
- package/src/shared/stable-json.ts +37 -0
- package/src/shared/status-detail-text.test.ts +194 -0
- package/src/shared/status-detail-text.ts +7 -0
- package/src/shared/status-summary.ts +189 -0
- package/src/shared/status-view-check.test.ts +252 -0
- package/src/shared/status-view-check.ts +519 -0
- package/src/shared/status-view.test.ts +395 -0
- package/src/shared/status-view.ts +794 -0
- package/src/shared/storage-busy.test.ts +73 -0
- package/src/shared/storage-permissions.test.ts +190 -0
- package/src/shared/storage-permissions.ts +212 -0
- package/src/shared/subagent-runner.ts +240 -0
- package/src/shared/summarize-child-stderr.test.ts +55 -0
- package/src/shared/summarize-child-stderr.ts +33 -0
- package/src/shared/system-directive.ts +9 -0
- package/src/shared/tag-owner-id.test.ts +33 -0
- package/src/shared/tag-owner-id.ts +29 -0
- package/src/shared/tag-transcript.test.ts +554 -0
- package/src/shared/tag-transcript.ts +1400 -0
- package/src/shared/tail-hygiene-status.ts +73 -0
- package/src/shared/test-temp-dir.test.ts +84 -0
- package/src/shared/test-temp-dir.ts +192 -0
- package/src/shared/transcript.ts +274 -0
- package/src/shared/user-answer.test.ts +12 -0
- package/src/shared/user-answer.ts +17 -0
- package/src/shared/user-facing-codes.test.ts +82 -0
- package/src/shared/user-facing-codes.ts +180 -0
- package/src/shared/window-geometry.test.ts +405 -0
- package/src/shared/window-geometry.ts +726 -0
- package/src/shared/windows-hidden-spawns.test.ts +133 -0
- package/src/shared/write-transaction-attribution.test.ts +214 -0
- package/src/shared/write-transaction-timing.ts +26 -0
- package/src/shared/xml-unescape.ts +19 -0
- package/README.md +0 -3
|
@@ -0,0 +1,1400 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Harness-agnostic tagging over the Transcript interface.
|
|
3
|
+
*
|
|
4
|
+
* This is a deliberately minimal alternative to the OpenCode-specific
|
|
5
|
+
* `tag-messages.ts` that operates on `MessageLike[]`. The OpenCode flow
|
|
6
|
+
* carries 380+ lines of accumulated complexity:
|
|
7
|
+
*
|
|
8
|
+
* - source-content persistence (for cross-pass detag/restore behavior),
|
|
9
|
+
* - tool-call indexing across separate "tool" and "tool_result" parts,
|
|
10
|
+
* - reasoning-byte tracking for historian projection,
|
|
11
|
+
* - file-part stable IDs,
|
|
12
|
+
* - existing-tag resolver with content-id fallback.
|
|
13
|
+
*
|
|
14
|
+
* Most of that is OpenCode-specific (cache stability across multi-pass
|
|
15
|
+
* transforms, AI SDK part-id semantics, file part shapes). Pi's
|
|
16
|
+
* `pi.on("context", ...)` fires once per LLM call with a complete
|
|
17
|
+
* `AgentMessage[]`, so we can use a simpler tagging contract:
|
|
18
|
+
*
|
|
19
|
+
* 1. Walk the transcript in order.
|
|
20
|
+
* 2. For each tag-eligible part (text, tool_use, tool_result), assign
|
|
21
|
+
* a tag number via the shared `Tagger`.
|
|
22
|
+
* 3. Inject `§N§ ` prefix into the visible text (unless skipped).
|
|
23
|
+
* 4. Build a `TagTarget` so `applyPendingOperations` from
|
|
24
|
+
* `apply-operations.ts` can replace this part with a sentinel when
|
|
25
|
+
* a queued drop fires.
|
|
26
|
+
*
|
|
27
|
+
* Tool drops aggregate by call_id across both invocation and result
|
|
28
|
+
* occurrences (mirrors OpenCode tag-messages.ts:196-220). When a drop
|
|
29
|
+
* fires for a tool tag, BOTH the assistant `toolCall`/`tool_use` part
|
|
30
|
+
* and the user `toolResult`/`tool_result` part are mutated together so
|
|
31
|
+
* the LLM sees consistent dropped state. Without this aggregation:
|
|
32
|
+
*
|
|
33
|
+
* - Tool tag byte_size reflects only the args (~58 bytes for a `read`)
|
|
34
|
+
* because the FIRST occurrence (invocation) is tagged first and
|
|
35
|
+
* `assignTag` short-circuits the SECOND occurrence (result, ~4KB)
|
|
36
|
+
* to the same tag without updating byte_size.
|
|
37
|
+
* - Drops touch only the second occurrence (last write wins on
|
|
38
|
+
* `targets.set`), leaving the first in original form.
|
|
39
|
+
*
|
|
40
|
+
* Reuses unchanged from the OpenCode path:
|
|
41
|
+
*
|
|
42
|
+
* - `Tagger` (DB-backed counter + assignment store).
|
|
43
|
+
* - `applyPendingOperations` (operates on `Map<number, TagTarget>`).
|
|
44
|
+
* - `applyFlushedStatuses` (same).
|
|
45
|
+
* - Tag prefix primitives (`prependTag`, `stripTagPrefix`, `byteSize`).
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
import { createHash } from "node:crypto";
|
|
49
|
+
import type { ContextDatabase } from "../features/magic-context/storage";
|
|
50
|
+
import { saveSourceContent } from "../features/magic-context/storage-source";
|
|
51
|
+
import {
|
|
52
|
+
updateTagByteSize,
|
|
53
|
+
updateTagInputByteSize,
|
|
54
|
+
updateTagInputTokenCount,
|
|
55
|
+
updateTagTokenCount,
|
|
56
|
+
} from "../features/magic-context/storage-tags";
|
|
57
|
+
import { makeToolCompositeKey, type Tagger } from "../features/magic-context/tagger";
|
|
58
|
+
import { droppedInputMarker } from "../hooks/magic-context/dropped-input-guard";
|
|
59
|
+
import { applyEditMarkerToInput } from "../hooks/magic-context/edit-marker";
|
|
60
|
+
import { estimateImageTokensFromDataUrl } from "../hooks/magic-context/image-token-estimate";
|
|
61
|
+
import { estimateTokens } from "../hooks/magic-context/read-session-formatting";
|
|
62
|
+
import {
|
|
63
|
+
byteSize,
|
|
64
|
+
prependTag,
|
|
65
|
+
stripTagPrefix,
|
|
66
|
+
stripWellFormedLeadingTagPrefix,
|
|
67
|
+
} from "../hooks/magic-context/tag-content-primitives";
|
|
68
|
+
import type { TagTarget } from "../hooks/magic-context/tag-messages";
|
|
69
|
+
import { toolInputStringBytes } from "../hooks/magic-context/tool-input-size";
|
|
70
|
+
import { TEXT_TAG_IDENTITY_MARKER } from "./tag-owner-id";
|
|
71
|
+
import type { Transcript, TranscriptMessage, TranscriptPart } from "./transcript";
|
|
72
|
+
|
|
73
|
+
// Re-exported so existing importers keep one source for the marker.
|
|
74
|
+
export { TEXT_TAG_IDENTITY_MARKER };
|
|
75
|
+
|
|
76
|
+
export interface TagTranscriptOptions {
|
|
77
|
+
/**
|
|
78
|
+
* When true, skip injecting `§N§` prefix into visible text. Tags
|
|
79
|
+
* still get assigned in the DB so historian/drops can reference
|
|
80
|
+
* them; the agent just doesn't see the markers. Used when the session's
|
|
81
|
+
* tool surface has no `mmc_reduce` tool to act on the markers. Cache-safe
|
|
82
|
+
* because the availability verdict is frozen per session.
|
|
83
|
+
*/
|
|
84
|
+
skipPrefixInjection?: boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Pi-only: map of messageId → raw-message fingerprint. When a NEW message
|
|
87
|
+
* text tag is created, its fingerprint is persisted on the tag row so a
|
|
88
|
+
* later pass can adopt the fallback-id tag onto the real SessionEntry id
|
|
89
|
+
* (keeping tag_number/§N§ stable). OpenCode omits this → tags store NULL
|
|
90
|
+
* → adoption never fires. Keyed by the bare messageId (not the `:pN`
|
|
91
|
+
* contentId) since all parts of a message share one fingerprint.
|
|
92
|
+
*/
|
|
93
|
+
entryFingerprintByMessageId?: ReadonlyMap<string, string>;
|
|
94
|
+
/**
|
|
95
|
+
* Stable Pi message ids observed on a prior pass. Their immutable parts may
|
|
96
|
+
* reuse tag assignments while this pass still reapplies visible prefixes and
|
|
97
|
+
* rebuilds the complete set of messages affected by each tag.
|
|
98
|
+
*/
|
|
99
|
+
reuseMessageIds?: ReadonlySet<string>;
|
|
100
|
+
/**
|
|
101
|
+
* Pi message ids whose persisted text-part vector no longer matches the
|
|
102
|
+
* current vector. Their parts use content-derived identities instead of
|
|
103
|
+
* positional `:pN` keys, so sibling insertion/deletion cannot rebind an
|
|
104
|
+
* older durable tag to different text.
|
|
105
|
+
*/
|
|
106
|
+
textIdentityDriftMessageIds?: ReadonlySet<string>;
|
|
107
|
+
/** Source-content cache shared with Pi's batched identity preflight. */
|
|
108
|
+
textIdentitySourceCache?: Map<number, string>;
|
|
109
|
+
/** Exact text/count pairs retained by Pi for safe lazy-token backfill reuse. */
|
|
110
|
+
textTokenCache?: Map<string, { text: string; tokenCount: number }>;
|
|
111
|
+
/** Exact tool-result text/count pairs retained under composite tag identity. */
|
|
112
|
+
toolTokenCache?: Map<string, { text: string; tokenCount: number }>;
|
|
113
|
+
/** Optional process-local benchmark callback; production callers omit it. */
|
|
114
|
+
onTiming?: (
|
|
115
|
+
phase: "identity" | "prefix" | "targets" | "tokenCounting",
|
|
116
|
+
elapsedMs: number,
|
|
117
|
+
) => void;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export interface TagTranscriptResult {
|
|
121
|
+
targets: Map<number, TagTarget>;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Tag eligible parts of a transcript and build TagTargets for them.
|
|
126
|
+
*
|
|
127
|
+
* "Eligible" means: parts that contribute meaningfully to the LLM input
|
|
128
|
+
* and whose content can be replaced when dropped. Specifically:
|
|
129
|
+
*
|
|
130
|
+
* - text parts (user or assistant): tagged as type "message", inject
|
|
131
|
+
* prefix into the visible text, target supports setContent.
|
|
132
|
+
* - thinking parts: NOT tagged. Reasoning content has provider-
|
|
133
|
+
* specific signed-content semantics (Anthropic redacted_thinking,
|
|
134
|
+
* etc.) and replacing them mid-conversation breaks signature
|
|
135
|
+
* verification. The historian's clear-reasoning pass handles them
|
|
136
|
+
* separately if needed.
|
|
137
|
+
* - tool_use parts (assistant tool invocations): tagged as type
|
|
138
|
+
* "tool", target supports drop/truncate via the tag-content
|
|
139
|
+
* primitives.
|
|
140
|
+
* - tool_result parts (folded into user messages by the Pi adapter):
|
|
141
|
+
* tagged as type "tool", paired with the corresponding invocation
|
|
142
|
+
* for full-pair drops.
|
|
143
|
+
* - image, file, structural, unknown: skipped.
|
|
144
|
+
*
|
|
145
|
+
* The contentId we pass to the tagger uses the part's stable id when
|
|
146
|
+
* available, otherwise a synthetic locator. Pi's adapter exposes:
|
|
147
|
+
* - tool_use parts: id = ToolCall.id (from pi-ai)
|
|
148
|
+
* - tool_result parts: id = ToolResultMessage.toolCallId
|
|
149
|
+
* - text parts: id = undefined → we synthesize from message+ordinal
|
|
150
|
+
*/
|
|
151
|
+
/**
|
|
152
|
+
* Per-callId aggregation of tool occurrences across the transcript.
|
|
153
|
+
* Built up during the walk and used to:
|
|
154
|
+
* 1. Assign one tag per call_id with byte_size = the tool_RESULT (output)
|
|
155
|
+
* size, and inputByteSize = the tool_use (args) size, tracked SEPARATELY
|
|
156
|
+
* (mirrors OpenCode tag-messages.ts). Reclaim accounting sums them
|
|
157
|
+
* (byteSize + inputByteSize + reasoning); folding args into byte_size too
|
|
158
|
+
* would double-count the args for a large-input/small-output tool.
|
|
159
|
+
* 2. Build a single aggregate TagTarget that mutates BOTH the
|
|
160
|
+
* invocation and result occurrences atomically, so a queued drop
|
|
161
|
+
* replaces both halves with a sentinel instead of last-write-wins.
|
|
162
|
+
*/
|
|
163
|
+
interface ToolOccurrence {
|
|
164
|
+
message: { info: { id?: string; role: string } };
|
|
165
|
+
part: TranscriptPart;
|
|
166
|
+
kind: "tool_use" | "tool_result";
|
|
167
|
+
/**
|
|
168
|
+
* The call's real input, captured the first time this pass overwrote it
|
|
169
|
+
* with the legacy marker, so a later real-argument render in the same pass
|
|
170
|
+
* can put it back.
|
|
171
|
+
*/
|
|
172
|
+
originalInput?: Record<string, unknown>;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
interface TagTranscriptTiming {
|
|
176
|
+
identity: number;
|
|
177
|
+
prefix: number;
|
|
178
|
+
targets: number;
|
|
179
|
+
tokenCounting: number;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
interface ToolAggregate {
|
|
183
|
+
callId: string;
|
|
184
|
+
/** Every occurrence seen so far belongs to a previously tagged stable message. */
|
|
185
|
+
identityReusable: boolean;
|
|
186
|
+
occurrences: ToolOccurrence[];
|
|
187
|
+
/** Largest byteSize seen across occurrences — used as the tag size. */
|
|
188
|
+
maxByteSize: number;
|
|
189
|
+
/** Token count paired with maxByteSize (the same output occurrence). */
|
|
190
|
+
maxTokenCount: number;
|
|
191
|
+
/** Tool name from the first occurrence we see one on. */
|
|
192
|
+
toolName: string | null;
|
|
193
|
+
/** Input byte size from the invocation occurrence (for storage projection). */
|
|
194
|
+
inputByteSize: number;
|
|
195
|
+
/** Persisted input-token count, or null for a legacy/unobserved invocation. */
|
|
196
|
+
inputTokenCount: number | null;
|
|
197
|
+
/** At least one assistant-side occurrence shares its message with native reasoning. */
|
|
198
|
+
requiresToolArcSkeleton: boolean;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function textIdentityDigest(value: string): string {
|
|
202
|
+
return createHash("sha256").update(value).digest("hex");
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function buildContentDerivedTextIds(messageId: string, parts: readonly TranscriptPart[]): string[] {
|
|
206
|
+
const sources = parts
|
|
207
|
+
.filter((part) => part.kind === "text")
|
|
208
|
+
.map((part) => stripTagPrefix(part.getText() ?? ""));
|
|
209
|
+
const vectorFingerprint = textIdentityDigest(JSON.stringify(sources));
|
|
210
|
+
const occurrences = new Map<string, number>();
|
|
211
|
+
|
|
212
|
+
return sources.map((source) => {
|
|
213
|
+
const contentFingerprint = textIdentityDigest(source);
|
|
214
|
+
const occurrence = occurrences.get(contentFingerprint) ?? 0;
|
|
215
|
+
occurrences.set(contentFingerprint, occurrence + 1);
|
|
216
|
+
return `${messageId}${TEXT_TAG_IDENTITY_MARKER}${vectorFingerprint}:${contentFingerprint}:o${occurrence}`;
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export function tagTranscript(
|
|
221
|
+
sessionId: string,
|
|
222
|
+
transcript: Transcript,
|
|
223
|
+
tagger: Tagger,
|
|
224
|
+
db: ContextDatabase,
|
|
225
|
+
options: TagTranscriptOptions = {},
|
|
226
|
+
): TagTranscriptResult {
|
|
227
|
+
const skipPrefixInjection = options.skipPrefixInjection === true;
|
|
228
|
+
const targets = new Map<number, TagTarget>();
|
|
229
|
+
const timing: TagTranscriptTiming | undefined = options.onTiming
|
|
230
|
+
? { identity: 0, prefix: 0, targets: 0, tokenCounting: 0 }
|
|
231
|
+
: undefined;
|
|
232
|
+
|
|
233
|
+
// Tool aggregation is keyed by the same owner+callId identity used by
|
|
234
|
+
// assignToolTag. OpenCode/Pi callId counters can repeat across turns, so
|
|
235
|
+
// a bare callId key can merge distinct invocations and replay drops/status
|
|
236
|
+
// changes against the wrong tool pair.
|
|
237
|
+
const toolAggregates = new Map<string, ToolAggregate & { tagId: number }>();
|
|
238
|
+
const openToolAggregateKeysByCallId = new Map<string, string[]>();
|
|
239
|
+
let activeToolResultRun: { callId: string; aggregateKey: string } | undefined;
|
|
240
|
+
|
|
241
|
+
// v3.3.1 Layer C (plan v3.3.1 Finding #16): the previous outer
|
|
242
|
+
// db.transaction() wrapper rolled back EVERY tag insert + savedSource
|
|
243
|
+
// when a single UNIQUE collision fired late in the walk. Per-tag
|
|
244
|
+
// SAVEPOINTs inside `assignToolTag` / `assignTag` already give us the
|
|
245
|
+
// atomicity we need. Removing the wrapper matches OpenCode's
|
|
246
|
+
// tag-messages.ts design — see the long comment there for the
|
|
247
|
+
// rationale (cache-bust amplifier story).
|
|
248
|
+
const conversationEnd = new ConversationEndGuard(transcript.messages);
|
|
249
|
+
|
|
250
|
+
for (let msgIndex = 0; msgIndex < transcript.messages.length; msgIndex += 1) {
|
|
251
|
+
const message = transcript.messages[msgIndex];
|
|
252
|
+
if (message === undefined) continue;
|
|
253
|
+
activeToolResultRun = undefined;
|
|
254
|
+
const messageId = message.info.id;
|
|
255
|
+
const reuseIdentity =
|
|
256
|
+
messageId !== undefined && options.reuseMessageIds?.has(messageId) === true;
|
|
257
|
+
|
|
258
|
+
let textOrdinal = 0;
|
|
259
|
+
let toolResultOrdinal = 0;
|
|
260
|
+
const parts = message.parts;
|
|
261
|
+
const messageHasNativeReasoning =
|
|
262
|
+
message.requiresToolArcSkeleton ??
|
|
263
|
+
(message.info.role === "assistant" && parts.some((part) => part.kind === "thinking"));
|
|
264
|
+
const contentDerivedTextIds =
|
|
265
|
+
messageId !== undefined && options.textIdentityDriftMessageIds?.has(messageId) === true
|
|
266
|
+
? buildContentDerivedTextIds(messageId, parts)
|
|
267
|
+
: undefined;
|
|
268
|
+
|
|
269
|
+
for (let partIndex = 0; partIndex < parts.length; partIndex += 1) {
|
|
270
|
+
const part = parts[partIndex];
|
|
271
|
+
if (part === undefined) continue;
|
|
272
|
+
const resultBlockOrdinal =
|
|
273
|
+
part.kind === "tool_result" ? toolResultOrdinal++ : undefined;
|
|
274
|
+
|
|
275
|
+
if (part.kind !== "tool_result") {
|
|
276
|
+
activeToolResultRun = undefined;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (part.kind === "text") {
|
|
280
|
+
// Synthetic message ids (Pi tail synthetic user with
|
|
281
|
+
// no id) cannot be tagged — there's no stable handle
|
|
282
|
+
// to bind a tag to across passes. Pass through
|
|
283
|
+
// untagged; this is rare (only happens for the
|
|
284
|
+
// dangling tool-result tail case in Pi).
|
|
285
|
+
if (messageId === undefined) {
|
|
286
|
+
textOrdinal += 1;
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
tagTextPart({
|
|
290
|
+
sessionId,
|
|
291
|
+
message,
|
|
292
|
+
messageId,
|
|
293
|
+
contentId:
|
|
294
|
+
contentDerivedTextIds?.[textOrdinal] ?? `${messageId}:p${textOrdinal}`,
|
|
295
|
+
msgIndex,
|
|
296
|
+
textOrdinal,
|
|
297
|
+
part,
|
|
298
|
+
tagger,
|
|
299
|
+
db,
|
|
300
|
+
targets,
|
|
301
|
+
skipPrefixInjection,
|
|
302
|
+
entryFingerprint: options.entryFingerprintByMessageId?.get(messageId) ?? null,
|
|
303
|
+
reuseIdentity: reuseIdentity || contentDerivedTextIds !== undefined,
|
|
304
|
+
timing,
|
|
305
|
+
textIdentitySourceCache: options.textIdentitySourceCache,
|
|
306
|
+
textTokenCache: options.textTokenCache,
|
|
307
|
+
});
|
|
308
|
+
textOrdinal += 1;
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if (part.kind === "tool_use" || part.kind === "tool_result") {
|
|
313
|
+
if (messageId === undefined) {
|
|
314
|
+
activeToolResultRun = undefined;
|
|
315
|
+
continue;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
const identityStart = timing ? performance.now() : 0;
|
|
319
|
+
const callId = part.id;
|
|
320
|
+
if (typeof callId !== "string" || callId.length === 0) {
|
|
321
|
+
activeToolResultRun = undefined;
|
|
322
|
+
// No stable callId to aggregate on. Tag independently.
|
|
323
|
+
tagToolPart({
|
|
324
|
+
sessionId,
|
|
325
|
+
message,
|
|
326
|
+
messageId,
|
|
327
|
+
msgIndex,
|
|
328
|
+
partIndex,
|
|
329
|
+
part,
|
|
330
|
+
tagger,
|
|
331
|
+
db,
|
|
332
|
+
targets,
|
|
333
|
+
skipPrefixInjection,
|
|
334
|
+
reuseIdentity,
|
|
335
|
+
timing,
|
|
336
|
+
});
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
const pendingKeys = openToolAggregateKeysByCallId.get(callId) ?? [];
|
|
341
|
+
let existingKey: string | undefined;
|
|
342
|
+
if (part.kind === "tool_result") {
|
|
343
|
+
if (
|
|
344
|
+
activeToolResultRun !== undefined &&
|
|
345
|
+
activeToolResultRun.callId === callId
|
|
346
|
+
) {
|
|
347
|
+
existingKey = activeToolResultRun.aggregateKey;
|
|
348
|
+
} else {
|
|
349
|
+
existingKey = findLastUnresolvedToolAggregateKey(
|
|
350
|
+
pendingKeys,
|
|
351
|
+
toolAggregates,
|
|
352
|
+
);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
const aggregateKey: string = existingKey ?? makeToolCompositeKey(messageId, callId);
|
|
356
|
+
// Keep block memoization separate from aggregate tag identity. The
|
|
357
|
+
// ordinal comes from this message's stable result-part order, not cache writes.
|
|
358
|
+
const tokenCacheKey =
|
|
359
|
+
resultBlockOrdinal === undefined
|
|
360
|
+
? aggregateKey
|
|
361
|
+
: `${aggregateKey}\0result-part:${messageId}:${resultBlockOrdinal}`;
|
|
362
|
+
const existing = toolAggregates.get(aggregateKey);
|
|
363
|
+
if (existing) {
|
|
364
|
+
existing.occurrences.push({ message, part, kind: part.kind });
|
|
365
|
+
existing.requiresToolArcSkeleton ||= messageHasNativeReasoning;
|
|
366
|
+
const canReuseIdentity = reuseIdentity && existing.identityReusable;
|
|
367
|
+
let text = "";
|
|
368
|
+
if (canReuseIdentity) {
|
|
369
|
+
// Prefix replay always needs result text. Byte length is also
|
|
370
|
+
// cheap enough to guard the durable growth invariant; BPE and
|
|
371
|
+
// DB writes remain staged behind an actual persisted-size bump.
|
|
372
|
+
if (part.kind === "tool_result") {
|
|
373
|
+
text = part.getText() ?? "";
|
|
374
|
+
applyGrownToolResultAccounting({
|
|
375
|
+
db,
|
|
376
|
+
sessionId,
|
|
377
|
+
tagger,
|
|
378
|
+
aggregate: existing,
|
|
379
|
+
byteSize: getToolPartByteSize(part, text),
|
|
380
|
+
part,
|
|
381
|
+
text,
|
|
382
|
+
timing,
|
|
383
|
+
tokenCache: options.toolTokenCache,
|
|
384
|
+
tokenCacheKey,
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
if (timing) timing.identity += performance.now() - identityStart;
|
|
388
|
+
} else {
|
|
389
|
+
const accounting = readAggregateToolAccounting(
|
|
390
|
+
part,
|
|
391
|
+
timing,
|
|
392
|
+
options.toolTokenCache,
|
|
393
|
+
tokenCacheKey,
|
|
394
|
+
);
|
|
395
|
+
text = accounting.text;
|
|
396
|
+
if (part.kind === "tool_result") {
|
|
397
|
+
applyGrownToolResultAccounting({
|
|
398
|
+
db,
|
|
399
|
+
sessionId,
|
|
400
|
+
tagger,
|
|
401
|
+
aggregate: existing,
|
|
402
|
+
byteSize: accounting.byteSize,
|
|
403
|
+
part,
|
|
404
|
+
text,
|
|
405
|
+
timing,
|
|
406
|
+
knownTokenCount: accounting.tokenCount,
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
if (existing.toolName === null && accounting.toolName) {
|
|
410
|
+
existing.toolName = accounting.toolName;
|
|
411
|
+
}
|
|
412
|
+
if (
|
|
413
|
+
existing.inputByteSize === 0 &&
|
|
414
|
+
part.kind === "tool_use" &&
|
|
415
|
+
accounting.inputByteSize > 0
|
|
416
|
+
) {
|
|
417
|
+
existing.inputByteSize = accounting.inputByteSize;
|
|
418
|
+
updateTagInputByteSize(
|
|
419
|
+
db,
|
|
420
|
+
sessionId,
|
|
421
|
+
existing.tagId,
|
|
422
|
+
accounting.inputByteSize,
|
|
423
|
+
);
|
|
424
|
+
}
|
|
425
|
+
if (
|
|
426
|
+
existing.inputTokenCount === null &&
|
|
427
|
+
part.kind === "tool_use" &&
|
|
428
|
+
accounting.inputTokenCount > 0
|
|
429
|
+
) {
|
|
430
|
+
existing.inputTokenCount = accounting.inputTokenCount;
|
|
431
|
+
updateTagInputTokenCount(
|
|
432
|
+
db,
|
|
433
|
+
sessionId,
|
|
434
|
+
existing.tagId,
|
|
435
|
+
accounting.inputTokenCount,
|
|
436
|
+
);
|
|
437
|
+
}
|
|
438
|
+
syncToolAggregateAccounting(tagger, sessionId, existing);
|
|
439
|
+
if (timing) timing.identity += performance.now() - identityStart;
|
|
440
|
+
}
|
|
441
|
+
existing.identityReusable &&= reuseIdentity;
|
|
442
|
+
applyToolPrefixAndTarget({
|
|
443
|
+
skipPrefixInjection,
|
|
444
|
+
part,
|
|
445
|
+
text,
|
|
446
|
+
tagId: existing.tagId,
|
|
447
|
+
aggregate: existing,
|
|
448
|
+
targets,
|
|
449
|
+
timing,
|
|
450
|
+
conversationEnd,
|
|
451
|
+
});
|
|
452
|
+
if (part.kind === "tool_result") {
|
|
453
|
+
markToolAggregateResolved(
|
|
454
|
+
callId,
|
|
455
|
+
aggregateKey,
|
|
456
|
+
openToolAggregateKeysByCallId,
|
|
457
|
+
);
|
|
458
|
+
activeToolResultRun = { callId, aggregateKey };
|
|
459
|
+
}
|
|
460
|
+
continue;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
const reusableTagId = reuseIdentity
|
|
464
|
+
? tagger.getToolTag(sessionId, callId, messageId)
|
|
465
|
+
: undefined;
|
|
466
|
+
const reusableAccounting = reuseIdentity
|
|
467
|
+
? tagger.getToolTagAccounting(sessionId, callId, messageId)
|
|
468
|
+
: undefined;
|
|
469
|
+
let aggregate: ToolAggregate & { tagId: number };
|
|
470
|
+
let text = "";
|
|
471
|
+
if (reusableTagId !== undefined && reusableAccounting !== undefined) {
|
|
472
|
+
aggregate = {
|
|
473
|
+
callId,
|
|
474
|
+
tagId: reusableTagId,
|
|
475
|
+
identityReusable: true,
|
|
476
|
+
occurrences: [{ message, part, kind: part.kind }],
|
|
477
|
+
// Stable identity does not imply stable payload size. Seed from
|
|
478
|
+
// the persisted row so unchanged results avoid BPE while a
|
|
479
|
+
// genuinely larger folded result can still bump accounting.
|
|
480
|
+
maxByteSize: reusableAccounting.byteSize,
|
|
481
|
+
maxTokenCount: reusableAccounting.tokenCount ?? 0,
|
|
482
|
+
toolName: null,
|
|
483
|
+
inputByteSize: reusableAccounting.inputByteSize,
|
|
484
|
+
inputTokenCount: reusableAccounting.inputTokenCount,
|
|
485
|
+
requiresToolArcSkeleton: messageHasNativeReasoning,
|
|
486
|
+
};
|
|
487
|
+
if (part.kind === "tool_result") {
|
|
488
|
+
text = part.getText() ?? "";
|
|
489
|
+
applyGrownToolResultAccounting({
|
|
490
|
+
db,
|
|
491
|
+
sessionId,
|
|
492
|
+
tagger,
|
|
493
|
+
aggregate,
|
|
494
|
+
byteSize: getToolPartByteSize(part, text),
|
|
495
|
+
part,
|
|
496
|
+
text,
|
|
497
|
+
timing,
|
|
498
|
+
tokenCache: options.toolTokenCache,
|
|
499
|
+
tokenCacheKey,
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
if (timing) timing.identity += performance.now() - identityStart;
|
|
503
|
+
} else {
|
|
504
|
+
const accounting = readAggregateToolAccounting(
|
|
505
|
+
part,
|
|
506
|
+
timing,
|
|
507
|
+
options.toolTokenCache,
|
|
508
|
+
tokenCacheKey,
|
|
509
|
+
);
|
|
510
|
+
text = accounting.text;
|
|
511
|
+
const outputByteSize = part.kind === "tool_result" ? accounting.byteSize : 0;
|
|
512
|
+
const outputTokenCount =
|
|
513
|
+
part.kind === "tool_result" ? accounting.tokenCount : 0;
|
|
514
|
+
const firstInputTokenCount =
|
|
515
|
+
part.kind === "tool_use" ? accounting.inputTokenCount : 0;
|
|
516
|
+
const tagId = tagger.assignToolTag(
|
|
517
|
+
sessionId,
|
|
518
|
+
callId,
|
|
519
|
+
messageId,
|
|
520
|
+
outputByteSize,
|
|
521
|
+
db,
|
|
522
|
+
0,
|
|
523
|
+
accounting.toolName,
|
|
524
|
+
accounting.inputByteSize,
|
|
525
|
+
() => ({
|
|
526
|
+
tokenCount: outputTokenCount,
|
|
527
|
+
inputTokenCount: firstInputTokenCount,
|
|
528
|
+
reasoningTokenCount: null,
|
|
529
|
+
}),
|
|
530
|
+
);
|
|
531
|
+
const persistedAccounting = tagger.getToolTagAccounting(
|
|
532
|
+
sessionId,
|
|
533
|
+
callId,
|
|
534
|
+
messageId,
|
|
535
|
+
);
|
|
536
|
+
aggregate = {
|
|
537
|
+
callId,
|
|
538
|
+
tagId,
|
|
539
|
+
identityReusable: false,
|
|
540
|
+
occurrences: [{ message, part, kind: part.kind }],
|
|
541
|
+
maxByteSize: persistedAccounting?.byteSize ?? outputByteSize,
|
|
542
|
+
maxTokenCount: persistedAccounting?.tokenCount ?? outputTokenCount,
|
|
543
|
+
toolName: accounting.toolName,
|
|
544
|
+
inputByteSize:
|
|
545
|
+
persistedAccounting?.inputByteSize ??
|
|
546
|
+
(part.kind === "tool_use" ? accounting.inputByteSize : 0),
|
|
547
|
+
inputTokenCount:
|
|
548
|
+
persistedAccounting?.inputTokenCount ??
|
|
549
|
+
(part.kind === "tool_use" ? firstInputTokenCount : null),
|
|
550
|
+
requiresToolArcSkeleton: messageHasNativeReasoning,
|
|
551
|
+
};
|
|
552
|
+
if (part.kind === "tool_result") {
|
|
553
|
+
applyGrownToolResultAccounting({
|
|
554
|
+
db,
|
|
555
|
+
sessionId,
|
|
556
|
+
tagger,
|
|
557
|
+
aggregate,
|
|
558
|
+
byteSize: accounting.byteSize,
|
|
559
|
+
part,
|
|
560
|
+
text,
|
|
561
|
+
timing,
|
|
562
|
+
knownTokenCount: accounting.tokenCount,
|
|
563
|
+
});
|
|
564
|
+
}
|
|
565
|
+
syncToolAggregateAccounting(tagger, sessionId, aggregate);
|
|
566
|
+
if (timing) timing.identity += performance.now() - identityStart;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
toolAggregates.set(aggregateKey, aggregate);
|
|
570
|
+
if (part.kind === "tool_use") {
|
|
571
|
+
openToolAggregateKeysByCallId.set(callId, [...pendingKeys, aggregateKey]);
|
|
572
|
+
}
|
|
573
|
+
applyToolPrefixAndTarget({
|
|
574
|
+
skipPrefixInjection,
|
|
575
|
+
part,
|
|
576
|
+
text,
|
|
577
|
+
tagId: aggregate.tagId,
|
|
578
|
+
aggregate,
|
|
579
|
+
targets,
|
|
580
|
+
timing,
|
|
581
|
+
conversationEnd,
|
|
582
|
+
});
|
|
583
|
+
if (part.kind === "tool_result") {
|
|
584
|
+
markToolAggregateResolved(callId, aggregateKey, openToolAggregateKeysByCallId);
|
|
585
|
+
activeToolResultRun = { callId, aggregateKey };
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
// thinking, image, file, structural, unknown → skip.
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
if (timing && options.onTiming) {
|
|
593
|
+
options.onTiming("identity", timing.identity);
|
|
594
|
+
options.onTiming("prefix", timing.prefix);
|
|
595
|
+
options.onTiming("targets", timing.targets);
|
|
596
|
+
options.onTiming("tokenCounting", timing.tokenCounting);
|
|
597
|
+
}
|
|
598
|
+
return { targets };
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
interface AggregateToolAccounting {
|
|
602
|
+
text: string;
|
|
603
|
+
byteSize: number;
|
|
604
|
+
tokenCount: number;
|
|
605
|
+
toolName: string | null;
|
|
606
|
+
inputByteSize: number;
|
|
607
|
+
inputTokenCount: number;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
interface GrownToolResultAccountingArgs {
|
|
611
|
+
db: ContextDatabase;
|
|
612
|
+
sessionId: string;
|
|
613
|
+
tagger: Tagger;
|
|
614
|
+
aggregate: ToolAggregate & { tagId: number };
|
|
615
|
+
byteSize: number;
|
|
616
|
+
part: TranscriptPart;
|
|
617
|
+
text: string;
|
|
618
|
+
timing: TagTranscriptTiming | undefined;
|
|
619
|
+
tokenCache?: Map<string, { text: string; tokenCount: number }>;
|
|
620
|
+
tokenCacheKey?: string;
|
|
621
|
+
knownTokenCount?: number;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
function syncToolAggregateAccounting(
|
|
625
|
+
tagger: Tagger,
|
|
626
|
+
sessionId: string,
|
|
627
|
+
aggregate: ToolAggregate & { tagId: number },
|
|
628
|
+
): void {
|
|
629
|
+
tagger.setToolTagAccounting(sessionId, aggregate.tagId, {
|
|
630
|
+
byteSize: aggregate.maxByteSize,
|
|
631
|
+
tokenCount: aggregate.maxTokenCount,
|
|
632
|
+
inputByteSize: aggregate.inputByteSize,
|
|
633
|
+
inputTokenCount: aggregate.inputTokenCount,
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
function applyGrownToolResultAccounting(args: GrownToolResultAccountingArgs): void {
|
|
638
|
+
if (args.byteSize <= args.aggregate.maxByteSize) return;
|
|
639
|
+
|
|
640
|
+
let tokenCount = args.knownTokenCount;
|
|
641
|
+
if (tokenCount !== undefined && args.tokenCacheKey) {
|
|
642
|
+
args.tokenCache?.set(args.tokenCacheKey, { text: args.text, tokenCount });
|
|
643
|
+
}
|
|
644
|
+
if (tokenCount === undefined) {
|
|
645
|
+
const tokenStart = args.timing ? performance.now() : 0;
|
|
646
|
+
tokenCount = getCachedToolPartTokenCount(
|
|
647
|
+
args.part,
|
|
648
|
+
args.text,
|
|
649
|
+
args.tokenCache,
|
|
650
|
+
args.tokenCacheKey,
|
|
651
|
+
);
|
|
652
|
+
if (args.timing) args.timing.tokenCounting += performance.now() - tokenStart;
|
|
653
|
+
}
|
|
654
|
+
args.aggregate.maxByteSize = args.byteSize;
|
|
655
|
+
args.aggregate.maxTokenCount = tokenCount;
|
|
656
|
+
updateTagByteSize(args.db, args.sessionId, args.aggregate.tagId, args.byteSize);
|
|
657
|
+
updateTagTokenCount(args.db, args.sessionId, args.aggregate.tagId, tokenCount);
|
|
658
|
+
syncToolAggregateAccounting(args.tagger, args.sessionId, args.aggregate);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
function readAggregateToolAccounting(
|
|
662
|
+
part: TranscriptPart,
|
|
663
|
+
timing: TagTranscriptTiming | undefined,
|
|
664
|
+
tokenCache?: Map<string, { text: string; tokenCount: number }>,
|
|
665
|
+
tokenCacheKey?: string,
|
|
666
|
+
): AggregateToolAccounting {
|
|
667
|
+
const text = part.getText() ?? "";
|
|
668
|
+
const byteSize = getToolPartByteSize(part, text);
|
|
669
|
+
const metadata = part.getToolMetadata();
|
|
670
|
+
let tokenCount = 0;
|
|
671
|
+
if (part.kind === "tool_result") {
|
|
672
|
+
const tokenStart = timing ? performance.now() : 0;
|
|
673
|
+
tokenCount = getCachedToolPartTokenCount(part, text, tokenCache, tokenCacheKey);
|
|
674
|
+
if (timing) timing.tokenCounting += performance.now() - tokenStart;
|
|
675
|
+
}
|
|
676
|
+
return {
|
|
677
|
+
text,
|
|
678
|
+
byteSize,
|
|
679
|
+
tokenCount,
|
|
680
|
+
toolName: metadata.toolName ?? null,
|
|
681
|
+
inputByteSize: metadata.inputByteSize,
|
|
682
|
+
inputTokenCount: metadata.inputTokenCount,
|
|
683
|
+
};
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
interface ApplyToolPrefixAndTargetArgs {
|
|
687
|
+
skipPrefixInjection: boolean;
|
|
688
|
+
part: TranscriptPart;
|
|
689
|
+
text: string;
|
|
690
|
+
tagId: number;
|
|
691
|
+
aggregate: ToolAggregate;
|
|
692
|
+
targets: Map<number, TagTarget>;
|
|
693
|
+
timing: TagTranscriptTiming | undefined;
|
|
694
|
+
conversationEnd: ConversationEndGuard;
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
function partHasContent(part: TranscriptPart): boolean {
|
|
698
|
+
return part.kind !== "text" || (part.getText() ?? "").trim().length > 0;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
/**
|
|
702
|
+
* Keeps structural tool removal from ending the provider request on an
|
|
703
|
+
* assistant turn, which models without assistant prefill support reject.
|
|
704
|
+
*
|
|
705
|
+
* The request ends with the newest message that has any content. Tool results
|
|
706
|
+
* there are what close the conversation with a user turn, so removal may take
|
|
707
|
+
* one only while that message keeps other content. Shared by every target one
|
|
708
|
+
* tagging pass builds, so drops earlier in the same pass count as removed.
|
|
709
|
+
*/
|
|
710
|
+
class ConversationEndGuard {
|
|
711
|
+
private readonly end: TranscriptMessage | undefined;
|
|
712
|
+
private readonly removed = new Set<unknown>();
|
|
713
|
+
|
|
714
|
+
constructor(messages: readonly TranscriptMessage[]) {
|
|
715
|
+
for (let index = messages.length - 1; index >= 0 && !this.end; index -= 1) {
|
|
716
|
+
const message = messages[index];
|
|
717
|
+
if (message?.parts.some(partHasContent)) this.end = message;
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
wouldStrand(occurrences: readonly ToolOccurrence[]): boolean {
|
|
722
|
+
const end = this.end;
|
|
723
|
+
if (!end || !occurrences.some((occ) => occ.message === end)) return false;
|
|
724
|
+
const leaving = new Set(occurrences.map((occ) => partKey(occ.part)));
|
|
725
|
+
const survives = (part: TranscriptPart) =>
|
|
726
|
+
!leaving.has(partKey(part)) && !this.removed.has(partKey(part));
|
|
727
|
+
return end.info.role === "assistant"
|
|
728
|
+
? !end.parts.some((part) => part.kind === "tool_result" && survives(part))
|
|
729
|
+
: !end.parts.some((part) => partHasContent(part) && survives(part));
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
noteRemoved(occurrences: readonly ToolOccurrence[]): void {
|
|
733
|
+
for (const occ of occurrences) this.removed.add(partKey(occ.part));
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
/**
|
|
738
|
+
* Adapters may hand out a fresh proxy object per read of `message.parts`, so
|
|
739
|
+
* tool parts are matched by kind and tool-call id; parts without an id fall
|
|
740
|
+
* back to object identity.
|
|
741
|
+
*/
|
|
742
|
+
function partKey(part: TranscriptPart): unknown {
|
|
743
|
+
return part.id === undefined ? part : `${part.kind}\u0000${part.id}`;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
function applyToolPrefixAndTarget(args: ApplyToolPrefixAndTargetArgs): void {
|
|
747
|
+
if (!args.skipPrefixInjection && args.part.kind === "tool_result") {
|
|
748
|
+
const prefixStart = args.timing ? performance.now() : 0;
|
|
749
|
+
args.part.setText(prependTag(args.tagId, args.text));
|
|
750
|
+
if (args.timing) args.timing.prefix += performance.now() - prefixStart;
|
|
751
|
+
}
|
|
752
|
+
const targetStart = args.timing ? performance.now() : 0;
|
|
753
|
+
args.targets.set(
|
|
754
|
+
args.tagId,
|
|
755
|
+
buildAggregateTarget(
|
|
756
|
+
args.tagId,
|
|
757
|
+
args.aggregate.occurrences,
|
|
758
|
+
args.aggregate.requiresToolArcSkeleton,
|
|
759
|
+
args.conversationEnd,
|
|
760
|
+
),
|
|
761
|
+
);
|
|
762
|
+
if (args.timing) args.timing.targets += performance.now() - targetStart;
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
function findLastUnresolvedToolAggregateKey(
|
|
766
|
+
pendingKeys: string[],
|
|
767
|
+
toolAggregates: Map<string, ToolAggregate & { tagId: number }>,
|
|
768
|
+
): string | undefined {
|
|
769
|
+
for (let i = pendingKeys.length - 1; i >= 0; i -= 1) {
|
|
770
|
+
const key = pendingKeys[i];
|
|
771
|
+
if (key === undefined) continue;
|
|
772
|
+
const aggregate = toolAggregates.get(key);
|
|
773
|
+
if (aggregate === undefined) continue;
|
|
774
|
+
if (!aggregate.occurrences.some((occ) => occ.kind === "tool_result")) {
|
|
775
|
+
return key;
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
return undefined;
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
function markToolAggregateResolved(
|
|
782
|
+
callId: string,
|
|
783
|
+
aggregateKey: string,
|
|
784
|
+
openToolAggregateKeysByCallId: Map<string, string[]>,
|
|
785
|
+
): void {
|
|
786
|
+
const pendingKeys = openToolAggregateKeysByCallId.get(callId);
|
|
787
|
+
if (pendingKeys === undefined) return;
|
|
788
|
+
const nextPendingKeys = pendingKeys.filter((key) => key !== aggregateKey);
|
|
789
|
+
if (nextPendingKeys.length === 0) {
|
|
790
|
+
openToolAggregateKeysByCallId.delete(callId);
|
|
791
|
+
return;
|
|
792
|
+
}
|
|
793
|
+
openToolAggregateKeysByCallId.set(callId, nextPendingKeys);
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
/** Real-tokenizer count for tagged text (images bill by visual tokens). */
|
|
797
|
+
function estimateTagTextTokens(text: string): number {
|
|
798
|
+
if (!text) return 0;
|
|
799
|
+
if (text.startsWith("data:image/")) return estimateImageTokensFromDataUrl(text);
|
|
800
|
+
return estimateTokens(text);
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
function getToolPartByteSize(part: TranscriptPart, text: string): number {
|
|
804
|
+
const textByteSize = byteSize(text);
|
|
805
|
+
if (textByteSize > 0 || part.kind !== "tool_result") return textByteSize;
|
|
806
|
+
return getNonTextToolResultByteSize(part);
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
/**
|
|
810
|
+
* Real-tokenizer mirror of {@link getToolPartByteSize}: token count of a tool
|
|
811
|
+
* part's output text (falling back to the raw payload for non-text results,
|
|
812
|
+
* matching the byte path so token_count stays consistent with byte_size).
|
|
813
|
+
*/
|
|
814
|
+
function getToolPartTokenCount(part: TranscriptPart, text: string): number {
|
|
815
|
+
if (text.length > 0 || part.kind !== "tool_result") return estimateTokens(text);
|
|
816
|
+
const raw = part.rawByteSize?.();
|
|
817
|
+
if (typeof raw === "number" && raw > 0) {
|
|
818
|
+
const record = isRecord(part) ? part : undefined;
|
|
819
|
+
const content =
|
|
820
|
+
record?.content ??
|
|
821
|
+
record?.rawContent ??
|
|
822
|
+
record?.rawPart ??
|
|
823
|
+
record?.part ??
|
|
824
|
+
record?.data ??
|
|
825
|
+
record?.image ??
|
|
826
|
+
record?.source;
|
|
827
|
+
const serialized = safeJsonStringify(content ?? part);
|
|
828
|
+
return serialized === undefined ? 0 : estimateTokens(serialized);
|
|
829
|
+
}
|
|
830
|
+
return 0;
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
function getCachedToolPartTokenCount(
|
|
834
|
+
part: TranscriptPart,
|
|
835
|
+
text: string,
|
|
836
|
+
cache?: Map<string, { text: string; tokenCount: number }>,
|
|
837
|
+
cacheKey?: string,
|
|
838
|
+
): number {
|
|
839
|
+
const cached = cacheKey ? cache?.get(cacheKey) : undefined;
|
|
840
|
+
if (cached?.text === text) return cached.tokenCount;
|
|
841
|
+
const tokenCount = getToolPartTokenCount(part, text);
|
|
842
|
+
if (cacheKey) cache?.set(cacheKey, { text, tokenCount });
|
|
843
|
+
return tokenCount;
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
function getNonTextToolResultByteSize(part: TranscriptPart): number {
|
|
847
|
+
// Prefer the adapter's exact raw-payload size when available (Pi's
|
|
848
|
+
// tool_result proxy can serialize the real content array, incl. images).
|
|
849
|
+
const raw = part.rawByteSize?.();
|
|
850
|
+
if (typeof raw === "number" && raw > 0) return raw;
|
|
851
|
+
const record = isRecord(part) ? part : undefined;
|
|
852
|
+
const content =
|
|
853
|
+
record?.content ??
|
|
854
|
+
record?.rawContent ??
|
|
855
|
+
record?.rawPart ??
|
|
856
|
+
record?.part ??
|
|
857
|
+
record?.data ??
|
|
858
|
+
record?.image ??
|
|
859
|
+
record?.source;
|
|
860
|
+
const serialized = safeJsonStringify(content ?? part);
|
|
861
|
+
return serialized === undefined ? 0 : byteSize(serialized);
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
function safeJsonStringify(value: unknown): string | undefined {
|
|
865
|
+
try {
|
|
866
|
+
return JSON.stringify(value);
|
|
867
|
+
} catch {
|
|
868
|
+
return undefined;
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
873
|
+
return typeof value === "object" && value !== null;
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
interface TagTextPartArgs {
|
|
877
|
+
sessionId: string;
|
|
878
|
+
message: { info: { id?: string; role: string } };
|
|
879
|
+
messageId: string;
|
|
880
|
+
contentId: string;
|
|
881
|
+
msgIndex: number;
|
|
882
|
+
textOrdinal: number;
|
|
883
|
+
part: TranscriptPart;
|
|
884
|
+
tagger: Tagger;
|
|
885
|
+
db: ContextDatabase;
|
|
886
|
+
targets: Map<number, TagTarget>;
|
|
887
|
+
skipPrefixInjection: boolean;
|
|
888
|
+
entryFingerprint: string | null;
|
|
889
|
+
reuseIdentity: boolean;
|
|
890
|
+
timing?: TagTranscriptTiming;
|
|
891
|
+
textIdentitySourceCache?: Map<number, string>;
|
|
892
|
+
textTokenCache?: Map<string, { text: string; tokenCount: number }>;
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
function tagTextPart(args: TagTextPartArgs): void {
|
|
896
|
+
const identityStart = args.timing ? performance.now() : 0;
|
|
897
|
+
const text = args.part.getText() ?? "";
|
|
898
|
+
// Pi and OMP can expose provider framing as assistant text blocks. Treat a
|
|
899
|
+
// previously prefixed blank as blank too, so MC never turns inert framing
|
|
900
|
+
// into a tag-bearing part that later strip logic could mistake for content.
|
|
901
|
+
if (
|
|
902
|
+
args.message.info.role === "assistant" &&
|
|
903
|
+
stripWellFormedLeadingTagPrefix(text).trim().length === 0
|
|
904
|
+
) {
|
|
905
|
+
if (args.timing) args.timing.identity += performance.now() - identityStart;
|
|
906
|
+
return;
|
|
907
|
+
}
|
|
908
|
+
const contentId = args.contentId;
|
|
909
|
+
const reusableTagId = args.reuseIdentity
|
|
910
|
+
? args.tagger.getTag(args.sessionId, contentId, "message")
|
|
911
|
+
: undefined;
|
|
912
|
+
if (reusableTagId !== undefined) {
|
|
913
|
+
if (args.timing) args.timing.identity += performance.now() - identityStart;
|
|
914
|
+
applyTextPrefixAndTarget(args, reusableTagId, text);
|
|
915
|
+
return;
|
|
916
|
+
}
|
|
917
|
+
const tagId = args.tagger.assignTag(
|
|
918
|
+
args.sessionId,
|
|
919
|
+
contentId,
|
|
920
|
+
"message",
|
|
921
|
+
byteSize(text),
|
|
922
|
+
args.db,
|
|
923
|
+
0,
|
|
924
|
+
null,
|
|
925
|
+
0,
|
|
926
|
+
args.entryFingerprint,
|
|
927
|
+
// Lazy: fires only on fresh insert. Strip any §N§ prefix so a re-tag
|
|
928
|
+
// from already-prefixed text still tokenizes the pristine content.
|
|
929
|
+
() => {
|
|
930
|
+
const tokenStart = args.timing ? performance.now() : 0;
|
|
931
|
+
const cached = args.textTokenCache?.get(contentId);
|
|
932
|
+
const tokenCount =
|
|
933
|
+
cached?.text === text
|
|
934
|
+
? cached.tokenCount
|
|
935
|
+
: estimateTagTextTokens(stripTagPrefix(text));
|
|
936
|
+
if (cached?.text !== text) {
|
|
937
|
+
args.textTokenCache?.set(contentId, { text, tokenCount });
|
|
938
|
+
}
|
|
939
|
+
const counts = {
|
|
940
|
+
tokenCount,
|
|
941
|
+
inputTokenCount: null,
|
|
942
|
+
reasoningTokenCount: null,
|
|
943
|
+
};
|
|
944
|
+
if (args.timing) args.timing.tokenCounting += performance.now() - tokenStart;
|
|
945
|
+
return counts;
|
|
946
|
+
},
|
|
947
|
+
);
|
|
948
|
+
|
|
949
|
+
// Persist the original (pre-tagged) source content so caveman
|
|
950
|
+
// compression and other "compress from original" heuristics have
|
|
951
|
+
// pristine text to read on later passes. saveSourceContent uses
|
|
952
|
+
// INSERT OR IGNORE — first write wins; later passes that re-tag
|
|
953
|
+
// the same (sessionId, tagId) pair from already-prefixed text won't
|
|
954
|
+
// overwrite the original. Cache-stable.
|
|
955
|
+
//
|
|
956
|
+
// We strip any existing §N§ prefix before saving in case a previous
|
|
957
|
+
// pass already injected one and the persisted source got lost
|
|
958
|
+
// (e.g. legacy session created before this code shipped). For new
|
|
959
|
+
// sessions stripTagPrefix is a no-op on the very first pass.
|
|
960
|
+
const sourceContent = stripTagPrefix(text);
|
|
961
|
+
if (sourceContent.trim().length > 0) {
|
|
962
|
+
saveSourceContent(args.db, args.sessionId, tagId, sourceContent);
|
|
963
|
+
args.textIdentitySourceCache?.set(tagId, sourceContent);
|
|
964
|
+
}
|
|
965
|
+
if (args.timing) args.timing.identity += performance.now() - identityStart;
|
|
966
|
+
applyTextPrefixAndTarget(args, tagId, text);
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
function applyTextPrefixAndTarget(args: TagTextPartArgs, tagId: number, text: string): void {
|
|
970
|
+
if (!args.skipPrefixInjection) {
|
|
971
|
+
const prefixStart = args.timing ? performance.now() : 0;
|
|
972
|
+
args.part.setText(prependTag(tagId, text));
|
|
973
|
+
if (args.timing) args.timing.prefix += performance.now() - prefixStart;
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
const targetStart = args.timing ? performance.now() : 0;
|
|
977
|
+
args.targets.set(
|
|
978
|
+
tagId,
|
|
979
|
+
buildTextTarget(
|
|
980
|
+
args.part,
|
|
981
|
+
args.message,
|
|
982
|
+
args.skipPrefixInjection ? "" : prependTag(tagId, ""),
|
|
983
|
+
),
|
|
984
|
+
);
|
|
985
|
+
if (args.timing) args.timing.targets += performance.now() - targetStart;
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
interface TagToolPartArgs {
|
|
989
|
+
sessionId: string;
|
|
990
|
+
message: { info: { id?: string; role: string } };
|
|
991
|
+
messageId: string;
|
|
992
|
+
msgIndex: number;
|
|
993
|
+
partIndex: number;
|
|
994
|
+
part: TranscriptPart;
|
|
995
|
+
tagger: Tagger;
|
|
996
|
+
db: ContextDatabase;
|
|
997
|
+
targets: Map<number, TagTarget>;
|
|
998
|
+
skipPrefixInjection: boolean;
|
|
999
|
+
reuseIdentity: boolean;
|
|
1000
|
+
timing?: TagTranscriptTiming;
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
function tagToolPart(args: TagToolPartArgs): void {
|
|
1004
|
+
const identityStart = args.timing ? performance.now() : 0;
|
|
1005
|
+
// Prefer the part's stable id (tool call id from Pi/OpenCode); fall
|
|
1006
|
+
// back to a synthetic locator. Tool calls and their results MAY
|
|
1007
|
+
// share an id (Pi sets toolCallId on ToolResultMessage to match the
|
|
1008
|
+
// originating ToolCall.id); when that happens, both tag operations
|
|
1009
|
+
// resolve to the same tag number — desired behavior, since drops
|
|
1010
|
+
// target the call-id pair as a unit.
|
|
1011
|
+
const stableId = args.part.id;
|
|
1012
|
+
const contentId = stableId ?? `${args.messageId}:t${args.partIndex}`;
|
|
1013
|
+
const reusableTagId = args.reuseIdentity
|
|
1014
|
+
? args.tagger.getToolTag(args.sessionId, contentId, contentId)
|
|
1015
|
+
: undefined;
|
|
1016
|
+
if (reusableTagId !== undefined) {
|
|
1017
|
+
const text = args.part.kind === "tool_result" ? (args.part.getText() ?? "") : "";
|
|
1018
|
+
if (args.timing) args.timing.identity += performance.now() - identityStart;
|
|
1019
|
+
applySingleToolPrefixAndTarget(args, reusableTagId, text);
|
|
1020
|
+
return;
|
|
1021
|
+
}
|
|
1022
|
+
const text = args.part.getText() ?? "";
|
|
1023
|
+
const toolByteSize = getToolPartByteSize(args.part, text);
|
|
1024
|
+
const meta = args.part.getToolMetadata();
|
|
1025
|
+
const tokenStart = args.timing ? performance.now() : 0;
|
|
1026
|
+
const toolTokenCount = getToolPartTokenCount(args.part, text);
|
|
1027
|
+
if (args.timing) args.timing.tokenCounting += performance.now() - tokenStart;
|
|
1028
|
+
// v3.3.1 Layer C: synthetic ownership for the no-callId Pi
|
|
1029
|
+
// fallback. Owner == callId == contentId. The composite key
|
|
1030
|
+
// collapses to a unique synthetic identifier per part, preserving
|
|
1031
|
+
// the legacy "each part gets its own tag" behavior while
|
|
1032
|
+
// satisfying the composite-identity contract (TagEntry.tool_owner_message_id
|
|
1033
|
+
// is non-null, lazy-adoption path is correctly bypassed).
|
|
1034
|
+
const tagId = args.tagger.assignToolTag(
|
|
1035
|
+
args.sessionId,
|
|
1036
|
+
contentId,
|
|
1037
|
+
contentId,
|
|
1038
|
+
toolByteSize,
|
|
1039
|
+
args.db,
|
|
1040
|
+
0,
|
|
1041
|
+
meta.toolName ?? null,
|
|
1042
|
+
meta.inputByteSize,
|
|
1043
|
+
() => {
|
|
1044
|
+
const tokenStart = args.timing ? performance.now() : 0;
|
|
1045
|
+
const counts = {
|
|
1046
|
+
tokenCount: toolTokenCount,
|
|
1047
|
+
inputTokenCount: meta.inputTokenCount,
|
|
1048
|
+
reasoningTokenCount: null,
|
|
1049
|
+
};
|
|
1050
|
+
if (args.timing) args.timing.tokenCounting += performance.now() - tokenStart;
|
|
1051
|
+
return counts;
|
|
1052
|
+
},
|
|
1053
|
+
);
|
|
1054
|
+
if (args.timing) args.timing.identity += performance.now() - identityStart;
|
|
1055
|
+
applySingleToolPrefixAndTarget(args, tagId, text);
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
function applySingleToolPrefixAndTarget(args: TagToolPartArgs, tagId: number, text: string): void {
|
|
1059
|
+
// For tool parts, the visible payload is the tool result text. We
|
|
1060
|
+
// can inject the tag prefix into it for in-text references; this
|
|
1061
|
+
// matches the OpenCode behavior of tagging tool outputs.
|
|
1062
|
+
if (!args.skipPrefixInjection && args.part.kind === "tool_result") {
|
|
1063
|
+
const prefixStart = args.timing ? performance.now() : 0;
|
|
1064
|
+
args.part.setText(prependTag(tagId, text));
|
|
1065
|
+
if (args.timing) args.timing.prefix += performance.now() - prefixStart;
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
const targetStart = args.timing ? performance.now() : 0;
|
|
1069
|
+
args.targets.set(tagId, buildToolTarget(args.part, args.message, tagId));
|
|
1070
|
+
if (args.timing) args.timing.targets += performance.now() - targetStart;
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
function setToolContentOrText(part: TranscriptPart, content: string): boolean {
|
|
1074
|
+
try {
|
|
1075
|
+
if (part.setToolOutput(content)) return true;
|
|
1076
|
+
} catch {
|
|
1077
|
+
// Pi assistant tool_use parts deliberately assert if callers try
|
|
1078
|
+
// to write a nonexistent output slot. Truncated-mode drops still
|
|
1079
|
+
// need to shrink the invocation, so fall back to visible text/args
|
|
1080
|
+
// replacement while preserving the adapter-level invariant.
|
|
1081
|
+
}
|
|
1082
|
+
return part.setText(content);
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
/**
|
|
1086
|
+
* Build a TagTarget that walks ALL occurrences of a tool call (invocation
|
|
1087
|
+
* + result) when mutating. This is the per-callId aggregate target used
|
|
1088
|
+
* by `tagTranscript` so a single drop replaces both halves.
|
|
1089
|
+
*
|
|
1090
|
+
* The closures hold a reference to the same `occurrences` array stored
|
|
1091
|
+
* on the aggregate, so when the array gets mutated (a second occurrence
|
|
1092
|
+
* is pushed mid-walk), the next call to setContent/drop/truncate sees
|
|
1093
|
+
* all occurrences automatically. Callers MUST rebuild the target after
|
|
1094
|
+
* pushing a new occurrence so the targets map points to a fresh closure
|
|
1095
|
+
* over the updated array — otherwise consumers that captured the target
|
|
1096
|
+
* before the push won't see the new occurrence.
|
|
1097
|
+
*
|
|
1098
|
+
* Mirrors OpenCode's createToolDropTarget semantics in tool-drop-target.ts.
|
|
1099
|
+
*/
|
|
1100
|
+
function buildAggregateTarget(
|
|
1101
|
+
tagId: number,
|
|
1102
|
+
occurrences: ToolOccurrence[],
|
|
1103
|
+
requiresToolArcSkeleton: boolean,
|
|
1104
|
+
conversationEnd?: ConversationEndGuard,
|
|
1105
|
+
): TagTarget {
|
|
1106
|
+
const role = occurrences[0]?.message.info.role ?? "user";
|
|
1107
|
+
const messageId = occurrences[0]?.message.info.id;
|
|
1108
|
+
|
|
1109
|
+
const truncate = (): "truncated" | "absent" => {
|
|
1110
|
+
// Keep the tool call and its result, but replace the call arguments with
|
|
1111
|
+
// a non-executable marker and the result content with the dropped marker.
|
|
1112
|
+
// Legacy render, replayed only for `drop_mode = 'truncated'` tags until a
|
|
1113
|
+
// HARD fold converts them; new drops use skeletonReal().
|
|
1114
|
+
const sentinel = `[dropped \u00a7${tagId}\u00a7]`;
|
|
1115
|
+
let any = false;
|
|
1116
|
+
for (const occ of occurrences) {
|
|
1117
|
+
if (occ.kind === "tool_use" && occ.part.setToolInput) {
|
|
1118
|
+
occ.originalInput ??= occ.part.getToolInput?.() ?? undefined;
|
|
1119
|
+
if (occ.part.setToolInput(droppedInputMarker(tagId))) any = true;
|
|
1120
|
+
} else if (setToolContentOrText(occ.part, sentinel)) {
|
|
1121
|
+
any = true;
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
return any ? "truncated" : "absent";
|
|
1125
|
+
};
|
|
1126
|
+
|
|
1127
|
+
const complete = (): boolean =>
|
|
1128
|
+
occurrences.some((occ) => occ.kind === "tool_use") &&
|
|
1129
|
+
occurrences.some((occ) => occ.kind === "tool_result");
|
|
1130
|
+
|
|
1131
|
+
const skeletonReal = (): "truncated" | "absent" | "incomplete" => {
|
|
1132
|
+
// Keep the tool call with the arguments the host gave it and replace
|
|
1133
|
+
// only the result content with the dropped marker. Nothing is written
|
|
1134
|
+
// into the argument position unless an earlier render this pass did,
|
|
1135
|
+
// in which case the real input goes back.
|
|
1136
|
+
if (!complete()) return "incomplete";
|
|
1137
|
+
const sentinel = `[dropped \u00a7${tagId}\u00a7]`;
|
|
1138
|
+
let any = false;
|
|
1139
|
+
for (const occ of occurrences) {
|
|
1140
|
+
if (occ.kind === "tool_use") {
|
|
1141
|
+
if (occ.originalInput && occ.part.setToolInput?.(occ.originalInput)) any = true;
|
|
1142
|
+
} else if (setToolContentOrText(occ.part, sentinel)) {
|
|
1143
|
+
any = true;
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
return any ? "truncated" : "absent";
|
|
1147
|
+
};
|
|
1148
|
+
|
|
1149
|
+
// Adapters without structural removal (or arcs that must keep their pair
|
|
1150
|
+
// beside native reasoning) cannot remove the call; drop() would keep it.
|
|
1151
|
+
const cannotRemove = (): boolean => {
|
|
1152
|
+
if (requiresToolArcSkeleton) return true;
|
|
1153
|
+
const authorization = occurrences.map((occ) => occ.part.canRemove?.());
|
|
1154
|
+
return !occurrences.every(
|
|
1155
|
+
(occ, index) => occ.part.remove && authorization[index] !== false,
|
|
1156
|
+
);
|
|
1157
|
+
};
|
|
1158
|
+
|
|
1159
|
+
return {
|
|
1160
|
+
measureReclaim(skeleton) {
|
|
1161
|
+
let beforeTools = 0;
|
|
1162
|
+
let afterTools = 0;
|
|
1163
|
+
const authorization = occurrences.map((occ) => occ.part.canRemove?.());
|
|
1164
|
+
const removable =
|
|
1165
|
+
!requiresToolArcSkeleton &&
|
|
1166
|
+
occurrences.every(
|
|
1167
|
+
(occ, index) =>
|
|
1168
|
+
occ.part.remove &&
|
|
1169
|
+
authorization[index] !== false &&
|
|
1170
|
+
authorization[index] !== "defer",
|
|
1171
|
+
);
|
|
1172
|
+
for (const occ of occurrences) {
|
|
1173
|
+
const before =
|
|
1174
|
+
occ.kind === "tool_use"
|
|
1175
|
+
? JSON.stringify(occ.part.getToolInput?.() ?? {})
|
|
1176
|
+
: (occ.part.getText() ?? "");
|
|
1177
|
+
beforeTools += estimateTokens(before);
|
|
1178
|
+
if (skeleton || !removable) {
|
|
1179
|
+
// A kept call keeps its real arguments; only the result shrinks.
|
|
1180
|
+
const after = occ.kind === "tool_use" ? before : `[dropped §${tagId}§]`;
|
|
1181
|
+
afterTools += estimateTokens(after);
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
return {
|
|
1185
|
+
beforeTools,
|
|
1186
|
+
afterTools: !skeleton && authorization.includes("defer") ? beforeTools : afterTools,
|
|
1187
|
+
beforeProse: 0,
|
|
1188
|
+
afterProse: 0,
|
|
1189
|
+
};
|
|
1190
|
+
},
|
|
1191
|
+
setContent(content: string): boolean {
|
|
1192
|
+
// Walk all occurrences; mutate every one. Return true if at
|
|
1193
|
+
// least one occurrence's content actually changed (used to
|
|
1194
|
+
// gate sentinel-replay re-writes).
|
|
1195
|
+
let changed = false;
|
|
1196
|
+
for (const occ of occurrences) {
|
|
1197
|
+
// Try setToolOutput first (works on tool_result-shaped parts);
|
|
1198
|
+
// fall back to setText so tool_use parts also get sentinelized.
|
|
1199
|
+
if (setToolContentOrText(occ.part, content)) {
|
|
1200
|
+
changed = true;
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
return changed;
|
|
1204
|
+
},
|
|
1205
|
+
getContent(): string | null {
|
|
1206
|
+
// Prefer the result occurrence's content (the bulky payload).
|
|
1207
|
+
for (const occ of occurrences) {
|
|
1208
|
+
if (occ.kind === "tool_result") {
|
|
1209
|
+
return occ.part.getText() ?? null;
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
return occurrences[0]?.part.getText() ?? null;
|
|
1213
|
+
},
|
|
1214
|
+
drop(): "removed" | "truncated" | "absent" | "incomplete" {
|
|
1215
|
+
if (!complete()) return "incomplete";
|
|
1216
|
+
if (!requiresToolArcSkeleton) {
|
|
1217
|
+
const authorization = occurrences.map((occ) => occ.part.canRemove?.());
|
|
1218
|
+
// A failed durable marker is not permission to substitute a new
|
|
1219
|
+
// skeleton. Keep both halves unchanged and leave the drop queued.
|
|
1220
|
+
if (authorization.includes("defer")) return "incomplete";
|
|
1221
|
+
if (
|
|
1222
|
+
occurrences.every(
|
|
1223
|
+
(occ, index) => occ.part.remove && authorization[index] !== false,
|
|
1224
|
+
)
|
|
1225
|
+
) {
|
|
1226
|
+
// If removing this call's result would leave the provider
|
|
1227
|
+
// request ending on an assistant turn, keep the call with its
|
|
1228
|
+
// REAL arguments plus the placeholder result instead.
|
|
1229
|
+
// "truncated" tells callers to persist that mode
|
|
1230
|
+
// (`skeleton_real`), so later passes serve the same bytes.
|
|
1231
|
+
// (The sentinel fallback below keeps call and result in place,
|
|
1232
|
+
// so it needs no exception.)
|
|
1233
|
+
if (conversationEnd?.wouldStrand(occurrences)) return skeletonReal();
|
|
1234
|
+
let removed = false;
|
|
1235
|
+
for (const occ of occurrences) removed = occ.part.remove?.() || removed;
|
|
1236
|
+
if (removed) conversationEnd?.noteRemoved(occurrences);
|
|
1237
|
+
return removed ? "removed" : "absent";
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
// Adapters without structural removal retain paired sentinels. This
|
|
1241
|
+
// writes a marker into the call's arguments, so only replays of
|
|
1242
|
+
// existing `full` tags reach it: new drops check cannotRemove() and
|
|
1243
|
+
// use skeletonReal(), and a HARD fold converts the existing ones.
|
|
1244
|
+
const sentinel = `[dropped \u00a7${tagId}\u00a7]`;
|
|
1245
|
+
let any = false;
|
|
1246
|
+
for (const occ of occurrences) {
|
|
1247
|
+
if (occ.part.replaceWithSentinel(sentinel)) any = true;
|
|
1248
|
+
}
|
|
1249
|
+
return any ? "removed" : "absent";
|
|
1250
|
+
},
|
|
1251
|
+
truncate,
|
|
1252
|
+
skeletonReal,
|
|
1253
|
+
cannotRemove,
|
|
1254
|
+
inputStringBytes(): number | null {
|
|
1255
|
+
for (const occ of occurrences) {
|
|
1256
|
+
if (occ.kind !== "tool_use") continue;
|
|
1257
|
+
return toolInputStringBytes(occ.originalInput ?? occ.part.getToolInput?.() ?? null);
|
|
1258
|
+
}
|
|
1259
|
+
return null;
|
|
1260
|
+
},
|
|
1261
|
+
wouldStrandConversationEnd(): boolean {
|
|
1262
|
+
return conversationEnd?.wouldStrand(occurrences) ?? false;
|
|
1263
|
+
},
|
|
1264
|
+
editMarker(): "truncated" | "absent" {
|
|
1265
|
+
// Edit-marker: preserve the tool_use input's filePath + a region
|
|
1266
|
+
// hint of the diff, sentinelize the result half. Separate from
|
|
1267
|
+
// truncate() so the existing skeleton bytes are never touched.
|
|
1268
|
+
// Deterministic + idempotent (re-derived from source each pass; the
|
|
1269
|
+
// region-hint clamp self-guards via ...[truncated]).
|
|
1270
|
+
const sentinel = `[dropped \u00a7${tagId}\u00a7]`;
|
|
1271
|
+
let any = false;
|
|
1272
|
+
for (const occ of occurrences) {
|
|
1273
|
+
if (occ.kind === "tool_use") {
|
|
1274
|
+
const input = occ.part.getToolInput?.();
|
|
1275
|
+
if (input) {
|
|
1276
|
+
const next = { ...input };
|
|
1277
|
+
applyEditMarkerToInput(next);
|
|
1278
|
+
if (occ.part.setToolInput?.(next)) any = true;
|
|
1279
|
+
}
|
|
1280
|
+
} else if (setToolContentOrText(occ.part, sentinel)) {
|
|
1281
|
+
any = true;
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
return any ? "truncated" : "absent";
|
|
1285
|
+
},
|
|
1286
|
+
// Open invocations still belong to the current turn; only complete arcs reclaim.
|
|
1287
|
+
canDrop: () => complete() && !occurrences.some((occ) => occ.part.hasUserAnswer?.()),
|
|
1288
|
+
requiresToolArcSkeleton,
|
|
1289
|
+
// Non-mutating read of the invocation input (the tool_use occurrence
|
|
1290
|
+
// carries the arguments). Used by smart-drops supersession selection.
|
|
1291
|
+
readInput(): Record<string, unknown> | null {
|
|
1292
|
+
for (const occ of occurrences) {
|
|
1293
|
+
const input = occ.part.getToolInput?.();
|
|
1294
|
+
if (input) return input;
|
|
1295
|
+
}
|
|
1296
|
+
return null;
|
|
1297
|
+
},
|
|
1298
|
+
message: {
|
|
1299
|
+
info: { id: messageId, role },
|
|
1300
|
+
parts: [],
|
|
1301
|
+
},
|
|
1302
|
+
};
|
|
1303
|
+
}
|
|
1304
|
+
|
|
1305
|
+
/**
|
|
1306
|
+
* TagTarget for a tag-eligible text part. The shared
|
|
1307
|
+
* `applyPendingOperations` flow calls `setContent` to swap in a
|
|
1308
|
+
* sentinel like `[dropped §N§]` when a queued drop fires; `getContent`
|
|
1309
|
+
* returns the current visible text so the truncated-preview path can
|
|
1310
|
+
* compute its before/after.
|
|
1311
|
+
*
|
|
1312
|
+
* The `message.info.role` is used by `buildReplacementContent` in
|
|
1313
|
+
* `apply-operations.ts` to differentiate user-message drops (which
|
|
1314
|
+
* preserve a truncated preview) from assistant drops (full sentinel).
|
|
1315
|
+
*/
|
|
1316
|
+
function buildTextTarget(
|
|
1317
|
+
part: TranscriptPart,
|
|
1318
|
+
message: { info: { id?: string; role: string } },
|
|
1319
|
+
textPrefix: string,
|
|
1320
|
+
): TagTarget {
|
|
1321
|
+
return {
|
|
1322
|
+
textPrefix,
|
|
1323
|
+
setContent(content: string): boolean {
|
|
1324
|
+
return part.setText(content);
|
|
1325
|
+
},
|
|
1326
|
+
getContent(): string | null {
|
|
1327
|
+
return part.getText() ?? null;
|
|
1328
|
+
},
|
|
1329
|
+
// `message` is typed as MessageLike, which has parts: unknown[].
|
|
1330
|
+
// We don't carry parts here (the apply-operations flow only
|
|
1331
|
+
// reads `info.role` on this field), so a minimal stub is
|
|
1332
|
+
// sufficient.
|
|
1333
|
+
message: {
|
|
1334
|
+
info: { id: message.info.id, role: message.info.role },
|
|
1335
|
+
parts: [],
|
|
1336
|
+
},
|
|
1337
|
+
};
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1340
|
+
/**
|
|
1341
|
+
* TagTarget for a tag-eligible tool part. Tool parts get full-drop or
|
|
1342
|
+
* skeleton-drop treatment from `applyFlushedStatuses` based on the stored
|
|
1343
|
+
* `drop_mode` column. Both render the SAME canonical `[dropped §N§]`
|
|
1344
|
+
* placeholder — full-drop replaces the whole pair, while skeleton-drop keeps
|
|
1345
|
+
* the tool_use call with only a dropped-input marker. Marker bytes are
|
|
1346
|
+
* byte-identical across passes and across harnesses.
|
|
1347
|
+
*/
|
|
1348
|
+
function buildToolTarget(
|
|
1349
|
+
part: TranscriptPart,
|
|
1350
|
+
message: { info: { id?: string; role: string } },
|
|
1351
|
+
tagId: number,
|
|
1352
|
+
): TagTarget {
|
|
1353
|
+
return {
|
|
1354
|
+
setContent(content: string): boolean {
|
|
1355
|
+
return setToolContentOrText(part, content);
|
|
1356
|
+
},
|
|
1357
|
+
getContent(): string | null {
|
|
1358
|
+
return part.getText() ?? null;
|
|
1359
|
+
},
|
|
1360
|
+
drop(): "removed" | "absent" {
|
|
1361
|
+
// Replace the tool part's visible content with a "[dropped]"
|
|
1362
|
+
// shell. We can't physically remove the part because Pi
|
|
1363
|
+
// requires tool_use ↔ tool_result pairing for the LLM call
|
|
1364
|
+
// to validate; instead we shrink the content to a sentinel.
|
|
1365
|
+
// For Pi the current Transcript contract treats both
|
|
1366
|
+
// invocation and result parts symmetrically — both expose
|
|
1367
|
+
// setText / setToolOutput.
|
|
1368
|
+
const replaced = part.replaceWithSentinel(`[dropped \u00a7${tagId}\u00a7]`);
|
|
1369
|
+
return replaced ? "removed" : "absent";
|
|
1370
|
+
},
|
|
1371
|
+
truncate(): "truncated" | "absent" {
|
|
1372
|
+
// Legacy render, replayed only for unconverted `truncated` tags.
|
|
1373
|
+
const changed = part.setToolInput
|
|
1374
|
+
? part.setToolInput(droppedInputMarker(tagId))
|
|
1375
|
+
: setToolContentOrText(part, `[dropped \u00a7${tagId}\u00a7]`);
|
|
1376
|
+
return changed ? "truncated" : "absent";
|
|
1377
|
+
},
|
|
1378
|
+
skeletonReal(): "truncated" | "absent" {
|
|
1379
|
+
// An invocation part keeps its real arguments untouched; a result
|
|
1380
|
+
// part's content becomes the dropped marker.
|
|
1381
|
+
if (part.setToolInput) return "truncated";
|
|
1382
|
+
return setToolContentOrText(part, `[dropped \u00a7${tagId}\u00a7]`)
|
|
1383
|
+
? "truncated"
|
|
1384
|
+
: "absent";
|
|
1385
|
+
},
|
|
1386
|
+
// drop() replaces an invocation part's arguments with a marker, so a
|
|
1387
|
+
// new drop of one keeps its real arguments instead.
|
|
1388
|
+
cannotRemove: () => part.setToolInput !== undefined,
|
|
1389
|
+
// Without a paired tool call, an answer marker can forbid automatic dropping,
|
|
1390
|
+
// but must not make ordinary results newly eligible for automatic reclaim.
|
|
1391
|
+
...(part.hasUserAnswer?.() ? { canDrop: () => false } : {}),
|
|
1392
|
+
inputStringBytes(): number | null {
|
|
1393
|
+
return part.setToolInput ? toolInputStringBytes(part.getToolInput?.() ?? null) : 0;
|
|
1394
|
+
},
|
|
1395
|
+
message: {
|
|
1396
|
+
info: { id: message.info.id, role: message.info.role },
|
|
1397
|
+
parts: [],
|
|
1398
|
+
},
|
|
1399
|
+
};
|
|
1400
|
+
}
|