apex-code 0.0.1-alpha.1 → 0.0.1-alpha.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +482 -0
- package/README.md +75 -680
- package/dist/cli/args.d.ts +21 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +119 -15
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/auth-command.d.ts.map +1 -1
- package/dist/cli/auth-command.js +3 -3
- package/dist/cli/auth-command.js.map +1 -1
- package/dist/cli/concurrent-session.d.ts +3 -0
- package/dist/cli/concurrent-session.d.ts.map +1 -0
- package/dist/cli/concurrent-session.js +13 -0
- package/dist/cli/concurrent-session.js.map +1 -0
- package/dist/cli/cost-command.d.ts +19 -0
- package/dist/cli/cost-command.d.ts.map +1 -0
- package/dist/cli/cost-command.js +107 -0
- package/dist/cli/cost-command.js.map +1 -0
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js +2 -1
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/cli/startup-ui.d.ts +1 -1
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +1 -2
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +99 -16
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +5 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +58 -24
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +2 -0
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +28 -0
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +140 -4
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +147 -9
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +440 -123
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +4 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +17 -14
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +18 -10
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/checkpoints/git-checkpoints.d.ts +33 -0
- package/dist/core/checkpoints/git-checkpoints.d.ts.map +1 -0
- package/dist/core/checkpoints/git-checkpoints.js +230 -0
- package/dist/core/checkpoints/git-checkpoints.js.map +1 -0
- package/dist/core/checkpoints/session-checkpoints.d.ts +23 -0
- package/dist/core/checkpoints/session-checkpoints.d.ts.map +1 -0
- package/dist/core/checkpoints/session-checkpoints.js +29 -0
- package/dist/core/checkpoints/session-checkpoints.js.map +1 -0
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +3 -0
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +4 -3
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +41 -32
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/context/deferred-schemas.d.ts +92 -0
- package/dist/core/context/deferred-schemas.d.ts.map +1 -0
- package/dist/core/context/deferred-schemas.js +74 -0
- package/dist/core/context/deferred-schemas.js.map +1 -0
- package/dist/core/context/eviction.d.ts +47 -0
- package/dist/core/context/eviction.d.ts.map +1 -0
- package/dist/core/context/eviction.js +83 -0
- package/dist/core/context/eviction.js.map +1 -0
- package/dist/core/context/pipeline.d.ts +90 -0
- package/dist/core/context/pipeline.d.ts.map +1 -0
- package/dist/core/context/pipeline.js +109 -0
- package/dist/core/context/pipeline.js.map +1 -0
- package/dist/core/credential-failover.d.ts +30 -0
- package/dist/core/credential-failover.d.ts.map +1 -0
- package/dist/core/credential-failover.js +46 -0
- package/dist/core/credential-failover.js.map +1 -0
- package/dist/core/credential-pool.d.ts +60 -0
- package/dist/core/credential-pool.d.ts.map +1 -0
- package/dist/core/credential-pool.js +84 -0
- package/dist/core/credential-pool.js.map +1 -0
- package/dist/core/defaults.d.ts +1 -0
- package/dist/core/defaults.d.ts.map +1 -1
- package/dist/core/defaults.js +9 -0
- package/dist/core/defaults.js.map +1 -1
- package/dist/core/delegation/agents.d.ts +15 -0
- package/dist/core/delegation/agents.d.ts.map +1 -0
- package/dist/core/delegation/agents.js +55 -0
- package/dist/core/delegation/agents.js.map +1 -0
- package/dist/core/delegation/ceiling.d.ts +29 -0
- package/dist/core/delegation/ceiling.d.ts.map +1 -0
- package/dist/core/delegation/ceiling.js +34 -0
- package/dist/core/delegation/ceiling.js.map +1 -0
- package/dist/core/delegation/runtime.d.ts +94 -0
- package/dist/core/delegation/runtime.d.ts.map +1 -0
- package/dist/core/delegation/runtime.js +117 -0
- package/dist/core/delegation/runtime.js.map +1 -0
- package/dist/core/durable-state/daemon.d.ts +37 -0
- package/dist/core/durable-state/daemon.d.ts.map +1 -0
- package/dist/core/durable-state/daemon.js +62 -0
- package/dist/core/durable-state/daemon.js.map +1 -0
- package/dist/core/durable-state/provenance.d.ts +7 -0
- package/dist/core/durable-state/provenance.d.ts.map +1 -0
- package/dist/core/durable-state/provenance.js +24 -0
- package/dist/core/durable-state/provenance.js.map +1 -0
- package/dist/core/durable-state/sqlite.d.ts +84 -0
- package/dist/core/durable-state/sqlite.d.ts.map +1 -0
- package/dist/core/durable-state/sqlite.js +355 -0
- package/dist/core/durable-state/sqlite.js.map +1 -0
- package/dist/core/environment.d.ts +12 -0
- package/dist/core/environment.d.ts.map +1 -0
- package/dist/core/environment.js +69 -0
- package/dist/core/environment.js.map +1 -0
- package/dist/core/evidence-policy.d.ts +17 -0
- package/dist/core/evidence-policy.d.ts.map +1 -0
- package/dist/core/evidence-policy.js +25 -0
- package/dist/core/evidence-policy.js.map +1 -0
- package/dist/core/evidence.d.ts +16 -0
- package/dist/core/evidence.d.ts.map +1 -0
- package/dist/core/evidence.js +51 -0
- package/dist/core/evidence.js.map +1 -0
- package/dist/core/exec.d.ts.map +1 -1
- package/dist/core/exec.js +5 -2
- package/dist/core/exec.js.map +1 -1
- package/dist/core/experimental.d.ts +4 -0
- package/dist/core/experimental.d.ts.map +1 -1
- package/dist/core/experimental.js +6 -1
- package/dist/core/experimental.js.map +1 -1
- package/dist/core/extensions/index.d.ts +2 -2
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +122 -49
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/types.d.ts +44 -9
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js +3 -0
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +1 -1
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +1 -1
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts +1 -2
- package/dist/core/http-dispatcher.d.ts.map +1 -1
- package/dist/core/http-dispatcher.js +2 -17
- package/dist/core/http-dispatcher.js.map +1 -1
- package/dist/core/http-idle-timeout.d.ts +12 -0
- package/dist/core/http-idle-timeout.d.ts.map +1 -0
- package/dist/core/http-idle-timeout.js +27 -0
- package/dist/core/http-idle-timeout.js.map +1 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/keybindings.d.ts +38 -13
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +26 -5
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/lsp/client.d.ts +78 -0
- package/dist/core/lsp/client.d.ts.map +1 -0
- package/dist/core/lsp/client.js +494 -0
- package/dist/core/lsp/client.js.map +1 -0
- package/dist/core/lsp/diagnostics.d.ts +47 -0
- package/dist/core/lsp/diagnostics.d.ts.map +1 -0
- package/dist/core/lsp/diagnostics.js +224 -0
- package/dist/core/lsp/diagnostics.js.map +1 -0
- package/dist/core/lsp/pool.d.ts +48 -0
- package/dist/core/lsp/pool.d.ts.map +1 -0
- package/dist/core/lsp/pool.js +150 -0
- package/dist/core/lsp/pool.js.map +1 -0
- package/dist/core/lsp/registry.d.ts +49 -0
- package/dist/core/lsp/registry.d.ts.map +1 -0
- package/dist/core/lsp/registry.js +215 -0
- package/dist/core/lsp/registry.js.map +1 -0
- package/dist/core/lsp/status.d.ts +23 -0
- package/dist/core/lsp/status.d.ts.map +1 -0
- package/dist/core/lsp/status.js +35 -0
- package/dist/core/lsp/status.js.map +1 -0
- package/dist/core/lsp/sync.d.ts +13 -0
- package/dist/core/lsp/sync.d.ts.map +1 -0
- package/dist/core/lsp/sync.js +71 -0
- package/dist/core/lsp/sync.js.map +1 -0
- package/dist/core/mcp/config.d.ts +16 -0
- package/dist/core/mcp/config.d.ts.map +1 -0
- package/dist/core/mcp/config.js +152 -0
- package/dist/core/mcp/config.js.map +1 -0
- package/dist/core/mcp/connector.d.ts +10 -0
- package/dist/core/mcp/connector.d.ts.map +1 -0
- package/dist/core/mcp/connector.js +70 -0
- package/dist/core/mcp/connector.js.map +1 -0
- package/dist/core/mcp/contract.d.ts +19 -0
- package/dist/core/mcp/contract.d.ts.map +1 -0
- package/dist/core/mcp/contract.js +89 -0
- package/dist/core/mcp/contract.js.map +1 -0
- package/dist/core/mcp/mcp-tool.d.ts +32 -0
- package/dist/core/mcp/mcp-tool.d.ts.map +1 -0
- package/dist/core/mcp/mcp-tool.js +165 -0
- package/dist/core/mcp/mcp-tool.js.map +1 -0
- package/dist/core/mcp/metadata-cache.d.ts +29 -0
- package/dist/core/mcp/metadata-cache.d.ts.map +1 -0
- package/dist/core/mcp/metadata-cache.js +99 -0
- package/dist/core/mcp/metadata-cache.js.map +1 -0
- package/dist/core/mcp/runtime.d.ts +18 -0
- package/dist/core/mcp/runtime.d.ts.map +1 -0
- package/dist/core/mcp/runtime.js +35 -0
- package/dist/core/mcp/runtime.js.map +1 -0
- package/dist/core/mcp/schema.d.ts +22 -0
- package/dist/core/mcp/schema.d.ts.map +1 -0
- package/dist/core/mcp/schema.js +20 -0
- package/dist/core/mcp/schema.js.map +1 -0
- package/dist/core/mcp/server-manager.d.ts +43 -0
- package/dist/core/mcp/server-manager.d.ts.map +1 -0
- package/dist/core/mcp/server-manager.js +142 -0
- package/dist/core/mcp/server-manager.js.map +1 -0
- package/dist/core/mcp/types.d.ts +98 -0
- package/dist/core/mcp/types.d.ts.map +1 -0
- package/dist/core/mcp/types.js +8 -0
- package/dist/core/mcp/types.js.map +1 -0
- package/dist/core/model-config.d.ts +18 -0
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +25 -6
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-resolver.d.ts +21 -0
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +73 -8
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/model-runtime.d.ts +73 -0
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +225 -8
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/models-store.d.ts.map +1 -1
- package/dist/core/models-store.js +2 -1
- package/dist/core/models-store.js.map +1 -1
- package/dist/core/observability/aggregate.d.ts +21 -0
- package/dist/core/observability/aggregate.d.ts.map +1 -0
- package/dist/core/observability/aggregate.js +36 -0
- package/dist/core/observability/aggregate.js.map +1 -0
- package/dist/core/observability/otlp.d.ts +66 -0
- package/dist/core/observability/otlp.d.ts.map +1 -0
- package/dist/core/observability/otlp.js +95 -0
- package/dist/core/observability/otlp.js.map +1 -0
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +40 -16
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/permissions/gate.d.ts +42 -0
- package/dist/core/permissions/gate.d.ts.map +1 -0
- package/dist/core/permissions/gate.js +72 -0
- package/dist/core/permissions/gate.js.map +1 -0
- package/dist/core/permissions/modes.d.ts +18 -0
- package/dist/core/permissions/modes.d.ts.map +1 -0
- package/dist/core/permissions/modes.js +57 -0
- package/dist/core/permissions/modes.js.map +1 -0
- package/dist/core/permissions/responder.d.ts +30 -0
- package/dist/core/permissions/responder.d.ts.map +1 -0
- package/dist/core/permissions/responder.js +32 -0
- package/dist/core/permissions/responder.js.map +1 -0
- package/dist/core/permissions/rules.d.ts +34 -0
- package/dist/core/permissions/rules.d.ts.map +1 -0
- package/dist/core/permissions/rules.js +74 -0
- package/dist/core/permissions/rules.js.map +1 -0
- package/dist/core/permissions/startup.d.ts +45 -0
- package/dist/core/permissions/startup.d.ts.map +1 -0
- package/dist/core/permissions/startup.js +63 -0
- package/dist/core/permissions/startup.js.map +1 -0
- package/dist/core/permissions/store.d.ts +114 -0
- package/dist/core/permissions/store.d.ts.map +1 -0
- package/dist/core/permissions/store.js +229 -0
- package/dist/core/permissions/store.js.map +1 -0
- package/dist/core/pi-manifest.d.ts.map +1 -1
- package/dist/core/pi-manifest.js +2 -1
- package/dist/core/pi-manifest.js.map +1 -1
- package/dist/core/project-trust.d.ts.map +1 -1
- package/dist/core/project-trust.js +1 -1
- package/dist/core/project-trust.js.map +1 -1
- package/dist/core/provider-attribution.d.ts.map +1 -1
- package/dist/core/provider-attribution.js +6 -7
- package/dist/core/provider-attribution.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts +2 -2
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +22 -17
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +3 -2
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sandbox/bwrap-arguments.d.ts +52 -0
- package/dist/core/sandbox/bwrap-arguments.d.ts.map +1 -0
- package/dist/core/sandbox/bwrap-arguments.js +86 -0
- package/dist/core/sandbox/bwrap-arguments.js.map +1 -0
- package/dist/core/sandbox/child-entry.d.ts +2 -0
- package/dist/core/sandbox/child-entry.d.ts.map +1 -0
- package/dist/core/sandbox/child-entry.js +22 -0
- package/dist/core/sandbox/child-entry.js.map +1 -0
- package/dist/core/sandbox/cli-launch.d.ts +88 -0
- package/dist/core/sandbox/cli-launch.d.ts.map +1 -0
- package/dist/core/sandbox/cli-launch.js +272 -0
- package/dist/core/sandbox/cli-launch.js.map +1 -0
- package/dist/core/sandbox/cli-supervisor.d.ts +30 -0
- package/dist/core/sandbox/cli-supervisor.d.ts.map +1 -0
- package/dist/core/sandbox/cli-supervisor.js +123 -0
- package/dist/core/sandbox/cli-supervisor.js.map +1 -0
- package/dist/core/sandbox/default-hosts.d.ts +28 -0
- package/dist/core/sandbox/default-hosts.d.ts.map +1 -0
- package/dist/core/sandbox/default-hosts.js +69 -0
- package/dist/core/sandbox/default-hosts.js.map +1 -0
- package/dist/core/sandbox/full-access.d.ts +28 -0
- package/dist/core/sandbox/full-access.d.ts.map +1 -0
- package/dist/core/sandbox/full-access.js +63 -0
- package/dist/core/sandbox/full-access.js.map +1 -0
- package/dist/core/sandbox/git-identity.d.ts +57 -0
- package/dist/core/sandbox/git-identity.d.ts.map +1 -0
- package/dist/core/sandbox/git-identity.js +78 -0
- package/dist/core/sandbox/git-identity.js.map +1 -0
- package/dist/core/sandbox/host-approval.d.ts +42 -0
- package/dist/core/sandbox/host-approval.d.ts.map +1 -0
- package/dist/core/sandbox/host-approval.js +99 -0
- package/dist/core/sandbox/host-approval.js.map +1 -0
- package/dist/core/sandbox/linux-backend.d.ts +46 -0
- package/dist/core/sandbox/linux-backend.d.ts.map +1 -0
- package/dist/core/sandbox/linux-backend.js +304 -0
- package/dist/core/sandbox/linux-backend.js.map +1 -0
- package/dist/core/sandbox/macos-backend.d.ts +28 -0
- package/dist/core/sandbox/macos-backend.d.ts.map +1 -0
- package/dist/core/sandbox/macos-backend.js +313 -0
- package/dist/core/sandbox/macos-backend.js.map +1 -0
- package/dist/core/sandbox/network-proxy.d.ts +38 -0
- package/dist/core/sandbox/network-proxy.d.ts.map +1 -0
- package/dist/core/sandbox/network-proxy.js +153 -0
- package/dist/core/sandbox/network-proxy.js.map +1 -0
- package/dist/core/sandbox/network-refusal.d.ts +24 -0
- package/dist/core/sandbox/network-refusal.d.ts.map +1 -0
- package/dist/core/sandbox/network-refusal.js +72 -0
- package/dist/core/sandbox/network-refusal.js.map +1 -0
- package/dist/core/sandbox/policy.d.ts +40 -0
- package/dist/core/sandbox/policy.d.ts.map +1 -0
- package/dist/core/sandbox/policy.js +55 -0
- package/dist/core/sandbox/policy.js.map +1 -0
- package/dist/core/sandbox/profiles.d.ts +25 -0
- package/dist/core/sandbox/profiles.d.ts.map +1 -0
- package/dist/core/sandbox/profiles.js +23 -0
- package/dist/core/sandbox/profiles.js.map +1 -0
- package/dist/core/sandbox/rpc/command-client.d.ts +28 -0
- package/dist/core/sandbox/rpc/command-client.d.ts.map +1 -0
- package/dist/core/sandbox/rpc/command-client.js +86 -0
- package/dist/core/sandbox/rpc/command-client.js.map +1 -0
- package/dist/core/sandbox/rpc/command-proxy.d.ts +48 -0
- package/dist/core/sandbox/rpc/command-proxy.d.ts.map +1 -0
- package/dist/core/sandbox/rpc/command-proxy.js +120 -0
- package/dist/core/sandbox/rpc/command-proxy.js.map +1 -0
- package/dist/core/sandbox/rpc/credential-client.d.ts +20 -0
- package/dist/core/sandbox/rpc/credential-client.d.ts.map +1 -0
- package/dist/core/sandbox/rpc/credential-client.js +170 -0
- package/dist/core/sandbox/rpc/credential-client.js.map +1 -0
- package/dist/core/sandbox/rpc/credential-proxy.d.ts +44 -0
- package/dist/core/sandbox/rpc/credential-proxy.d.ts.map +1 -0
- package/dist/core/sandbox/rpc/credential-proxy.js +287 -0
- package/dist/core/sandbox/rpc/credential-proxy.js.map +1 -0
- package/dist/core/sandbox/rpc/framing.d.ts +35 -0
- package/dist/core/sandbox/rpc/framing.d.ts.map +1 -0
- package/dist/core/sandbox/rpc/framing.js +114 -0
- package/dist/core/sandbox/rpc/framing.js.map +1 -0
- package/dist/core/sandbox/rpc/git-credential-helper.d.ts +40 -0
- package/dist/core/sandbox/rpc/git-credential-helper.d.ts.map +1 -0
- package/dist/core/sandbox/rpc/git-credential-helper.js +152 -0
- package/dist/core/sandbox/rpc/git-credential-helper.js.map +1 -0
- package/dist/core/sandbox/rpc/git-credential-proxy.d.ts +48 -0
- package/dist/core/sandbox/rpc/git-credential-proxy.d.ts.map +1 -0
- package/dist/core/sandbox/rpc/git-credential-proxy.js +142 -0
- package/dist/core/sandbox/rpc/git-credential-proxy.js.map +1 -0
- package/dist/core/sandbox/supervisor-temp.d.ts +18 -0
- package/dist/core/sandbox/supervisor-temp.d.ts.map +1 -0
- package/dist/core/sandbox/supervisor-temp.js +21 -0
- package/dist/core/sandbox/supervisor-temp.js.map +1 -0
- package/dist/core/sandbox/supervisor.d.ts +51 -0
- package/dist/core/sandbox/supervisor.d.ts.map +1 -0
- package/dist/core/sandbox/supervisor.js +18 -0
- package/dist/core/sandbox/supervisor.js.map +1 -0
- package/dist/core/sandbox/terminal-handoff.d.ts +45 -0
- package/dist/core/sandbox/terminal-handoff.d.ts.map +1 -0
- package/dist/core/sandbox/terminal-handoff.js +176 -0
- package/dist/core/sandbox/terminal-handoff.js.map +1 -0
- package/dist/core/sandbox/terminal-size.d.ts +40 -0
- package/dist/core/sandbox/terminal-size.d.ts.map +1 -0
- package/dist/core/sandbox/terminal-size.js +105 -0
- package/dist/core/sandbox/terminal-size.js.map +1 -0
- package/dist/core/sandbox/violations.d.ts +23 -0
- package/dist/core/sandbox/violations.d.ts.map +1 -0
- package/dist/core/sandbox/violations.js +30 -0
- package/dist/core/sandbox/violations.js.map +1 -0
- package/dist/core/sdk.d.ts +32 -41
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +174 -6
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-export.d.ts +4 -0
- package/dist/core/session-export.d.ts.map +1 -0
- package/dist/core/session-export.js +32 -0
- package/dist/core/session-export.js.map +1 -0
- package/dist/core/session-lease.d.ts +31 -0
- package/dist/core/session-lease.d.ts.map +1 -0
- package/dist/core/session-lease.js +138 -0
- package/dist/core/session-lease.js.map +1 -0
- package/dist/core/session-manager.d.ts +58 -2
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +92 -7
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-share.d.ts +31 -0
- package/dist/core/session-share.d.ts.map +1 -0
- package/dist/core/session-share.js +45 -0
- package/dist/core/session-share.js.map +1 -0
- package/dist/core/settings-diagnostics.d.ts +9 -0
- package/dist/core/settings-diagnostics.d.ts.map +1 -0
- package/dist/core/settings-diagnostics.js +21 -0
- package/dist/core/settings-diagnostics.js.map +1 -0
- package/dist/core/settings-manager.d.ts +99 -9
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +141 -36
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts +19 -7
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +128 -52
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +6 -2
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/system-prompt.d.ts +2 -2
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +59 -68
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/timings.d.ts +1 -1
- package/dist/core/timings.d.ts.map +1 -1
- package/dist/core/timings.js +3 -2
- package/dist/core/timings.js.map +1 -1
- package/dist/core/tools/ask-user.d.ts +25 -0
- package/dist/core/tools/ask-user.d.ts.map +1 -0
- package/dist/core/tools/ask-user.js +49 -0
- package/dist/core/tools/ask-user.js.map +1 -0
- package/dist/core/tools/bash-command-segments.d.ts +22 -0
- package/dist/core/tools/bash-command-segments.d.ts.map +1 -0
- package/dist/core/tools/bash-command-segments.js +128 -0
- package/dist/core/tools/bash-command-segments.js.map +1 -0
- package/dist/core/tools/bash.d.ts +40 -4
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +183 -32
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/contract-snapshot.d.ts +58 -0
- package/dist/core/tools/contract-snapshot.d.ts.map +1 -0
- package/dist/core/tools/contract-snapshot.js +51 -0
- package/dist/core/tools/contract-snapshot.js.map +1 -0
- package/dist/core/tools/contract.d.ts +185 -0
- package/dist/core/tools/contract.d.ts.map +1 -0
- package/dist/core/tools/contract.js +50 -0
- package/dist/core/tools/contract.js.map +1 -0
- package/dist/core/tools/delegate.d.ts +38 -0
- package/dist/core/tools/delegate.d.ts.map +1 -0
- package/dist/core/tools/delegate.js +90 -0
- package/dist/core/tools/delegate.js.map +1 -0
- package/dist/core/tools/diagnostics.d.ts +39 -0
- package/dist/core/tools/diagnostics.d.ts.map +1 -0
- package/dist/core/tools/diagnostics.js +62 -0
- package/dist/core/tools/diagnostics.js.map +1 -0
- package/dist/core/tools/edit-diff.d.ts +0 -5
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +2 -5
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts +12 -2
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +61 -10
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/find.d.ts +2 -2
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +13 -1
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts +4 -2
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +47 -10
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts +60 -6
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +148 -2
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/ls.d.ts +4 -2
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +17 -1
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/lsp.d.ts +62 -0
- package/dist/core/tools/lsp.d.ts.map +1 -0
- package/dist/core/tools/lsp.js +216 -0
- package/dist/core/tools/lsp.js.map +1 -0
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +1 -1
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/core/tools/path-permission.d.ts +18 -0
- package/dist/core/tools/path-permission.d.ts.map +1 -0
- package/dist/core/tools/path-permission.js +28 -0
- package/dist/core/tools/path-permission.js.map +1 -0
- package/dist/core/tools/plan-present.d.ts +27 -0
- package/dist/core/tools/plan-present.d.ts.map +1 -0
- package/dist/core/tools/plan-present.js +55 -0
- package/dist/core/tools/plan-present.js.map +1 -0
- package/dist/core/tools/powershell.d.ts +16 -0
- package/dist/core/tools/powershell.d.ts.map +1 -0
- package/dist/core/tools/powershell.js +39 -0
- package/dist/core/tools/powershell.js.map +1 -0
- package/dist/core/tools/read.d.ts +2 -2
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +14 -0
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/skill-search.d.ts +32 -0
- package/dist/core/tools/skill-search.d.ts.map +1 -0
- package/dist/core/tools/skill-search.js +56 -0
- package/dist/core/tools/skill-search.js.map +1 -0
- package/dist/core/tools/test.d.ts +34 -0
- package/dist/core/tools/test.d.ts.map +1 -0
- package/dist/core/tools/test.js +75 -0
- package/dist/core/tools/test.js.map +1 -0
- package/dist/core/tools/todo-write.d.ts +31 -0
- package/dist/core/tools/todo-write.d.ts.map +1 -0
- package/dist/core/tools/todo-write.js +51 -0
- package/dist/core/tools/todo-write.js.map +1 -0
- package/dist/core/tools/tool-definition-wrapper.d.ts +13 -2
- package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
- package/dist/core/tools/tool-definition-wrapper.js +11 -1
- package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
- package/dist/core/tools/tool-schema.d.ts +22 -0
- package/dist/core/tools/tool-schema.d.ts.map +1 -0
- package/dist/core/tools/tool-schema.js +45 -0
- package/dist/core/tools/tool-schema.js.map +1 -0
- package/dist/core/tools/web-fetch.d.ts +26 -0
- package/dist/core/tools/web-fetch.d.ts.map +1 -0
- package/dist/core/tools/web-fetch.js +62 -0
- package/dist/core/tools/web-fetch.js.map +1 -0
- package/dist/core/tools/web-search-exa.d.ts +33 -0
- package/dist/core/tools/web-search-exa.d.ts.map +1 -0
- package/dist/core/tools/web-search-exa.js +128 -0
- package/dist/core/tools/web-search-exa.js.map +1 -0
- package/dist/core/tools/web-search.d.ts +26 -0
- package/dist/core/tools/web-search.d.ts.map +1 -0
- package/dist/core/tools/web-search.js +53 -0
- package/dist/core/tools/web-search.js.map +1 -0
- package/dist/core/tools/write.d.ts +16 -2
- package/dist/core/tools/write.d.ts.map +1 -1
- package/dist/core/tools/write.js +48 -2
- package/dist/core/tools/write.js.map +1 -1
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +2 -1
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/core/usage-performance-store.d.ts +56 -0
- package/dist/core/usage-performance-store.d.ts.map +1 -0
- package/dist/core/usage-performance-store.js +85 -0
- package/dist/core/usage-performance-store.js.map +1 -0
- package/dist/core/web-search-provider.d.ts +64 -0
- package/dist/core/web-search-provider.d.ts.map +1 -0
- package/dist/core/web-search-provider.js +149 -0
- package/dist/core/web-search-provider.js.map +1 -0
- package/dist/extensions/llama/index.d.ts.map +1 -1
- package/dist/extensions/llama/index.js +2 -0
- package/dist/extensions/llama/index.js.map +1 -1
- package/dist/extensions/llama/provider.d.ts.map +1 -1
- package/dist/extensions/llama/provider.js +6 -2
- package/dist/extensions/llama/provider.js.map +1 -1
- package/dist/index.d.ts +9 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -4
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +5 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +87 -22
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +6 -5
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/components/assistant-message.d.ts +29 -0
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/assistant-message.js +182 -23
- package/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts +7 -0
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +20 -0
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/config-selector.js +9 -6
- package/dist/modes/interactive/components/config-selector.js.map +1 -1
- package/dist/modes/interactive/components/custom-editor.d.ts +72 -1
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-editor.js +338 -1
- package/dist/modes/interactive/components/custom-editor.js.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.d.ts +7 -1
- package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/dist/modes/interactive/components/dynamic-border.js +11 -2
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/dist/modes/interactive/components/extension-selector.d.ts +4 -0
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/extension-selector.js +24 -6
- package/dist/modes/interactive/components/extension-selector.js.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.d.ts +1 -4
- package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
- package/dist/modes/interactive/components/first-time-setup.js +17 -41
- package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
- package/dist/modes/interactive/components/first-use-hints.d.ts +8 -0
- package/dist/modes/interactive/components/first-use-hints.d.ts.map +1 -0
- package/dist/modes/interactive/components/first-use-hints.js +22 -0
- package/dist/modes/interactive/components/first-use-hints.js.map +1 -0
- package/dist/modes/interactive/components/footer.d.ts +31 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +205 -24
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +2 -0
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +2 -0
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +31 -9
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +236 -96
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +25 -5
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +226 -58
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-submenu.d.ts +72 -0
- package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -0
- package/dist/modes/interactive/components/settings-submenu.js +165 -0
- package/dist/modes/interactive/components/settings-submenu.js.map +1 -0
- package/dist/modes/interactive/components/splash-header.d.ts +66 -0
- package/dist/modes/interactive/components/splash-header.d.ts.map +1 -0
- package/dist/modes/interactive/components/splash-header.js +180 -0
- package/dist/modes/interactive/components/splash-header.js.map +1 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts +15 -3
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +74 -17
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +28 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +144 -35
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/components/tool-panel.d.ts +30 -0
- package/dist/modes/interactive/components/tool-panel.d.ts.map +1 -0
- package/dist/modes/interactive/components/tool-panel.js +130 -0
- package/dist/modes/interactive/components/tool-panel.js.map +1 -0
- package/dist/modes/interactive/external-editor.d.ts.map +1 -1
- package/dist/modes/interactive/external-editor.js +60 -10
- package/dist/modes/interactive/external-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +90 -5
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +729 -206
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/model-catalog-refresh.d.ts +7 -0
- package/dist/modes/interactive/model-catalog-refresh.d.ts.map +1 -0
- package/dist/modes/interactive/model-catalog-refresh.js +34 -0
- package/dist/modes/interactive/model-catalog-refresh.js.map +1 -0
- package/dist/modes/interactive/theme/apex.json +93 -0
- package/dist/modes/interactive/theme/dark.json +2 -0
- package/dist/modes/interactive/theme/light.json +3 -1
- package/dist/modes/interactive/theme/theme-controller.d.ts +10 -2
- package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme-controller.js +25 -11
- package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
- package/dist/modes/interactive/theme/theme-schema.json +11 -3
- package/dist/modes/interactive/theme/theme.d.ts +14 -3
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +65 -10
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/json-event.d.ts +18 -12
- package/dist/modes/json-event.d.ts.map +1 -1
- package/dist/modes/json-event.js +22 -5
- package/dist/modes/json-event.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +2 -1
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/package-manager-cli.d.ts +1 -0
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +210 -19
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/rpc-entry.d.ts.map +1 -1
- package/dist/rpc-entry.js +2 -1
- package/dist/rpc-entry.js.map +1 -1
- package/dist/testing/replay/metrics.d.ts +24 -0
- package/dist/testing/replay/metrics.d.ts.map +1 -0
- package/dist/testing/replay/metrics.js +35 -0
- package/dist/testing/replay/metrics.js.map +1 -0
- package/dist/testing/replay/recorded-provider.d.ts +10 -0
- package/dist/testing/replay/recorded-provider.d.ts.map +1 -0
- package/dist/testing/replay/recorded-provider.js +108 -0
- package/dist/testing/replay/recorded-provider.js.map +1 -0
- package/dist/testing/replay/runner.d.ts +56 -0
- package/dist/testing/replay/runner.d.ts.map +1 -0
- package/dist/testing/replay/runner.js +406 -0
- package/dist/testing/replay/runner.js.map +1 -0
- package/dist/themes/apex-logo.d.ts +41 -0
- package/dist/themes/apex-logo.d.ts.map +1 -0
- package/dist/themes/apex-logo.js +35 -0
- package/dist/themes/apex-logo.js.map +1 -0
- package/dist/utils/apex-code-user-agent.d.ts +2 -0
- package/dist/utils/apex-code-user-agent.d.ts.map +1 -0
- package/dist/utils/apex-code-user-agent.js +5 -0
- package/dist/utils/apex-code-user-agent.js.map +1 -0
- package/dist/utils/changelog.d.ts +7 -2
- package/dist/utils/changelog.d.ts.map +1 -1
- package/dist/utils/changelog.js +82 -13
- package/dist/utils/changelog.js.map +1 -1
- package/dist/utils/clipboard-image.d.ts.map +1 -1
- package/dist/utils/clipboard-image.js +1 -1
- package/dist/utils/clipboard-image.js.map +1 -1
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js +2 -1
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/management-http.d.ts +5 -3
- package/dist/utils/management-http.d.ts.map +1 -1
- package/dist/utils/management-http.js +14 -10
- package/dist/utils/management-http.js.map +1 -1
- package/dist/utils/shell.d.ts +3 -0
- package/dist/utils/shell.d.ts.map +1 -1
- package/dist/utils/shell.js +17 -5
- package/dist/utils/shell.js.map +1 -1
- package/dist/utils/syntax-highlight.d.ts +1 -0
- package/dist/utils/syntax-highlight.d.ts.map +1 -1
- package/dist/utils/syntax-highlight.js +60 -1
- package/dist/utils/syntax-highlight.js.map +1 -1
- package/dist/utils/text.d.ts +8 -0
- package/dist/utils/text.d.ts.map +1 -0
- package/dist/utils/text.js +9 -0
- package/dist/utils/text.js.map +1 -0
- package/dist/utils/tools-manager.d.ts +70 -2
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +280 -124
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/version-check.d.ts +7 -5
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +27 -14
- package/dist/utils/version-check.js.map +1 -1
- package/dist/utils/windows-self-update.d.ts.map +1 -1
- package/dist/utils/windows-self-update.js +1 -1
- package/dist/utils/windows-self-update.js.map +1 -1
- package/docs/compaction.md +41 -24
- package/docs/containerization.md +24 -21
- package/docs/custom-provider.md +15 -12
- package/docs/development.md +11 -11
- package/docs/environment-variables.md +37 -77
- package/docs/extensions.md +68 -54
- package/docs/index.md +12 -24
- package/docs/json.md +18 -11
- package/docs/keybindings.md +18 -12
- package/docs/llama-cpp.md +9 -7
- package/docs/models.md +17 -11
- package/docs/packages.md +47 -43
- package/docs/prompt-templates.md +3 -3
- package/docs/providers.md +10 -10
- package/docs/quickstart.md +49 -32
- package/docs/rpc.md +35 -18
- package/docs/sdk.md +20 -6
- package/docs/security.md +18 -18
- package/docs/session-format.md +9 -9
- package/docs/sessions.md +13 -13
- package/docs/settings.md +83 -16
- package/docs/shell-aliases.md +1 -1
- package/docs/skills.md +66 -15
- package/docs/terminal-setup.md +44 -19
- package/docs/termux.md +4 -4
- package/docs/themes.md +32 -11
- package/docs/tmux.md +4 -4
- package/docs/tui.md +5 -5
- package/docs/usage.md +61 -53
- package/docs/windows.md +24 -2
- package/examples/extensions/border-status-editor.ts +1 -1
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +2 -2
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/git-checkpoint.ts +24 -36
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/notify.ts +3 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/subagent/README.md +3 -1
- package/examples/extensions/subagent/agents.ts +40 -9
- package/examples/extensions/subagent/index.ts +27 -4
- package/examples/extensions/titlebar-spinner.ts +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/examples/rpc-extension-ui.ts +1 -1
- package/examples/sdk/06-extensions.ts +1 -1
- package/examples/sdk/README.md +1 -1
- package/npm-shrinkwrap.json +435 -452
- package/package.json +17 -18
- package/dist/core/telemetry.d.ts +0 -3
- package/dist/core/telemetry.d.ts.map +0 -1
- package/dist/core/telemetry.js +0 -9
- package/dist/core/telemetry.js.map +0 -1
- package/dist/server/create-harness.d.ts +0 -26
- package/dist/server/create-harness.d.ts.map +0 -1
- package/dist/server/create-harness.js +0 -104
- package/dist/server/create-harness.js.map +0 -1
- package/dist/utils/pi-user-agent.d.ts +0 -2
- package/dist/utils/pi-user-agent.d.ts.map +0 -1
- package/dist/utils/pi-user-agent.js +0 -5
- package/dist/utils/pi-user-agent.js.map +0 -1
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deferred-schema resolution — announce-by-name projection and explicit load path.
|
|
3
|
+
*
|
|
4
|
+
* Ordering context (`docs/architecture/contracts.md` § 2, "Context pipeline order —
|
|
5
|
+
* settled"): deferred-schema resolution is the first of three stages applied at the
|
|
6
|
+
* `transformContext` seam —
|
|
7
|
+
*
|
|
8
|
+
* deferred-schema resolution → tool-result eviction → compaction
|
|
9
|
+
*
|
|
10
|
+
* — because it changes the static prefix (system prompt + tool definitions) that both
|
|
11
|
+
* later stages measure themselves against. This module implements only that first
|
|
12
|
+
* stage's two primitives; wiring it into `transformContext` is task 3.3.
|
|
13
|
+
*
|
|
14
|
+
* `ContextSpec.deferSchema` (`core/tools/contract.ts`) is the per-tool flag this
|
|
15
|
+
* module reads: a tool with `deferSchema: true` is announced to the model by name and
|
|
16
|
+
* description only — its full JSON parameter schema is withheld from the static
|
|
17
|
+
* prefix — and materialized on demand through `loadDeferredSchema` when a later
|
|
18
|
+
* wiring stage needs the real schema for a tool the model decided to call.
|
|
19
|
+
*
|
|
20
|
+
* Both functions are pure: everything they need arrives as a parameter, nothing is
|
|
21
|
+
* read from a global tool registry, and neither performs I/O.
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Minimal shape this module needs from a tool definition. Any richer type — e.g.
|
|
25
|
+
* `ApexToolDefinition` from `core/tools/contract.ts` — satisfies this structurally,
|
|
26
|
+
* so a caller can pass its real tool-definition array directly with no adapter.
|
|
27
|
+
*/
|
|
28
|
+
export interface DeferrableTool {
|
|
29
|
+
name: string;
|
|
30
|
+
description: string;
|
|
31
|
+
/**
|
|
32
|
+
* The tool's full parameter schema (a TypeBox `TSchema` on `ApexToolDefinition` in
|
|
33
|
+
* this repo, but this module treats it as opaque — it never inspects, validates,
|
|
34
|
+
* or transforms its shape, only copies or withholds it whole).
|
|
35
|
+
*/
|
|
36
|
+
parameters: unknown;
|
|
37
|
+
contract: {
|
|
38
|
+
context: {
|
|
39
|
+
deferSchema: boolean;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* A tool as announced to the model: name, description, and a parameter schema that is
|
|
45
|
+
* either the tool's real schema (`deferSchema: false`) or the stub below
|
|
46
|
+
* (`deferSchema: true`).
|
|
47
|
+
*/
|
|
48
|
+
export interface AnnouncedTool {
|
|
49
|
+
name: string;
|
|
50
|
+
description: string;
|
|
51
|
+
parameters: unknown;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Stub schema substituted for a deferred tool's real parameters in the announce-by-name
|
|
55
|
+
* projection. An empty object schema rather than `undefined`/omission, so a provider
|
|
56
|
+
* that requires a `parameters`/`input_schema` field on every tool entry still receives
|
|
57
|
+
* a well-formed one.
|
|
58
|
+
*/
|
|
59
|
+
export declare const DEFERRED_SCHEMA_STUB: Readonly<{
|
|
60
|
+
type: "object";
|
|
61
|
+
properties: Record<string, never>;
|
|
62
|
+
}>;
|
|
63
|
+
/**
|
|
64
|
+
* Announce-by-name projection (context pipeline stage 1, "deferred-schema
|
|
65
|
+
* resolution").
|
|
66
|
+
*
|
|
67
|
+
* Tools with `contract.context.deferSchema === true` are represented by name and
|
|
68
|
+
* description only; their `parameters` field is replaced with `DEFERRED_SCHEMA_STUB`.
|
|
69
|
+
* Tools with `deferSchema === false` pass through with their real schema unchanged
|
|
70
|
+
* (the same reference, so deep- and reference-equality both hold).
|
|
71
|
+
*
|
|
72
|
+
* Pure: same length and order as `tools` in, no field other than `parameters` is
|
|
73
|
+
* altered, no global state is read.
|
|
74
|
+
*/
|
|
75
|
+
export declare function announceToolsByName<T extends DeferrableTool>(tools: readonly T[]): AnnouncedTool[];
|
|
76
|
+
/**
|
|
77
|
+
* Explicit load path (context pipeline stage 1's counterpart): given a tool name,
|
|
78
|
+
* returns its real, full parameter schema — the mechanism a later wiring stage
|
|
79
|
+
* (task 3.3) calls when the model needs the real schema for a deferred tool it
|
|
80
|
+
* decided to call.
|
|
81
|
+
*
|
|
82
|
+
* Looks up `name` in `tools` and returns that tool's real `parameters`, regardless of
|
|
83
|
+
* whether `deferSchema` is `true` or `false` — a tool that never deferred its schema
|
|
84
|
+
* still has a well-defined "real schema" to return, and the caller should not have to
|
|
85
|
+
* branch on `deferSchema` before loading.
|
|
86
|
+
*
|
|
87
|
+
* Throws if no tool named `name` exists in `tools`. Does not throw for a tool whose
|
|
88
|
+
* `deferSchema` is `false`; that is a valid no-op returning the same schema the
|
|
89
|
+
* announce-by-name projection already showed for it.
|
|
90
|
+
*/
|
|
91
|
+
export declare function loadDeferredSchema<T extends DeferrableTool>(tools: readonly T[], name: string): unknown;
|
|
92
|
+
//# sourceMappingURL=deferred-schemas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deferred-schemas.d.ts","sourceRoot":"","sources":["../../../src/core/context/deferred-schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE;QACT,OAAO,EAAE;YACR,WAAW,EAAE,OAAO,CAAC;SACrB,CAAC;KACF,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;CACpB;AAED;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;CAAE,CAG/F,CAAC;AAEH;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,cAAc,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,GAAG,aAAa,EAAE,CAMlG;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,cAAc,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAMvG","sourcesContent":["/**\n * Deferred-schema resolution — announce-by-name projection and explicit load path.\n *\n * Ordering context (`docs/architecture/contracts.md` § 2, \"Context pipeline order —\n * settled\"): deferred-schema resolution is the first of three stages applied at the\n * `transformContext` seam —\n *\n * deferred-schema resolution → tool-result eviction → compaction\n *\n * — because it changes the static prefix (system prompt + tool definitions) that both\n * later stages measure themselves against. This module implements only that first\n * stage's two primitives; wiring it into `transformContext` is task 3.3.\n *\n * `ContextSpec.deferSchema` (`core/tools/contract.ts`) is the per-tool flag this\n * module reads: a tool with `deferSchema: true` is announced to the model by name and\n * description only — its full JSON parameter schema is withheld from the static\n * prefix — and materialized on demand through `loadDeferredSchema` when a later\n * wiring stage needs the real schema for a tool the model decided to call.\n *\n * Both functions are pure: everything they need arrives as a parameter, nothing is\n * read from a global tool registry, and neither performs I/O.\n */\n\n/**\n * Minimal shape this module needs from a tool definition. Any richer type — e.g.\n * `ApexToolDefinition` from `core/tools/contract.ts` — satisfies this structurally,\n * so a caller can pass its real tool-definition array directly with no adapter.\n */\nexport interface DeferrableTool {\n\tname: string;\n\tdescription: string;\n\t/**\n\t * The tool's full parameter schema (a TypeBox `TSchema` on `ApexToolDefinition` in\n\t * this repo, but this module treats it as opaque — it never inspects, validates,\n\t * or transforms its shape, only copies or withholds it whole).\n\t */\n\tparameters: unknown;\n\tcontract: {\n\t\tcontext: {\n\t\t\tdeferSchema: boolean;\n\t\t};\n\t};\n}\n\n/**\n * A tool as announced to the model: name, description, and a parameter schema that is\n * either the tool's real schema (`deferSchema: false`) or the stub below\n * (`deferSchema: true`).\n */\nexport interface AnnouncedTool {\n\tname: string;\n\tdescription: string;\n\tparameters: unknown;\n}\n\n/**\n * Stub schema substituted for a deferred tool's real parameters in the announce-by-name\n * projection. An empty object schema rather than `undefined`/omission, so a provider\n * that requires a `parameters`/`input_schema` field on every tool entry still receives\n * a well-formed one.\n */\nexport const DEFERRED_SCHEMA_STUB: Readonly<{ type: \"object\"; properties: Record<string, never> }> = Object.freeze({\n\ttype: \"object\",\n\tproperties: {},\n});\n\n/**\n * Announce-by-name projection (context pipeline stage 1, \"deferred-schema\n * resolution\").\n *\n * Tools with `contract.context.deferSchema === true` are represented by name and\n * description only; their `parameters` field is replaced with `DEFERRED_SCHEMA_STUB`.\n * Tools with `deferSchema === false` pass through with their real schema unchanged\n * (the same reference, so deep- and reference-equality both hold).\n *\n * Pure: same length and order as `tools` in, no field other than `parameters` is\n * altered, no global state is read.\n */\nexport function announceToolsByName<T extends DeferrableTool>(tools: readonly T[]): AnnouncedTool[] {\n\treturn tools.map((tool) => ({\n\t\tname: tool.name,\n\t\tdescription: tool.description,\n\t\tparameters: tool.contract.context.deferSchema ? DEFERRED_SCHEMA_STUB : tool.parameters,\n\t}));\n}\n\n/**\n * Explicit load path (context pipeline stage 1's counterpart): given a tool name,\n * returns its real, full parameter schema — the mechanism a later wiring stage\n * (task 3.3) calls when the model needs the real schema for a deferred tool it\n * decided to call.\n *\n * Looks up `name` in `tools` and returns that tool's real `parameters`, regardless of\n * whether `deferSchema` is `true` or `false` — a tool that never deferred its schema\n * still has a well-defined \"real schema\" to return, and the caller should not have to\n * branch on `deferSchema` before loading.\n *\n * Throws if no tool named `name` exists in `tools`. Does not throw for a tool whose\n * `deferSchema` is `false`; that is a valid no-op returning the same schema the\n * announce-by-name projection already showed for it.\n */\nexport function loadDeferredSchema<T extends DeferrableTool>(tools: readonly T[], name: string): unknown {\n\tconst tool = tools.find((candidate) => candidate.name === name);\n\tif (!tool) {\n\t\tthrow new Error(`loadDeferredSchema: no tool named \"${name}\" in the provided definitions`);\n\t}\n\treturn tool.parameters;\n}\n"]}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deferred-schema resolution — announce-by-name projection and explicit load path.
|
|
3
|
+
*
|
|
4
|
+
* Ordering context (`docs/architecture/contracts.md` § 2, "Context pipeline order —
|
|
5
|
+
* settled"): deferred-schema resolution is the first of three stages applied at the
|
|
6
|
+
* `transformContext` seam —
|
|
7
|
+
*
|
|
8
|
+
* deferred-schema resolution → tool-result eviction → compaction
|
|
9
|
+
*
|
|
10
|
+
* — because it changes the static prefix (system prompt + tool definitions) that both
|
|
11
|
+
* later stages measure themselves against. This module implements only that first
|
|
12
|
+
* stage's two primitives; wiring it into `transformContext` is task 3.3.
|
|
13
|
+
*
|
|
14
|
+
* `ContextSpec.deferSchema` (`core/tools/contract.ts`) is the per-tool flag this
|
|
15
|
+
* module reads: a tool with `deferSchema: true` is announced to the model by name and
|
|
16
|
+
* description only — its full JSON parameter schema is withheld from the static
|
|
17
|
+
* prefix — and materialized on demand through `loadDeferredSchema` when a later
|
|
18
|
+
* wiring stage needs the real schema for a tool the model decided to call.
|
|
19
|
+
*
|
|
20
|
+
* Both functions are pure: everything they need arrives as a parameter, nothing is
|
|
21
|
+
* read from a global tool registry, and neither performs I/O.
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Stub schema substituted for a deferred tool's real parameters in the announce-by-name
|
|
25
|
+
* projection. An empty object schema rather than `undefined`/omission, so a provider
|
|
26
|
+
* that requires a `parameters`/`input_schema` field on every tool entry still receives
|
|
27
|
+
* a well-formed one.
|
|
28
|
+
*/
|
|
29
|
+
export const DEFERRED_SCHEMA_STUB = Object.freeze({
|
|
30
|
+
type: "object",
|
|
31
|
+
properties: {},
|
|
32
|
+
});
|
|
33
|
+
/**
|
|
34
|
+
* Announce-by-name projection (context pipeline stage 1, "deferred-schema
|
|
35
|
+
* resolution").
|
|
36
|
+
*
|
|
37
|
+
* Tools with `contract.context.deferSchema === true` are represented by name and
|
|
38
|
+
* description only; their `parameters` field is replaced with `DEFERRED_SCHEMA_STUB`.
|
|
39
|
+
* Tools with `deferSchema === false` pass through with their real schema unchanged
|
|
40
|
+
* (the same reference, so deep- and reference-equality both hold).
|
|
41
|
+
*
|
|
42
|
+
* Pure: same length and order as `tools` in, no field other than `parameters` is
|
|
43
|
+
* altered, no global state is read.
|
|
44
|
+
*/
|
|
45
|
+
export function announceToolsByName(tools) {
|
|
46
|
+
return tools.map((tool) => ({
|
|
47
|
+
name: tool.name,
|
|
48
|
+
description: tool.description,
|
|
49
|
+
parameters: tool.contract.context.deferSchema ? DEFERRED_SCHEMA_STUB : tool.parameters,
|
|
50
|
+
}));
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Explicit load path (context pipeline stage 1's counterpart): given a tool name,
|
|
54
|
+
* returns its real, full parameter schema — the mechanism a later wiring stage
|
|
55
|
+
* (task 3.3) calls when the model needs the real schema for a deferred tool it
|
|
56
|
+
* decided to call.
|
|
57
|
+
*
|
|
58
|
+
* Looks up `name` in `tools` and returns that tool's real `parameters`, regardless of
|
|
59
|
+
* whether `deferSchema` is `true` or `false` — a tool that never deferred its schema
|
|
60
|
+
* still has a well-defined "real schema" to return, and the caller should not have to
|
|
61
|
+
* branch on `deferSchema` before loading.
|
|
62
|
+
*
|
|
63
|
+
* Throws if no tool named `name` exists in `tools`. Does not throw for a tool whose
|
|
64
|
+
* `deferSchema` is `false`; that is a valid no-op returning the same schema the
|
|
65
|
+
* announce-by-name projection already showed for it.
|
|
66
|
+
*/
|
|
67
|
+
export function loadDeferredSchema(tools, name) {
|
|
68
|
+
const tool = tools.find((candidate) => candidate.name === name);
|
|
69
|
+
if (!tool) {
|
|
70
|
+
throw new Error(`loadDeferredSchema: no tool named "${name}" in the provided definitions`);
|
|
71
|
+
}
|
|
72
|
+
return tool.parameters;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=deferred-schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deferred-schemas.js","sourceRoot":"","sources":["../../../src/core/context/deferred-schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAkCH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAoE,MAAM,CAAC,MAAM,CAAC;IAClH,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE,EAAE;CACd,CAAC,CAAC;AAEH;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,mBAAmB,CAA2B,KAAmB,EAAmB;IACnG,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC3B,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU;KACtF,CAAC,CAAC,CAAC;AAAA,CACJ;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,kBAAkB,CAA2B,KAAmB,EAAE,IAAY,EAAW;IACxG,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IAChE,IAAI,CAAC,IAAI,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,sCAAsC,IAAI,+BAA+B,CAAC,CAAC;IAC5F,CAAC;IACD,OAAO,IAAI,CAAC,UAAU,CAAC;AAAA,CACvB","sourcesContent":["/**\n * Deferred-schema resolution — announce-by-name projection and explicit load path.\n *\n * Ordering context (`docs/architecture/contracts.md` § 2, \"Context pipeline order —\n * settled\"): deferred-schema resolution is the first of three stages applied at the\n * `transformContext` seam —\n *\n * deferred-schema resolution → tool-result eviction → compaction\n *\n * — because it changes the static prefix (system prompt + tool definitions) that both\n * later stages measure themselves against. This module implements only that first\n * stage's two primitives; wiring it into `transformContext` is task 3.3.\n *\n * `ContextSpec.deferSchema` (`core/tools/contract.ts`) is the per-tool flag this\n * module reads: a tool with `deferSchema: true` is announced to the model by name and\n * description only — its full JSON parameter schema is withheld from the static\n * prefix — and materialized on demand through `loadDeferredSchema` when a later\n * wiring stage needs the real schema for a tool the model decided to call.\n *\n * Both functions are pure: everything they need arrives as a parameter, nothing is\n * read from a global tool registry, and neither performs I/O.\n */\n\n/**\n * Minimal shape this module needs from a tool definition. Any richer type — e.g.\n * `ApexToolDefinition` from `core/tools/contract.ts` — satisfies this structurally,\n * so a caller can pass its real tool-definition array directly with no adapter.\n */\nexport interface DeferrableTool {\n\tname: string;\n\tdescription: string;\n\t/**\n\t * The tool's full parameter schema (a TypeBox `TSchema` on `ApexToolDefinition` in\n\t * this repo, but this module treats it as opaque — it never inspects, validates,\n\t * or transforms its shape, only copies or withholds it whole).\n\t */\n\tparameters: unknown;\n\tcontract: {\n\t\tcontext: {\n\t\t\tdeferSchema: boolean;\n\t\t};\n\t};\n}\n\n/**\n * A tool as announced to the model: name, description, and a parameter schema that is\n * either the tool's real schema (`deferSchema: false`) or the stub below\n * (`deferSchema: true`).\n */\nexport interface AnnouncedTool {\n\tname: string;\n\tdescription: string;\n\tparameters: unknown;\n}\n\n/**\n * Stub schema substituted for a deferred tool's real parameters in the announce-by-name\n * projection. An empty object schema rather than `undefined`/omission, so a provider\n * that requires a `parameters`/`input_schema` field on every tool entry still receives\n * a well-formed one.\n */\nexport const DEFERRED_SCHEMA_STUB: Readonly<{ type: \"object\"; properties: Record<string, never> }> = Object.freeze({\n\ttype: \"object\",\n\tproperties: {},\n});\n\n/**\n * Announce-by-name projection (context pipeline stage 1, \"deferred-schema\n * resolution\").\n *\n * Tools with `contract.context.deferSchema === true` are represented by name and\n * description only; their `parameters` field is replaced with `DEFERRED_SCHEMA_STUB`.\n * Tools with `deferSchema === false` pass through with their real schema unchanged\n * (the same reference, so deep- and reference-equality both hold).\n *\n * Pure: same length and order as `tools` in, no field other than `parameters` is\n * altered, no global state is read.\n */\nexport function announceToolsByName<T extends DeferrableTool>(tools: readonly T[]): AnnouncedTool[] {\n\treturn tools.map((tool) => ({\n\t\tname: tool.name,\n\t\tdescription: tool.description,\n\t\tparameters: tool.contract.context.deferSchema ? DEFERRED_SCHEMA_STUB : tool.parameters,\n\t}));\n}\n\n/**\n * Explicit load path (context pipeline stage 1's counterpart): given a tool name,\n * returns its real, full parameter schema — the mechanism a later wiring stage\n * (task 3.3) calls when the model needs the real schema for a deferred tool it\n * decided to call.\n *\n * Looks up `name` in `tools` and returns that tool's real `parameters`, regardless of\n * whether `deferSchema` is `true` or `false` — a tool that never deferred its schema\n * still has a well-defined \"real schema\" to return, and the caller should not have to\n * branch on `deferSchema` before loading.\n *\n * Throws if no tool named `name` exists in `tools`. Does not throw for a tool whose\n * `deferSchema` is `false`; that is a valid no-op returning the same schema the\n * announce-by-name projection already showed for it.\n */\nexport function loadDeferredSchema<T extends DeferrableTool>(tools: readonly T[], name: string): unknown {\n\tconst tool = tools.find((candidate) => candidate.name === name);\n\tif (!tool) {\n\t\tthrow new Error(`loadDeferredSchema: no tool named \"${name}\" in the provided definitions`);\n\t}\n\treturn tool.parameters;\n}\n"]}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool-result eviction — Phase 3 task 3.1.
|
|
3
|
+
*
|
|
4
|
+
* Implements the eviction algorithm settled in `docs/architecture/contracts.md` § 2
|
|
5
|
+
* ("Context pipeline order — settled"): a pure, prefix-oldest, contiguous-run
|
|
6
|
+
* transform over the message list. It runs *before* compaction in the pipeline
|
|
7
|
+
* order (deferred-schema resolution → eviction → compaction), but this module knows
|
|
8
|
+
* nothing about that ordering or about `transformContext` — wiring is task 3.3.
|
|
9
|
+
*
|
|
10
|
+
* Pure by construction: no clock, no randomness, no I/O, no reads of the live tool
|
|
11
|
+
* registry. Every fact this function needs about a tool comes through the injected
|
|
12
|
+
* `contractLookup`, and every fact about "how big is this" comes from the message
|
|
13
|
+
* content already in hand.
|
|
14
|
+
*/
|
|
15
|
+
import type { AgentMessage } from "apex-code-agent-core";
|
|
16
|
+
import type { ToolContract } from "../tools/contract.ts";
|
|
17
|
+
/**
|
|
18
|
+
* What `evictToolResults` needs to know about a tool's contract to decide whether
|
|
19
|
+
* (and how) to evict one of its results. Only the `context` axis of `ToolContract`
|
|
20
|
+
* matters here — callers may pass a full contract, or (as tests do) a hand-built
|
|
21
|
+
* stand-in with just `context` filled in.
|
|
22
|
+
*/
|
|
23
|
+
export type ContractLookup = (toolName: string) => Pick<ToolContract, "context"> | undefined;
|
|
24
|
+
/** Marker substituted for an evicted result when its contract declares none. */
|
|
25
|
+
export declare const DEFAULT_EVICTION_MARKER = "[Tool result evicted to save context. Re-run the tool to see it again.]";
|
|
26
|
+
/**
|
|
27
|
+
* Replace the oldest contiguous run of recoverable tool results with markers, until
|
|
28
|
+
* the estimated total token cost of *all* tool-result messages in the list drops to
|
|
29
|
+
* or below `budget` (chars/4, the same heuristic `estimateTokens` uses elsewhere in
|
|
30
|
+
* this codebase — see `core/compaction/compaction.ts`). "Contiguous run from the
|
|
31
|
+
* oldest end" is enforced by walking messages in order and stopping the walk for
|
|
32
|
+
* good — not just skipping — the moment a tool result is encountered whose contract
|
|
33
|
+
* says it is not recoverable (or has no contract at all, matching the `UNCLASSIFIED`
|
|
34
|
+
* default of `resultRecoverable: false`): later eligible results are never reached,
|
|
35
|
+
* so no hole ever opens in the middle of the transcript. Non-tool-result messages
|
|
36
|
+
* (assistant/user turns) are passed through untouched and do not interrupt or count
|
|
37
|
+
* toward the walk.
|
|
38
|
+
*
|
|
39
|
+
* Deterministic and idempotent: a message whose content already exactly equals its
|
|
40
|
+
* tool's marker is recognized as already evicted and left alone, so re-running this
|
|
41
|
+
* function over its own output (or over a budget that is already satisfied) is a
|
|
42
|
+
* no-op. Never mutates `messages` or any message object — always returns a new
|
|
43
|
+
* array; unevicted messages keep their original object identity (unmutated sharing
|
|
44
|
+
* is not mutation), evicted ones are new objects with only `content` replaced.
|
|
45
|
+
*/
|
|
46
|
+
export declare function evictToolResults(messages: readonly AgentMessage[], contractLookup: ContractLookup, budget: number): AgentMessage[];
|
|
47
|
+
//# sourceMappingURL=eviction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eviction.d.ts","sourceRoot":"","sources":["../../../src/core/context/eviction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,GAAG,SAAS,CAAC;AAE7F,gFAAgF;AAChF,eAAO,MAAM,uBAAuB,4EAA4E,CAAC;AAiBjH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,CAC/B,QAAQ,EAAE,SAAS,YAAY,EAAE,EACjC,cAAc,EAAE,cAAc,EAC9B,MAAM,EAAE,MAAM,GACZ,YAAY,EAAE,CAsChB","sourcesContent":["/**\n * Tool-result eviction — Phase 3 task 3.1.\n *\n * Implements the eviction algorithm settled in `docs/architecture/contracts.md` § 2\n * (\"Context pipeline order — settled\"): a pure, prefix-oldest, contiguous-run\n * transform over the message list. It runs *before* compaction in the pipeline\n * order (deferred-schema resolution → eviction → compaction), but this module knows\n * nothing about that ordering or about `transformContext` — wiring is task 3.3.\n *\n * Pure by construction: no clock, no randomness, no I/O, no reads of the live tool\n * registry. Every fact this function needs about a tool comes through the injected\n * `contractLookup`, and every fact about \"how big is this\" comes from the message\n * content already in hand.\n */\n\nimport type { TextContent } from \"@earendil-works/pi-ai\";\nimport type { AgentMessage } from \"apex-code-agent-core\";\nimport { estimateTokens } from \"../compaction/compaction.ts\";\nimport type { ToolContract } from \"../tools/contract.ts\";\n\n/**\n * What `evictToolResults` needs to know about a tool's contract to decide whether\n * (and how) to evict one of its results. Only the `context` axis of `ToolContract`\n * matters here — callers may pass a full contract, or (as tests do) a hand-built\n * stand-in with just `context` filled in.\n */\nexport type ContractLookup = (toolName: string) => Pick<ToolContract, \"context\"> | undefined;\n\n/** Marker substituted for an evicted result when its contract declares none. */\nexport const DEFAULT_EVICTION_MARKER = \"[Tool result evicted to save context. Re-run the tool to see it again.]\";\n\nfunction isToolResultMessage(message: AgentMessage): message is Extract<AgentMessage, { role: \"toolResult\" }> {\n\treturn message.role === \"toolResult\";\n}\n\n/** True when `content` is already exactly the single-text-block marker form. */\nfunction isAlreadyEvicted(content: readonly unknown[], marker: string): boolean {\n\treturn (\n\t\tcontent.length === 1 &&\n\t\ttypeof content[0] === \"object\" &&\n\t\tcontent[0] !== null &&\n\t\t(content[0] as { type?: unknown }).type === \"text\" &&\n\t\t(content[0] as { text?: unknown }).text === marker\n\t);\n}\n\n/**\n * Replace the oldest contiguous run of recoverable tool results with markers, until\n * the estimated total token cost of *all* tool-result messages in the list drops to\n * or below `budget` (chars/4, the same heuristic `estimateTokens` uses elsewhere in\n * this codebase — see `core/compaction/compaction.ts`). \"Contiguous run from the\n * oldest end\" is enforced by walking messages in order and stopping the walk for\n * good — not just skipping — the moment a tool result is encountered whose contract\n * says it is not recoverable (or has no contract at all, matching the `UNCLASSIFIED`\n * default of `resultRecoverable: false`): later eligible results are never reached,\n * so no hole ever opens in the middle of the transcript. Non-tool-result messages\n * (assistant/user turns) are passed through untouched and do not interrupt or count\n * toward the walk.\n *\n * Deterministic and idempotent: a message whose content already exactly equals its\n * tool's marker is recognized as already evicted and left alone, so re-running this\n * function over its own output (or over a budget that is already satisfied) is a\n * no-op. Never mutates `messages` or any message object — always returns a new\n * array; unevicted messages keep their original object identity (unmutated sharing\n * is not mutation), evicted ones are new objects with only `content` replaced.\n */\nexport function evictToolResults(\n\tmessages: readonly AgentMessage[],\n\tcontractLookup: ContractLookup,\n\tbudget: number,\n): AgentMessage[] {\n\tlet remaining = 0;\n\tfor (const message of messages) {\n\t\tif (isToolResultMessage(message)) remaining += estimateTokens(message);\n\t}\n\n\tconst result: AgentMessage[] = [];\n\tlet stopped = false;\n\n\tfor (const message of messages) {\n\t\tif (stopped || !isToolResultMessage(message) || remaining <= budget) {\n\t\t\tresult.push(message);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst contract = contractLookup(message.toolName);\n\t\tconst recoverable = contract?.context.resultRecoverable === true;\n\t\tif (!recoverable) {\n\t\t\tstopped = true;\n\t\t\tresult.push(message);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst marker = contract.context.evictionMarker ?? DEFAULT_EVICTION_MARKER;\n\t\tif (isAlreadyEvicted(message.content, marker)) {\n\t\t\tresult.push(message);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst before = estimateTokens(message);\n\t\tconst markerContent: TextContent[] = [{ type: \"text\", text: marker }];\n\t\tconst evicted = { ...message, content: markerContent };\n\t\tconst after = estimateTokens(evicted);\n\t\tremaining = remaining - before + after;\n\t\tresult.push(evicted);\n\t}\n\n\treturn result;\n}\n"]}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool-result eviction — Phase 3 task 3.1.
|
|
3
|
+
*
|
|
4
|
+
* Implements the eviction algorithm settled in `docs/architecture/contracts.md` § 2
|
|
5
|
+
* ("Context pipeline order — settled"): a pure, prefix-oldest, contiguous-run
|
|
6
|
+
* transform over the message list. It runs *before* compaction in the pipeline
|
|
7
|
+
* order (deferred-schema resolution → eviction → compaction), but this module knows
|
|
8
|
+
* nothing about that ordering or about `transformContext` — wiring is task 3.3.
|
|
9
|
+
*
|
|
10
|
+
* Pure by construction: no clock, no randomness, no I/O, no reads of the live tool
|
|
11
|
+
* registry. Every fact this function needs about a tool comes through the injected
|
|
12
|
+
* `contractLookup`, and every fact about "how big is this" comes from the message
|
|
13
|
+
* content already in hand.
|
|
14
|
+
*/
|
|
15
|
+
import { estimateTokens } from "../compaction/compaction.js";
|
|
16
|
+
/** Marker substituted for an evicted result when its contract declares none. */
|
|
17
|
+
export const DEFAULT_EVICTION_MARKER = "[Tool result evicted to save context. Re-run the tool to see it again.]";
|
|
18
|
+
function isToolResultMessage(message) {
|
|
19
|
+
return message.role === "toolResult";
|
|
20
|
+
}
|
|
21
|
+
/** True when `content` is already exactly the single-text-block marker form. */
|
|
22
|
+
function isAlreadyEvicted(content, marker) {
|
|
23
|
+
return (content.length === 1 &&
|
|
24
|
+
typeof content[0] === "object" &&
|
|
25
|
+
content[0] !== null &&
|
|
26
|
+
content[0].type === "text" &&
|
|
27
|
+
content[0].text === marker);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Replace the oldest contiguous run of recoverable tool results with markers, until
|
|
31
|
+
* the estimated total token cost of *all* tool-result messages in the list drops to
|
|
32
|
+
* or below `budget` (chars/4, the same heuristic `estimateTokens` uses elsewhere in
|
|
33
|
+
* this codebase — see `core/compaction/compaction.ts`). "Contiguous run from the
|
|
34
|
+
* oldest end" is enforced by walking messages in order and stopping the walk for
|
|
35
|
+
* good — not just skipping — the moment a tool result is encountered whose contract
|
|
36
|
+
* says it is not recoverable (or has no contract at all, matching the `UNCLASSIFIED`
|
|
37
|
+
* default of `resultRecoverable: false`): later eligible results are never reached,
|
|
38
|
+
* so no hole ever opens in the middle of the transcript. Non-tool-result messages
|
|
39
|
+
* (assistant/user turns) are passed through untouched and do not interrupt or count
|
|
40
|
+
* toward the walk.
|
|
41
|
+
*
|
|
42
|
+
* Deterministic and idempotent: a message whose content already exactly equals its
|
|
43
|
+
* tool's marker is recognized as already evicted and left alone, so re-running this
|
|
44
|
+
* function over its own output (or over a budget that is already satisfied) is a
|
|
45
|
+
* no-op. Never mutates `messages` or any message object — always returns a new
|
|
46
|
+
* array; unevicted messages keep their original object identity (unmutated sharing
|
|
47
|
+
* is not mutation), evicted ones are new objects with only `content` replaced.
|
|
48
|
+
*/
|
|
49
|
+
export function evictToolResults(messages, contractLookup, budget) {
|
|
50
|
+
let remaining = 0;
|
|
51
|
+
for (const message of messages) {
|
|
52
|
+
if (isToolResultMessage(message))
|
|
53
|
+
remaining += estimateTokens(message);
|
|
54
|
+
}
|
|
55
|
+
const result = [];
|
|
56
|
+
let stopped = false;
|
|
57
|
+
for (const message of messages) {
|
|
58
|
+
if (stopped || !isToolResultMessage(message) || remaining <= budget) {
|
|
59
|
+
result.push(message);
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const contract = contractLookup(message.toolName);
|
|
63
|
+
const recoverable = contract?.context.resultRecoverable === true;
|
|
64
|
+
if (!recoverable) {
|
|
65
|
+
stopped = true;
|
|
66
|
+
result.push(message);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
const marker = contract.context.evictionMarker ?? DEFAULT_EVICTION_MARKER;
|
|
70
|
+
if (isAlreadyEvicted(message.content, marker)) {
|
|
71
|
+
result.push(message);
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
const before = estimateTokens(message);
|
|
75
|
+
const markerContent = [{ type: "text", text: marker }];
|
|
76
|
+
const evicted = { ...message, content: markerContent };
|
|
77
|
+
const after = estimateTokens(evicted);
|
|
78
|
+
remaining = remaining - before + after;
|
|
79
|
+
result.push(evicted);
|
|
80
|
+
}
|
|
81
|
+
return result;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=eviction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eviction.js","sourceRoot":"","sources":["../../../src/core/context/eviction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAW7D,gFAAgF;AAChF,MAAM,CAAC,MAAM,uBAAuB,GAAG,yEAAyE,CAAC;AAEjH,SAAS,mBAAmB,CAAC,OAAqB,EAA4D;IAC7G,OAAO,OAAO,CAAC,IAAI,KAAK,YAAY,CAAC;AAAA,CACrC;AAED,gFAAgF;AAChF,SAAS,gBAAgB,CAAC,OAA2B,EAAE,MAAc,EAAW;IAC/E,OAAO,CACN,OAAO,CAAC,MAAM,KAAK,CAAC;QACpB,OAAO,OAAO,CAAC,CAAC,CAAC,KAAK,QAAQ;QAC9B,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI;QAClB,OAAO,CAAC,CAAC,CAAwB,CAAC,IAAI,KAAK,MAAM;QACjD,OAAO,CAAC,CAAC,CAAwB,CAAC,IAAI,KAAK,MAAM,CAClD,CAAC;AAAA,CACF;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,gBAAgB,CAC/B,QAAiC,EACjC,cAA8B,EAC9B,MAAc,EACG;IACjB,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAChC,IAAI,mBAAmB,CAAC,OAAO,CAAC;YAAE,SAAS,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,MAAM,GAAmB,EAAE,CAAC;IAClC,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAChC,IAAI,OAAO,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,IAAI,SAAS,IAAI,MAAM,EAAE,CAAC;YACrE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACrB,SAAS;QACV,CAAC;QAED,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAClD,MAAM,WAAW,GAAG,QAAQ,EAAE,OAAO,CAAC,iBAAiB,KAAK,IAAI,CAAC;QACjE,IAAI,CAAC,WAAW,EAAE,CAAC;YAClB,OAAO,GAAG,IAAI,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACrB,SAAS;QACV,CAAC;QAED,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,cAAc,IAAI,uBAAuB,CAAC;QAC1E,IAAI,gBAAgB,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC;YAC/C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACrB,SAAS;QACV,CAAC;QAED,MAAM,MAAM,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;QACvC,MAAM,aAAa,GAAkB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QACtE,MAAM,OAAO,GAAG,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC;QACvD,MAAM,KAAK,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;QACtC,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,KAAK,CAAC;QACvC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACtB,CAAC;IAED,OAAO,MAAM,CAAC;AAAA,CACd","sourcesContent":["/**\n * Tool-result eviction — Phase 3 task 3.1.\n *\n * Implements the eviction algorithm settled in `docs/architecture/contracts.md` § 2\n * (\"Context pipeline order — settled\"): a pure, prefix-oldest, contiguous-run\n * transform over the message list. It runs *before* compaction in the pipeline\n * order (deferred-schema resolution → eviction → compaction), but this module knows\n * nothing about that ordering or about `transformContext` — wiring is task 3.3.\n *\n * Pure by construction: no clock, no randomness, no I/O, no reads of the live tool\n * registry. Every fact this function needs about a tool comes through the injected\n * `contractLookup`, and every fact about \"how big is this\" comes from the message\n * content already in hand.\n */\n\nimport type { TextContent } from \"@earendil-works/pi-ai\";\nimport type { AgentMessage } from \"apex-code-agent-core\";\nimport { estimateTokens } from \"../compaction/compaction.ts\";\nimport type { ToolContract } from \"../tools/contract.ts\";\n\n/**\n * What `evictToolResults` needs to know about a tool's contract to decide whether\n * (and how) to evict one of its results. Only the `context` axis of `ToolContract`\n * matters here — callers may pass a full contract, or (as tests do) a hand-built\n * stand-in with just `context` filled in.\n */\nexport type ContractLookup = (toolName: string) => Pick<ToolContract, \"context\"> | undefined;\n\n/** Marker substituted for an evicted result when its contract declares none. */\nexport const DEFAULT_EVICTION_MARKER = \"[Tool result evicted to save context. Re-run the tool to see it again.]\";\n\nfunction isToolResultMessage(message: AgentMessage): message is Extract<AgentMessage, { role: \"toolResult\" }> {\n\treturn message.role === \"toolResult\";\n}\n\n/** True when `content` is already exactly the single-text-block marker form. */\nfunction isAlreadyEvicted(content: readonly unknown[], marker: string): boolean {\n\treturn (\n\t\tcontent.length === 1 &&\n\t\ttypeof content[0] === \"object\" &&\n\t\tcontent[0] !== null &&\n\t\t(content[0] as { type?: unknown }).type === \"text\" &&\n\t\t(content[0] as { text?: unknown }).text === marker\n\t);\n}\n\n/**\n * Replace the oldest contiguous run of recoverable tool results with markers, until\n * the estimated total token cost of *all* tool-result messages in the list drops to\n * or below `budget` (chars/4, the same heuristic `estimateTokens` uses elsewhere in\n * this codebase — see `core/compaction/compaction.ts`). \"Contiguous run from the\n * oldest end\" is enforced by walking messages in order and stopping the walk for\n * good — not just skipping — the moment a tool result is encountered whose contract\n * says it is not recoverable (or has no contract at all, matching the `UNCLASSIFIED`\n * default of `resultRecoverable: false`): later eligible results are never reached,\n * so no hole ever opens in the middle of the transcript. Non-tool-result messages\n * (assistant/user turns) are passed through untouched and do not interrupt or count\n * toward the walk.\n *\n * Deterministic and idempotent: a message whose content already exactly equals its\n * tool's marker is recognized as already evicted and left alone, so re-running this\n * function over its own output (or over a budget that is already satisfied) is a\n * no-op. Never mutates `messages` or any message object — always returns a new\n * array; unevicted messages keep their original object identity (unmutated sharing\n * is not mutation), evicted ones are new objects with only `content` replaced.\n */\nexport function evictToolResults(\n\tmessages: readonly AgentMessage[],\n\tcontractLookup: ContractLookup,\n\tbudget: number,\n): AgentMessage[] {\n\tlet remaining = 0;\n\tfor (const message of messages) {\n\t\tif (isToolResultMessage(message)) remaining += estimateTokens(message);\n\t}\n\n\tconst result: AgentMessage[] = [];\n\tlet stopped = false;\n\n\tfor (const message of messages) {\n\t\tif (stopped || !isToolResultMessage(message) || remaining <= budget) {\n\t\t\tresult.push(message);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst contract = contractLookup(message.toolName);\n\t\tconst recoverable = contract?.context.resultRecoverable === true;\n\t\tif (!recoverable) {\n\t\t\tstopped = true;\n\t\t\tresult.push(message);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst marker = contract.context.evictionMarker ?? DEFAULT_EVICTION_MARKER;\n\t\tif (isAlreadyEvicted(message.content, marker)) {\n\t\t\tresult.push(message);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst before = estimateTokens(message);\n\t\tconst markerContent: TextContent[] = [{ type: \"text\", text: marker }];\n\t\tconst evicted = { ...message, content: markerContent };\n\t\tconst after = estimateTokens(evicted);\n\t\tremaining = remaining - before + after;\n\t\tresult.push(evicted);\n\t}\n\n\treturn result;\n}\n"]}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context pipeline wiring — shared by `AgentSession` (production) and the offline
|
|
3
|
+
* replay harness (`src/testing/replay/runner.ts`), so there is exactly one
|
|
4
|
+
* implementation of "how deferred-schema resolution and eviction attach to an
|
|
5
|
+
* `Agent`" rather than two independently maintained copies.
|
|
6
|
+
*
|
|
7
|
+
* Implements the ordering settled in `docs/architecture/contracts.md` § 2:
|
|
8
|
+
* deferred-schema resolution → tool-result eviction → compaction. Compaction runs
|
|
9
|
+
* reactively from its own existing seam (`_checkCompaction` in `agent-session.ts`)
|
|
10
|
+
* and is untouched here; this module only adds the two stages that run *ahead of*
|
|
11
|
+
* every LLM request, so that reactive check is reached less often because the
|
|
12
|
+
* request it is reacting to is smaller.
|
|
13
|
+
*
|
|
14
|
+
* The two stages land in different seams because they operate on different halves
|
|
15
|
+
* of the outbound request. Eviction is a pure function of `AgentMessage[]`, which is
|
|
16
|
+
* exactly what `transformContext` sees, immediately before `convertToLlm` — so it is
|
|
17
|
+
* wired there. Deferred-schema resolution operates on the *tool list*, not messages;
|
|
18
|
+
* `transformContext`'s signature has no tools parameter, and `AgentContext.tools` is
|
|
19
|
+
* a snapshot taken once per prompt rather than rebuilt per request. The seam that
|
|
20
|
+
* actually sees the assembled outbound tool list on every request is
|
|
21
|
+
* `streamFunction` — it receives the full `Context`, tools included, immediately
|
|
22
|
+
* before the provider call — so the projection is applied there instead. Because the
|
|
23
|
+
* two stages act on disjoint fields of the request with no data dependency between
|
|
24
|
+
* them, this does not change the observable pipeline order.
|
|
25
|
+
*/
|
|
26
|
+
import type { Agent, StreamFn } from "apex-code-agent-core";
|
|
27
|
+
import { type ContractLookup } from "./eviction.ts";
|
|
28
|
+
/**
|
|
29
|
+
* Eviction-budget formula shared by every caller of `installContextPipeline`.
|
|
30
|
+
* Compaction fires once total context tokens exceed `contextWindow - reserveTokens`
|
|
31
|
+
* (`shouldCompact` in `core/compaction/compaction.ts`). Budgeting eviction — counted
|
|
32
|
+
* purely against tool-result tokens, per `evictToolResults`'s own contract — at half
|
|
33
|
+
* of that headroom leaves the other half free for system prompt and conversational
|
|
34
|
+
* growth, so eviction (cheap, structure-preserving) gets a chance to shrink the
|
|
35
|
+
* transcript before the expensive compaction stage is ever reached, matching
|
|
36
|
+
* contracts.md § 2's "why this order" (eviction before compaction, so compaction is
|
|
37
|
+
* reached later and less often).
|
|
38
|
+
*
|
|
39
|
+
* `Math.max(0, ...)` mirrors `shouldCompact`'s own behavior when `contextWindow` is
|
|
40
|
+
* unknown (0): evict aggressively rather than not at all, rather than inventing a
|
|
41
|
+
* different, unproven fallback.
|
|
42
|
+
*
|
|
43
|
+
* Production (`AgentSession`) calls this with the real model's `contextWindow` and
|
|
44
|
+
* the user's configured `reserveTokens`. The offline replay harness deliberately
|
|
45
|
+
* does *not* call this with the fixture model's `contextWindow` — see
|
|
46
|
+
* `REPLAY_EVICTION_BUDGET` in `src/testing/replay/runner.ts` for why a dedicated
|
|
47
|
+
* constant is used there instead.
|
|
48
|
+
*/
|
|
49
|
+
export declare function evictionBudget(contextWindow: number, reserveTokens: number): number;
|
|
50
|
+
/**
|
|
51
|
+
* Adapter between a caller's tool registry and `announceToolsByName`, which
|
|
52
|
+
* operates on a minimal `DeferrableTool` shape that has no notion of a tool
|
|
53
|
+
* registry. Only `parameters` is ever replaced; every other field of the outbound
|
|
54
|
+
* tool (name, description, and on `AgentTool` specifically, `execute`, `label`,
|
|
55
|
+
* etc.) passes through unchanged via the object spread.
|
|
56
|
+
*
|
|
57
|
+
* A tool with no entry in `contractLookup` (a foreign/unclassified tool) is treated
|
|
58
|
+
* as `deferSchema: false` here — the safe default on this axis is to keep
|
|
59
|
+
* describing it fully, the mirror image of eviction's "no contract => don't evict"
|
|
60
|
+
* default: when unsure, don't withhold information the model needs.
|
|
61
|
+
*/
|
|
62
|
+
export declare function projectToolSchemas<T extends {
|
|
63
|
+
name: string;
|
|
64
|
+
description: string;
|
|
65
|
+
parameters: unknown;
|
|
66
|
+
}>(tools: readonly T[], contractLookup: ContractLookup, loadedSchemaNames?: ReadonlySet<string>): T[];
|
|
67
|
+
/** Returns true for the built-in streamSimple function, including its context-pipeline wrapper. */
|
|
68
|
+
export declare function isDefaultStreamFunction(streamFunction: StreamFn): boolean;
|
|
69
|
+
export interface ContextPipelineOptions {
|
|
70
|
+
/** Resolves a tool's contract; shared by both eviction and schema projection. */
|
|
71
|
+
contractLookup: ContractLookup;
|
|
72
|
+
/** Names whose real schemas have been loaded by the model in this session. */
|
|
73
|
+
loadedSchemaNames?: ReadonlySet<string>;
|
|
74
|
+
/**
|
|
75
|
+
* Eviction budget as a thunk, not a plain number: `AgentSession`'s budget
|
|
76
|
+
* depends on `this.model` and `this.settingsManager`, both of which can change
|
|
77
|
+
* over the session's lifetime (model switch, settings edit), and is never
|
|
78
|
+
* cached. Evaluating it fresh on every request is what keeps eviction correct
|
|
79
|
+
* after either changes mid-session.
|
|
80
|
+
*/
|
|
81
|
+
evictionBudget: () => number;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Installs the settled context pipeline (deferred-schema resolution → eviction)
|
|
85
|
+
* onto `agent`, chaining onto whatever `transformContext` / `streamFunction` the
|
|
86
|
+
* caller already installed rather than replacing it — the same pattern
|
|
87
|
+
* `AgentSession._installAgentNextTurnRefresh` uses for `prepareNextTurnWithContext`.
|
|
88
|
+
*/
|
|
89
|
+
export declare function installContextPipeline(agent: Agent, options: ContextPipelineOptions): void;
|
|
90
|
+
//# sourceMappingURL=pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../../src/core/context/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAGH,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAG5D,OAAO,EAAE,KAAK,cAAc,EAAoB,MAAM,eAAe,CAAC;AAEtE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAEnF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,EACtG,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,cAAc,EAAE,cAAc,EAC9B,iBAAiB,GAAE,WAAW,CAAC,MAAM,CAAa,GAChD,CAAC,EAAE,CAcL;AAID,mGAAmG;AACnG,wBAAgB,uBAAuB,CAAC,cAAc,EAAE,QAAQ,GAAG,OAAO,CAEzE;AAED,MAAM,WAAW,sBAAsB;IACtC,iFAAiF;IACjF,cAAc,EAAE,cAAc,CAAC;IAC/B,8EAA8E;IAC9E,iBAAiB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACxC;;;;;;OAMG;IACH,cAAc,EAAE,MAAM,MAAM,CAAC;CAC7B;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,sBAAsB,GAAG,IAAI,CA0B1F","sourcesContent":["/**\n * Context pipeline wiring — shared by `AgentSession` (production) and the offline\n * replay harness (`src/testing/replay/runner.ts`), so there is exactly one\n * implementation of \"how deferred-schema resolution and eviction attach to an\n * `Agent`\" rather than two independently maintained copies.\n *\n * Implements the ordering settled in `docs/architecture/contracts.md` § 2:\n * deferred-schema resolution → tool-result eviction → compaction. Compaction runs\n * reactively from its own existing seam (`_checkCompaction` in `agent-session.ts`)\n * and is untouched here; this module only adds the two stages that run *ahead of*\n * every LLM request, so that reactive check is reached less often because the\n * request it is reacting to is smaller.\n *\n * The two stages land in different seams because they operate on different halves\n * of the outbound request. Eviction is a pure function of `AgentMessage[]`, which is\n * exactly what `transformContext` sees, immediately before `convertToLlm` — so it is\n * wired there. Deferred-schema resolution operates on the *tool list*, not messages;\n * `transformContext`'s signature has no tools parameter, and `AgentContext.tools` is\n * a snapshot taken once per prompt rather than rebuilt per request. The seam that\n * actually sees the assembled outbound tool list on every request is\n * `streamFunction` — it receives the full `Context`, tools included, immediately\n * before the provider call — so the projection is applied there instead. Because the\n * two stages act on disjoint fields of the request with no data dependency between\n * them, this does not change the observable pipeline order.\n */\n\nimport { streamSimple } from \"@earendil-works/pi-ai/compat\";\nimport type { Agent, StreamFn } from \"apex-code-agent-core\";\nimport { resolveToolContext } from \"../tools/contract.ts\";\nimport { announceToolsByName, type DeferrableTool } from \"./deferred-schemas.ts\";\nimport { type ContractLookup, evictToolResults } from \"./eviction.ts\";\n\n/**\n * Eviction-budget formula shared by every caller of `installContextPipeline`.\n * Compaction fires once total context tokens exceed `contextWindow - reserveTokens`\n * (`shouldCompact` in `core/compaction/compaction.ts`). Budgeting eviction — counted\n * purely against tool-result tokens, per `evictToolResults`'s own contract — at half\n * of that headroom leaves the other half free for system prompt and conversational\n * growth, so eviction (cheap, structure-preserving) gets a chance to shrink the\n * transcript before the expensive compaction stage is ever reached, matching\n * contracts.md § 2's \"why this order\" (eviction before compaction, so compaction is\n * reached later and less often).\n *\n * `Math.max(0, ...)` mirrors `shouldCompact`'s own behavior when `contextWindow` is\n * unknown (0): evict aggressively rather than not at all, rather than inventing a\n * different, unproven fallback.\n *\n * Production (`AgentSession`) calls this with the real model's `contextWindow` and\n * the user's configured `reserveTokens`. The offline replay harness deliberately\n * does *not* call this with the fixture model's `contextWindow` — see\n * `REPLAY_EVICTION_BUDGET` in `src/testing/replay/runner.ts` for why a dedicated\n * constant is used there instead.\n */\nexport function evictionBudget(contextWindow: number, reserveTokens: number): number {\n\treturn Math.max(0, Math.floor((contextWindow - reserveTokens) / 2));\n}\n\n/**\n * Adapter between a caller's tool registry and `announceToolsByName`, which\n * operates on a minimal `DeferrableTool` shape that has no notion of a tool\n * registry. Only `parameters` is ever replaced; every other field of the outbound\n * tool (name, description, and on `AgentTool` specifically, `execute`, `label`,\n * etc.) passes through unchanged via the object spread.\n *\n * A tool with no entry in `contractLookup` (a foreign/unclassified tool) is treated\n * as `deferSchema: false` here — the safe default on this axis is to keep\n * describing it fully, the mirror image of eviction's \"no contract => don't evict\"\n * default: when unsure, don't withhold information the model needs.\n */\nexport function projectToolSchemas<T extends { name: string; description: string; parameters: unknown }>(\n\ttools: readonly T[],\n\tcontractLookup: ContractLookup,\n\tloadedSchemaNames: ReadonlySet<string> = new Set(),\n): T[] {\n\tconst deferrable: DeferrableTool[] = tools.map((tool) => ({\n\t\tname: tool.name,\n\t\tdescription: tool.description,\n\t\tparameters: tool.parameters,\n\t\tcontract: {\n\t\t\tcontext: {\n\t\t\t\tdeferSchema:\n\t\t\t\t\t!loadedSchemaNames.has(tool.name) && resolveToolContext(contractLookup, tool.name).context.deferSchema,\n\t\t\t},\n\t\t},\n\t}));\n\tconst announced = announceToolsByName(deferrable);\n\treturn tools.map((tool, index) => ({ ...tool, parameters: announced[index].parameters }));\n}\n\nconst defaultStreamFunctions = new WeakSet<StreamFn>();\n\n/** Returns true for the built-in streamSimple function, including its context-pipeline wrapper. */\nexport function isDefaultStreamFunction(streamFunction: StreamFn): boolean {\n\treturn streamFunction === streamSimple || defaultStreamFunctions.has(streamFunction);\n}\n\nexport interface ContextPipelineOptions {\n\t/** Resolves a tool's contract; shared by both eviction and schema projection. */\n\tcontractLookup: ContractLookup;\n\t/** Names whose real schemas have been loaded by the model in this session. */\n\tloadedSchemaNames?: ReadonlySet<string>;\n\t/**\n\t * Eviction budget as a thunk, not a plain number: `AgentSession`'s budget\n\t * depends on `this.model` and `this.settingsManager`, both of which can change\n\t * over the session's lifetime (model switch, settings edit), and is never\n\t * cached. Evaluating it fresh on every request is what keeps eviction correct\n\t * after either changes mid-session.\n\t */\n\tevictionBudget: () => number;\n}\n\n/**\n * Installs the settled context pipeline (deferred-schema resolution → eviction)\n * onto `agent`, chaining onto whatever `transformContext` / `streamFunction` the\n * caller already installed rather than replacing it — the same pattern\n * `AgentSession._installAgentNextTurnRefresh` uses for `prepareNextTurnWithContext`.\n */\nexport function installContextPipeline(agent: Agent, options: ContextPipelineOptions): void {\n\tconst { contractLookup, evictionBudget: getBudget, loadedSchemaNames = new Set<string>() } = options;\n\n\tconst previousTransformContext = agent.transformContext;\n\tagent.transformContext = async (messages, signal) => {\n\t\tconst afterPrevious = previousTransformContext ? await previousTransformContext(messages, signal) : messages;\n\t\treturn evictToolResults(afterPrevious, contractLookup, getBudget());\n\t};\n\n\tconst previousStreamFunction = agent.streamFunction;\n\tconst wrappedStreamFunction = (\n\t\tmodel: Parameters<typeof previousStreamFunction>[0],\n\t\tcontext: Parameters<typeof previousStreamFunction>[1],\n\t\tstreamOptions: Parameters<typeof previousStreamFunction>[2],\n\t) => {\n\t\tif (!context.tools || context.tools.length === 0) {\n\t\t\treturn previousStreamFunction(model, context, streamOptions);\n\t\t}\n\t\treturn previousStreamFunction(\n\t\t\tmodel,\n\t\t\t{ ...context, tools: projectToolSchemas(context.tools, contractLookup, loadedSchemaNames) },\n\t\t\tstreamOptions,\n\t\t);\n\t};\n\tif (isDefaultStreamFunction(previousStreamFunction)) defaultStreamFunctions.add(wrappedStreamFunction);\n\tagent.streamFunction = wrappedStreamFunction;\n}\n"]}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context pipeline wiring — shared by `AgentSession` (production) and the offline
|
|
3
|
+
* replay harness (`src/testing/replay/runner.ts`), so there is exactly one
|
|
4
|
+
* implementation of "how deferred-schema resolution and eviction attach to an
|
|
5
|
+
* `Agent`" rather than two independently maintained copies.
|
|
6
|
+
*
|
|
7
|
+
* Implements the ordering settled in `docs/architecture/contracts.md` § 2:
|
|
8
|
+
* deferred-schema resolution → tool-result eviction → compaction. Compaction runs
|
|
9
|
+
* reactively from its own existing seam (`_checkCompaction` in `agent-session.ts`)
|
|
10
|
+
* and is untouched here; this module only adds the two stages that run *ahead of*
|
|
11
|
+
* every LLM request, so that reactive check is reached less often because the
|
|
12
|
+
* request it is reacting to is smaller.
|
|
13
|
+
*
|
|
14
|
+
* The two stages land in different seams because they operate on different halves
|
|
15
|
+
* of the outbound request. Eviction is a pure function of `AgentMessage[]`, which is
|
|
16
|
+
* exactly what `transformContext` sees, immediately before `convertToLlm` — so it is
|
|
17
|
+
* wired there. Deferred-schema resolution operates on the *tool list*, not messages;
|
|
18
|
+
* `transformContext`'s signature has no tools parameter, and `AgentContext.tools` is
|
|
19
|
+
* a snapshot taken once per prompt rather than rebuilt per request. The seam that
|
|
20
|
+
* actually sees the assembled outbound tool list on every request is
|
|
21
|
+
* `streamFunction` — it receives the full `Context`, tools included, immediately
|
|
22
|
+
* before the provider call — so the projection is applied there instead. Because the
|
|
23
|
+
* two stages act on disjoint fields of the request with no data dependency between
|
|
24
|
+
* them, this does not change the observable pipeline order.
|
|
25
|
+
*/
|
|
26
|
+
import { streamSimple } from "@earendil-works/pi-ai/compat";
|
|
27
|
+
import { resolveToolContext } from "../tools/contract.js";
|
|
28
|
+
import { announceToolsByName } from "./deferred-schemas.js";
|
|
29
|
+
import { evictToolResults } from "./eviction.js";
|
|
30
|
+
/**
|
|
31
|
+
* Eviction-budget formula shared by every caller of `installContextPipeline`.
|
|
32
|
+
* Compaction fires once total context tokens exceed `contextWindow - reserveTokens`
|
|
33
|
+
* (`shouldCompact` in `core/compaction/compaction.ts`). Budgeting eviction — counted
|
|
34
|
+
* purely against tool-result tokens, per `evictToolResults`'s own contract — at half
|
|
35
|
+
* of that headroom leaves the other half free for system prompt and conversational
|
|
36
|
+
* growth, so eviction (cheap, structure-preserving) gets a chance to shrink the
|
|
37
|
+
* transcript before the expensive compaction stage is ever reached, matching
|
|
38
|
+
* contracts.md § 2's "why this order" (eviction before compaction, so compaction is
|
|
39
|
+
* reached later and less often).
|
|
40
|
+
*
|
|
41
|
+
* `Math.max(0, ...)` mirrors `shouldCompact`'s own behavior when `contextWindow` is
|
|
42
|
+
* unknown (0): evict aggressively rather than not at all, rather than inventing a
|
|
43
|
+
* different, unproven fallback.
|
|
44
|
+
*
|
|
45
|
+
* Production (`AgentSession`) calls this with the real model's `contextWindow` and
|
|
46
|
+
* the user's configured `reserveTokens`. The offline replay harness deliberately
|
|
47
|
+
* does *not* call this with the fixture model's `contextWindow` — see
|
|
48
|
+
* `REPLAY_EVICTION_BUDGET` in `src/testing/replay/runner.ts` for why a dedicated
|
|
49
|
+
* constant is used there instead.
|
|
50
|
+
*/
|
|
51
|
+
export function evictionBudget(contextWindow, reserveTokens) {
|
|
52
|
+
return Math.max(0, Math.floor((contextWindow - reserveTokens) / 2));
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Adapter between a caller's tool registry and `announceToolsByName`, which
|
|
56
|
+
* operates on a minimal `DeferrableTool` shape that has no notion of a tool
|
|
57
|
+
* registry. Only `parameters` is ever replaced; every other field of the outbound
|
|
58
|
+
* tool (name, description, and on `AgentTool` specifically, `execute`, `label`,
|
|
59
|
+
* etc.) passes through unchanged via the object spread.
|
|
60
|
+
*
|
|
61
|
+
* A tool with no entry in `contractLookup` (a foreign/unclassified tool) is treated
|
|
62
|
+
* as `deferSchema: false` here — the safe default on this axis is to keep
|
|
63
|
+
* describing it fully, the mirror image of eviction's "no contract => don't evict"
|
|
64
|
+
* default: when unsure, don't withhold information the model needs.
|
|
65
|
+
*/
|
|
66
|
+
export function projectToolSchemas(tools, contractLookup, loadedSchemaNames = new Set()) {
|
|
67
|
+
const deferrable = tools.map((tool) => ({
|
|
68
|
+
name: tool.name,
|
|
69
|
+
description: tool.description,
|
|
70
|
+
parameters: tool.parameters,
|
|
71
|
+
contract: {
|
|
72
|
+
context: {
|
|
73
|
+
deferSchema: !loadedSchemaNames.has(tool.name) && resolveToolContext(contractLookup, tool.name).context.deferSchema,
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
}));
|
|
77
|
+
const announced = announceToolsByName(deferrable);
|
|
78
|
+
return tools.map((tool, index) => ({ ...tool, parameters: announced[index].parameters }));
|
|
79
|
+
}
|
|
80
|
+
const defaultStreamFunctions = new WeakSet();
|
|
81
|
+
/** Returns true for the built-in streamSimple function, including its context-pipeline wrapper. */
|
|
82
|
+
export function isDefaultStreamFunction(streamFunction) {
|
|
83
|
+
return streamFunction === streamSimple || defaultStreamFunctions.has(streamFunction);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Installs the settled context pipeline (deferred-schema resolution → eviction)
|
|
87
|
+
* onto `agent`, chaining onto whatever `transformContext` / `streamFunction` the
|
|
88
|
+
* caller already installed rather than replacing it — the same pattern
|
|
89
|
+
* `AgentSession._installAgentNextTurnRefresh` uses for `prepareNextTurnWithContext`.
|
|
90
|
+
*/
|
|
91
|
+
export function installContextPipeline(agent, options) {
|
|
92
|
+
const { contractLookup, evictionBudget: getBudget, loadedSchemaNames = new Set() } = options;
|
|
93
|
+
const previousTransformContext = agent.transformContext;
|
|
94
|
+
agent.transformContext = async (messages, signal) => {
|
|
95
|
+
const afterPrevious = previousTransformContext ? await previousTransformContext(messages, signal) : messages;
|
|
96
|
+
return evictToolResults(afterPrevious, contractLookup, getBudget());
|
|
97
|
+
};
|
|
98
|
+
const previousStreamFunction = agent.streamFunction;
|
|
99
|
+
const wrappedStreamFunction = (model, context, streamOptions) => {
|
|
100
|
+
if (!context.tools || context.tools.length === 0) {
|
|
101
|
+
return previousStreamFunction(model, context, streamOptions);
|
|
102
|
+
}
|
|
103
|
+
return previousStreamFunction(model, { ...context, tools: projectToolSchemas(context.tools, contractLookup, loadedSchemaNames) }, streamOptions);
|
|
104
|
+
};
|
|
105
|
+
if (isDefaultStreamFunction(previousStreamFunction))
|
|
106
|
+
defaultStreamFunctions.add(wrappedStreamFunction);
|
|
107
|
+
agent.streamFunction = wrappedStreamFunction;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../../src/core/context/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAE5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAuB,MAAM,uBAAuB,CAAC;AACjF,OAAO,EAAuB,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,cAAc,CAAC,aAAqB,EAAE,aAAqB,EAAU;IACpF,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,aAAa,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAAA,CACpE;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,kBAAkB,CACjC,KAAmB,EACnB,cAA8B,EAC9B,iBAAiB,GAAwB,IAAI,GAAG,EAAE,EAC5C;IACN,MAAM,UAAU,GAAqB,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACzD,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,QAAQ,EAAE;YACT,OAAO,EAAE;gBACR,WAAW,EACV,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,kBAAkB,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,WAAW;aACvG;SACD;KACD,CAAC,CAAC,CAAC;IACJ,MAAM,SAAS,GAAG,mBAAmB,CAAC,UAAU,CAAC,CAAC;IAClD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;AAAA,CAC1F;AAED,MAAM,sBAAsB,GAAG,IAAI,OAAO,EAAY,CAAC;AAEvD,mGAAmG;AACnG,MAAM,UAAU,uBAAuB,CAAC,cAAwB,EAAW;IAC1E,OAAO,cAAc,KAAK,YAAY,IAAI,sBAAsB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;AAAA,CACrF;AAiBD;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAAY,EAAE,OAA+B,EAAQ;IAC3F,MAAM,EAAE,cAAc,EAAE,cAAc,EAAE,SAAS,EAAE,iBAAiB,GAAG,IAAI,GAAG,EAAU,EAAE,GAAG,OAAO,CAAC;IAErG,MAAM,wBAAwB,GAAG,KAAK,CAAC,gBAAgB,CAAC;IACxD,KAAK,CAAC,gBAAgB,GAAG,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC;QACpD,MAAM,aAAa,GAAG,wBAAwB,CAAC,CAAC,CAAC,MAAM,wBAAwB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;QAC7G,OAAO,gBAAgB,CAAC,aAAa,EAAE,cAAc,EAAE,SAAS,EAAE,CAAC,CAAC;IAAA,CACpE,CAAC;IAEF,MAAM,sBAAsB,GAAG,KAAK,CAAC,cAAc,CAAC;IACpD,MAAM,qBAAqB,GAAG,CAC7B,KAAmD,EACnD,OAAqD,EACrD,aAA2D,EAC1D,EAAE,CAAC;QACJ,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClD,OAAO,sBAAsB,CAAC,KAAK,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;QAC9D,CAAC;QACD,OAAO,sBAAsB,CAC5B,KAAK,EACL,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,kBAAkB,CAAC,OAAO,CAAC,KAAK,EAAE,cAAc,EAAE,iBAAiB,CAAC,EAAE,EAC3F,aAAa,CACb,CAAC;IAAA,CACF,CAAC;IACF,IAAI,uBAAuB,CAAC,sBAAsB,CAAC;QAAE,sBAAsB,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;IACvG,KAAK,CAAC,cAAc,GAAG,qBAAqB,CAAC;AAAA,CAC7C","sourcesContent":["/**\n * Context pipeline wiring — shared by `AgentSession` (production) and the offline\n * replay harness (`src/testing/replay/runner.ts`), so there is exactly one\n * implementation of \"how deferred-schema resolution and eviction attach to an\n * `Agent`\" rather than two independently maintained copies.\n *\n * Implements the ordering settled in `docs/architecture/contracts.md` § 2:\n * deferred-schema resolution → tool-result eviction → compaction. Compaction runs\n * reactively from its own existing seam (`_checkCompaction` in `agent-session.ts`)\n * and is untouched here; this module only adds the two stages that run *ahead of*\n * every LLM request, so that reactive check is reached less often because the\n * request it is reacting to is smaller.\n *\n * The two stages land in different seams because they operate on different halves\n * of the outbound request. Eviction is a pure function of `AgentMessage[]`, which is\n * exactly what `transformContext` sees, immediately before `convertToLlm` — so it is\n * wired there. Deferred-schema resolution operates on the *tool list*, not messages;\n * `transformContext`'s signature has no tools parameter, and `AgentContext.tools` is\n * a snapshot taken once per prompt rather than rebuilt per request. The seam that\n * actually sees the assembled outbound tool list on every request is\n * `streamFunction` — it receives the full `Context`, tools included, immediately\n * before the provider call — so the projection is applied there instead. Because the\n * two stages act on disjoint fields of the request with no data dependency between\n * them, this does not change the observable pipeline order.\n */\n\nimport { streamSimple } from \"@earendil-works/pi-ai/compat\";\nimport type { Agent, StreamFn } from \"apex-code-agent-core\";\nimport { resolveToolContext } from \"../tools/contract.ts\";\nimport { announceToolsByName, type DeferrableTool } from \"./deferred-schemas.ts\";\nimport { type ContractLookup, evictToolResults } from \"./eviction.ts\";\n\n/**\n * Eviction-budget formula shared by every caller of `installContextPipeline`.\n * Compaction fires once total context tokens exceed `contextWindow - reserveTokens`\n * (`shouldCompact` in `core/compaction/compaction.ts`). Budgeting eviction — counted\n * purely against tool-result tokens, per `evictToolResults`'s own contract — at half\n * of that headroom leaves the other half free for system prompt and conversational\n * growth, so eviction (cheap, structure-preserving) gets a chance to shrink the\n * transcript before the expensive compaction stage is ever reached, matching\n * contracts.md § 2's \"why this order\" (eviction before compaction, so compaction is\n * reached later and less often).\n *\n * `Math.max(0, ...)` mirrors `shouldCompact`'s own behavior when `contextWindow` is\n * unknown (0): evict aggressively rather than not at all, rather than inventing a\n * different, unproven fallback.\n *\n * Production (`AgentSession`) calls this with the real model's `contextWindow` and\n * the user's configured `reserveTokens`. The offline replay harness deliberately\n * does *not* call this with the fixture model's `contextWindow` — see\n * `REPLAY_EVICTION_BUDGET` in `src/testing/replay/runner.ts` for why a dedicated\n * constant is used there instead.\n */\nexport function evictionBudget(contextWindow: number, reserveTokens: number): number {\n\treturn Math.max(0, Math.floor((contextWindow - reserveTokens) / 2));\n}\n\n/**\n * Adapter between a caller's tool registry and `announceToolsByName`, which\n * operates on a minimal `DeferrableTool` shape that has no notion of a tool\n * registry. Only `parameters` is ever replaced; every other field of the outbound\n * tool (name, description, and on `AgentTool` specifically, `execute`, `label`,\n * etc.) passes through unchanged via the object spread.\n *\n * A tool with no entry in `contractLookup` (a foreign/unclassified tool) is treated\n * as `deferSchema: false` here — the safe default on this axis is to keep\n * describing it fully, the mirror image of eviction's \"no contract => don't evict\"\n * default: when unsure, don't withhold information the model needs.\n */\nexport function projectToolSchemas<T extends { name: string; description: string; parameters: unknown }>(\n\ttools: readonly T[],\n\tcontractLookup: ContractLookup,\n\tloadedSchemaNames: ReadonlySet<string> = new Set(),\n): T[] {\n\tconst deferrable: DeferrableTool[] = tools.map((tool) => ({\n\t\tname: tool.name,\n\t\tdescription: tool.description,\n\t\tparameters: tool.parameters,\n\t\tcontract: {\n\t\t\tcontext: {\n\t\t\t\tdeferSchema:\n\t\t\t\t\t!loadedSchemaNames.has(tool.name) && resolveToolContext(contractLookup, tool.name).context.deferSchema,\n\t\t\t},\n\t\t},\n\t}));\n\tconst announced = announceToolsByName(deferrable);\n\treturn tools.map((tool, index) => ({ ...tool, parameters: announced[index].parameters }));\n}\n\nconst defaultStreamFunctions = new WeakSet<StreamFn>();\n\n/** Returns true for the built-in streamSimple function, including its context-pipeline wrapper. */\nexport function isDefaultStreamFunction(streamFunction: StreamFn): boolean {\n\treturn streamFunction === streamSimple || defaultStreamFunctions.has(streamFunction);\n}\n\nexport interface ContextPipelineOptions {\n\t/** Resolves a tool's contract; shared by both eviction and schema projection. */\n\tcontractLookup: ContractLookup;\n\t/** Names whose real schemas have been loaded by the model in this session. */\n\tloadedSchemaNames?: ReadonlySet<string>;\n\t/**\n\t * Eviction budget as a thunk, not a plain number: `AgentSession`'s budget\n\t * depends on `this.model` and `this.settingsManager`, both of which can change\n\t * over the session's lifetime (model switch, settings edit), and is never\n\t * cached. Evaluating it fresh on every request is what keeps eviction correct\n\t * after either changes mid-session.\n\t */\n\tevictionBudget: () => number;\n}\n\n/**\n * Installs the settled context pipeline (deferred-schema resolution → eviction)\n * onto `agent`, chaining onto whatever `transformContext` / `streamFunction` the\n * caller already installed rather than replacing it — the same pattern\n * `AgentSession._installAgentNextTurnRefresh` uses for `prepareNextTurnWithContext`.\n */\nexport function installContextPipeline(agent: Agent, options: ContextPipelineOptions): void {\n\tconst { contractLookup, evictionBudget: getBudget, loadedSchemaNames = new Set<string>() } = options;\n\n\tconst previousTransformContext = agent.transformContext;\n\tagent.transformContext = async (messages, signal) => {\n\t\tconst afterPrevious = previousTransformContext ? await previousTransformContext(messages, signal) : messages;\n\t\treturn evictToolResults(afterPrevious, contractLookup, getBudget());\n\t};\n\n\tconst previousStreamFunction = agent.streamFunction;\n\tconst wrappedStreamFunction = (\n\t\tmodel: Parameters<typeof previousStreamFunction>[0],\n\t\tcontext: Parameters<typeof previousStreamFunction>[1],\n\t\tstreamOptions: Parameters<typeof previousStreamFunction>[2],\n\t) => {\n\t\tif (!context.tools || context.tools.length === 0) {\n\t\t\treturn previousStreamFunction(model, context, streamOptions);\n\t\t}\n\t\treturn previousStreamFunction(\n\t\t\tmodel,\n\t\t\t{ ...context, tools: projectToolSchemas(context.tools, contractLookup, loadedSchemaNames) },\n\t\t\tstreamOptions,\n\t\t);\n\t};\n\tif (isDefaultStreamFunction(previousStreamFunction)) defaultStreamFunctions.add(wrappedStreamFunction);\n\tagent.streamFunction = wrappedStreamFunction;\n}\n"]}
|