@google/gemini-cli-core 0.42.0-preview.1 → 0.43.0-preview.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/docs/changelogs/index.md +14 -0
- package/dist/docs/changelogs/latest.md +108 -166
- package/dist/docs/changelogs/preview.md +227 -103
- package/dist/docs/cli/auto-memory.md +60 -38
- package/dist/docs/cli/settings.md +1 -1
- package/dist/docs/cli/tutorials/memory-management.md +1 -1
- package/dist/docs/extensions/releasing.md +58 -24
- package/dist/docs/reference/configuration.md +14 -1
- package/dist/docs/reference/keyboard-shortcuts.md +23 -0
- package/dist/src/agent/content-utils.js +2 -0
- package/dist/src/agent/content-utils.js.map +1 -1
- package/dist/src/agent/content-utils.test.js +5 -1
- package/dist/src/agent/content-utils.test.js.map +1 -1
- package/dist/src/agent/event-translator.js +7 -6
- package/dist/src/agent/event-translator.js.map +1 -1
- package/dist/src/agent/legacy-agent-session.js +4 -0
- package/dist/src/agent/legacy-agent-session.js.map +1 -1
- package/dist/src/agent/legacy-agent-session.test.js +9 -1
- package/dist/src/agent/legacy-agent-session.test.js.map +1 -1
- package/dist/src/agent/tool-display-utils.d.ts +3 -2
- package/dist/src/agent/tool-display-utils.js +3 -2
- package/dist/src/agent/tool-display-utils.js.map +1 -1
- package/dist/src/agent/types.d.ts +33 -3
- package/dist/src/agents/a2aUtils.d.ts +1 -1
- package/dist/src/agents/a2aUtils.js +4 -3
- package/dist/src/agents/a2aUtils.js.map +1 -1
- package/dist/src/agents/agentLoader.d.ts +2 -2
- package/dist/src/agents/browser/browserAgentInvocation.js +24 -19
- package/dist/src/agents/browser/browserAgentInvocation.js.map +1 -1
- package/dist/src/agents/local-executor.d.ts +1 -0
- package/dist/src/agents/local-executor.js +46 -32
- package/dist/src/agents/local-executor.js.map +1 -1
- package/dist/src/agents/local-executor.test.js +127 -0
- package/dist/src/agents/local-executor.test.js.map +1 -1
- package/dist/src/agents/local-invocation.js +24 -20
- package/dist/src/agents/local-invocation.js.map +1 -1
- package/dist/src/agents/local-invocation.test.js +9 -9
- package/dist/src/agents/local-invocation.test.js.map +1 -1
- package/dist/src/agents/local-subagent-protocol.d.ts +18 -0
- package/dist/src/agents/local-subagent-protocol.js +357 -0
- package/dist/src/agents/local-subagent-protocol.js.map +1 -0
- package/dist/src/agents/local-subagent-protocol.test.d.ts +6 -0
- package/dist/src/agents/local-subagent-protocol.test.js +676 -0
- package/dist/src/agents/local-subagent-protocol.test.js.map +1 -0
- package/dist/src/agents/remote-invocation.js +6 -6
- package/dist/src/agents/remote-invocation.js.map +1 -1
- package/dist/src/agents/remote-invocation.test.js +23 -12
- package/dist/src/agents/remote-invocation.test.js.map +1 -1
- package/dist/src/agents/remote-subagent-protocol.d.ts +31 -0
- package/dist/src/agents/remote-subagent-protocol.js +330 -0
- package/dist/src/agents/remote-subagent-protocol.js.map +1 -0
- package/dist/src/agents/remote-subagent-protocol.test.d.ts +6 -0
- package/dist/src/agents/remote-subagent-protocol.test.js +652 -0
- package/dist/src/agents/remote-subagent-protocol.test.js.map +1 -0
- package/dist/src/agents/skill-extraction-agent.js +1 -0
- package/dist/src/agents/skill-extraction-agent.js.map +1 -1
- package/dist/src/agents/skill-extraction-agent.test.js +1 -0
- package/dist/src/agents/skill-extraction-agent.test.js.map +1 -1
- package/dist/src/agents/types.d.ts +13 -2
- package/dist/src/agents/types.js +7 -0
- package/dist/src/agents/types.js.map +1 -1
- package/dist/src/availability/modelAvailabilityService.d.ts +6 -6
- package/dist/src/availability/modelAvailabilityService.js +14 -7
- package/dist/src/availability/modelAvailabilityService.js.map +1 -1
- package/dist/src/availability/modelAvailabilityService.test.js +34 -0
- package/dist/src/availability/modelAvailabilityService.test.js.map +1 -1
- package/dist/src/availability/policyHelpers.js +24 -12
- package/dist/src/availability/policyHelpers.js.map +1 -1
- package/dist/src/availability/policyHelpers.test.js +3 -2
- package/dist/src/availability/policyHelpers.test.js.map +1 -1
- package/dist/src/code_assist/oauth2.js +3 -0
- package/dist/src/code_assist/oauth2.js.map +1 -1
- package/dist/src/code_assist/setup.d.ts +3 -0
- package/dist/src/code_assist/setup.js +9 -0
- package/dist/src/code_assist/setup.js.map +1 -1
- package/dist/src/code_assist/setup.test.js +9 -1
- package/dist/src/code_assist/setup.test.js.map +1 -1
- package/dist/src/commands/memory.d.ts +5 -14
- package/dist/src/commands/memory.js +19 -141
- package/dist/src/commands/memory.js.map +1 -1
- package/dist/src/commands/memory.test.js +62 -0
- package/dist/src/commands/memory.test.js.map +1 -1
- package/dist/src/config/config.d.ts +6 -2
- package/dist/src/config/config.js +63 -8
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.test.js +48 -0
- package/dist/src/config/config.test.js.map +1 -1
- package/dist/src/config/defaultModelConfigs.js +13 -0
- package/dist/src/config/defaultModelConfigs.js.map +1 -1
- package/dist/src/config/models.js +1 -1
- package/dist/src/config/models.js.map +1 -1
- package/dist/src/config/projectRegistry.d.ts +1 -0
- package/dist/src/config/projectRegistry.js +13 -2
- package/dist/src/config/projectRegistry.js.map +1 -1
- package/dist/src/config/projectRegistry.test.js +43 -0
- package/dist/src/config/projectRegistry.test.js.map +1 -1
- package/dist/src/context/config/profiles.js +4 -0
- package/dist/src/context/config/profiles.js.map +1 -1
- package/dist/src/context/contextManager.barrier.test.js +4 -3
- package/dist/src/context/contextManager.barrier.test.js.map +1 -1
- package/dist/src/context/contextManager.d.ts +9 -2
- package/dist/src/context/contextManager.hotstart.test.d.ts +6 -0
- package/dist/src/context/contextManager.hotstart.test.js +61 -0
- package/dist/src/context/contextManager.hotstart.test.js.map +1 -0
- package/dist/src/context/contextManager.js +96 -21
- package/dist/src/context/contextManager.js.map +1 -1
- package/dist/src/context/eventBus.d.ts +6 -0
- package/dist/src/context/eventBus.js +6 -0
- package/dist/src/context/eventBus.js.map +1 -1
- package/dist/src/context/graph/render.d.ts +3 -1
- package/dist/src/context/graph/render.js +33 -9
- package/dist/src/context/graph/render.js.map +1 -1
- package/dist/src/context/graph/render.test.d.ts +6 -0
- package/dist/src/context/graph/render.test.js +203 -0
- package/dist/src/context/graph/render.test.js.map +1 -0
- package/dist/src/context/graph/toGraph.js +3 -3
- package/dist/src/context/graph/toGraph.js.map +1 -1
- package/dist/src/context/graph/toGraph.test.d.ts +6 -0
- package/dist/src/context/graph/toGraph.test.js +35 -0
- package/dist/src/context/graph/toGraph.test.js.map +1 -0
- package/dist/src/context/initializer.js +11 -2
- package/dist/src/context/initializer.js.map +1 -1
- package/dist/src/context/pipeline/contextWorkingBuffer.d.ts +5 -7
- package/dist/src/context/pipeline/contextWorkingBuffer.js +105 -29
- package/dist/src/context/pipeline/contextWorkingBuffer.js.map +1 -1
- package/dist/src/context/pipeline/contextWorkingBuffer.test.js +67 -0
- package/dist/src/context/pipeline/contextWorkingBuffer.test.js.map +1 -1
- package/dist/src/context/pipeline/environment.d.ts +4 -0
- package/dist/src/context/pipeline/environmentImpl.d.ts +6 -5
- package/dist/src/context/pipeline/environmentImpl.js +6 -8
- package/dist/src/context/pipeline/environmentImpl.js.map +1 -1
- package/dist/src/context/pipeline/environmentImpl.test.js +5 -1
- package/dist/src/context/pipeline/environmentImpl.test.js.map +1 -1
- package/dist/src/context/pipeline/orchestrator.d.ts +1 -0
- package/dist/src/context/pipeline/orchestrator.js +59 -24
- package/dist/src/context/pipeline/orchestrator.js.map +1 -1
- package/dist/src/context/processors/blobDegradationProcessor.test.js +2 -2
- package/dist/src/context/processors/rollingSummaryProcessor.js +2 -15
- package/dist/src/context/processors/rollingSummaryProcessor.js.map +1 -1
- package/dist/src/context/processors/stateSnapshotAsyncProcessor.d.ts +7 -0
- package/dist/src/context/processors/stateSnapshotAsyncProcessor.js +33 -21
- package/dist/src/context/processors/stateSnapshotAsyncProcessor.js.map +1 -1
- package/dist/src/context/processors/stateSnapshotAsyncProcessor.test.js +31 -7
- package/dist/src/context/processors/stateSnapshotAsyncProcessor.test.js.map +1 -1
- package/dist/src/context/processors/stateSnapshotProcessor.d.ts +2 -0
- package/dist/src/context/processors/stateSnapshotProcessor.js +28 -4
- package/dist/src/context/processors/stateSnapshotProcessor.js.map +1 -1
- package/dist/src/context/processors/stateSnapshotProcessor.test.js +40 -1
- package/dist/src/context/processors/stateSnapshotProcessor.test.js.map +1 -1
- package/dist/src/context/system-tests/hysteresis.test.d.ts +6 -0
- package/dist/src/context/system-tests/hysteresis.test.js +98 -0
- package/dist/src/context/system-tests/hysteresis.test.js.map +1 -0
- package/dist/src/context/system-tests/lifecycle.golden.test.js +90 -69
- package/dist/src/context/system-tests/lifecycle.golden.test.js.map +1 -1
- package/dist/src/context/system-tests/simulationHarness.d.ts +1 -4
- package/dist/src/context/system-tests/simulationHarness.js +16 -30
- package/dist/src/context/system-tests/simulationHarness.js.map +1 -1
- package/dist/src/context/testing/contextTestUtils.d.ts +1 -0
- package/dist/src/context/testing/contextTestUtils.js +48 -25
- package/dist/src/context/testing/contextTestUtils.js.map +1 -1
- package/dist/src/context/utils/adaptiveTokenCalculator.d.ts +61 -0
- package/dist/src/context/utils/adaptiveTokenCalculator.js +116 -0
- package/dist/src/context/utils/adaptiveTokenCalculator.js.map +1 -0
- package/dist/src/context/utils/adaptiveTokenCalculator.test.d.ts +6 -0
- package/dist/src/context/utils/adaptiveTokenCalculator.test.js +85 -0
- package/dist/src/context/utils/adaptiveTokenCalculator.test.js.map +1 -0
- package/dist/src/context/utils/contextTokenCalculator.d.ts +47 -1
- package/dist/src/context/utils/contextTokenCalculator.js +20 -3
- package/dist/src/context/utils/contextTokenCalculator.js.map +1 -1
- package/dist/src/context/utils/contextTokenCalculator.test.js +8 -8
- package/dist/src/context/utils/contextTokenCalculator.test.js.map +1 -1
- package/dist/src/context/utils/formatNodesForLlm.d.ts +21 -0
- package/dist/src/context/utils/formatNodesForLlm.js +69 -0
- package/dist/src/context/utils/formatNodesForLlm.js.map +1 -0
- package/dist/src/context/utils/formatNodesForLlm.test.d.ts +6 -0
- package/dist/src/context/utils/formatNodesForLlm.test.js +110 -0
- package/dist/src/context/utils/formatNodesForLlm.test.js.map +1 -0
- package/dist/src/context/utils/snapshotGenerator.d.ts +23 -1
- package/dist/src/context/utils/snapshotGenerator.js +249 -31
- package/dist/src/context/utils/snapshotGenerator.js.map +1 -1
- package/dist/src/context/utils/snapshotGenerator.test.d.ts +6 -0
- package/dist/src/context/utils/snapshotGenerator.test.js +255 -0
- package/dist/src/context/utils/snapshotGenerator.test.js.map +1 -0
- package/dist/src/context/utils/tokenCalibration.d.ts +9 -0
- package/dist/src/context/utils/tokenCalibration.js +30 -0
- package/dist/src/context/utils/tokenCalibration.js.map +1 -0
- package/dist/src/core/baseLlmClient.d.ts +8 -0
- package/dist/src/core/baseLlmClient.js +14 -0
- package/dist/src/core/baseLlmClient.js.map +1 -1
- package/dist/src/core/client.js +12 -1
- package/dist/src/core/client.js.map +1 -1
- package/dist/src/core/client.test.js +4 -4
- package/dist/src/core/contentGenerator.js +12 -10
- package/dist/src/core/contentGenerator.js.map +1 -1
- package/dist/src/core/geminiChat.d.ts +2 -0
- package/dist/src/core/geminiChat.js +60 -5
- package/dist/src/core/geminiChat.js.map +1 -1
- package/dist/src/core/geminiChat.test.js +195 -2
- package/dist/src/core/geminiChat.test.js.map +1 -1
- package/dist/src/core/turn.js +30 -2
- package/dist/src/core/turn.js.map +1 -1
- package/dist/src/core/turn.test.js +13 -8
- package/dist/src/core/turn.test.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +2 -2
- package/dist/src/generated/git-commit.js +2 -2
- package/dist/src/hooks/hookEventHandler.js +3 -2
- package/dist/src/hooks/hookEventHandler.js.map +1 -1
- package/dist/src/hooks/hookEventHandler.test.js +80 -0
- package/dist/src/hooks/hookEventHandler.test.js.map +1 -1
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.js +2 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/prompts/snippets.js +1 -1
- package/dist/src/prompts/snippets.js.map +1 -1
- package/dist/src/routing/strategies/approvalModeStrategy.js +5 -3
- package/dist/src/routing/strategies/approvalModeStrategy.js.map +1 -1
- package/dist/src/routing/strategies/approvalModeStrategy.test.js +2 -0
- package/dist/src/routing/strategies/approvalModeStrategy.test.js.map +1 -1
- package/dist/src/routing/strategies/classifierStrategy.js +8 -1
- package/dist/src/routing/strategies/classifierStrategy.js.map +1 -1
- package/dist/src/routing/strategies/classifierStrategy.test.js +4 -0
- package/dist/src/routing/strategies/classifierStrategy.test.js.map +1 -1
- package/dist/src/routing/strategies/gemmaClassifierStrategy.js +7 -1
- package/dist/src/routing/strategies/gemmaClassifierStrategy.js.map +1 -1
- package/dist/src/routing/strategies/gemmaClassifierStrategy.test.js +4 -0
- package/dist/src/routing/strategies/gemmaClassifierStrategy.test.js.map +1 -1
- package/dist/src/routing/strategies/numericalClassifierStrategy.d.ts +1 -0
- package/dist/src/routing/strategies/numericalClassifierStrategy.js +22 -3
- package/dist/src/routing/strategies/numericalClassifierStrategy.js.map +1 -1
- package/dist/src/routing/strategies/numericalClassifierStrategy.test.js +168 -23
- package/dist/src/routing/strategies/numericalClassifierStrategy.test.js.map +1 -1
- package/dist/src/scheduler/scheduler.js +11 -0
- package/dist/src/scheduler/scheduler.js.map +1 -1
- package/dist/src/scheduler/scheduler.test.js +1 -1
- package/dist/src/scheduler/scheduler.test.js.map +1 -1
- package/dist/src/scheduler/state-manager.js +5 -1
- package/dist/src/scheduler/state-manager.js.map +1 -1
- package/dist/src/scheduler/tool-executor.js +7 -4
- package/dist/src/scheduler/tool-executor.js.map +1 -1
- package/dist/src/scheduler/types.d.ts +5 -1
- package/dist/src/scheduler/types.js.map +1 -1
- package/dist/src/services/fileDiscoveryService.js +2 -1
- package/dist/src/services/fileDiscoveryService.js.map +1 -1
- package/dist/src/services/fileDiscoveryService.test.js +36 -0
- package/dist/src/services/fileDiscoveryService.test.js.map +1 -1
- package/dist/src/services/gitService.js +8 -1
- package/dist/src/services/gitService.js.map +1 -1
- package/dist/src/services/gitService.test.js +104 -0
- package/dist/src/services/gitService.test.js.map +1 -1
- package/dist/src/services/keychainService.js +14 -5
- package/dist/src/services/keychainService.js.map +1 -1
- package/dist/src/services/memoryPatchUtils.d.ts +66 -4
- package/dist/src/services/memoryPatchUtils.js +267 -5
- package/dist/src/services/memoryPatchUtils.js.map +1 -1
- package/dist/src/services/memoryService.js +25 -1
- package/dist/src/services/memoryService.js.map +1 -1
- package/dist/src/services/memoryService.test.js +61 -1
- package/dist/src/services/memoryService.test.js.map +1 -1
- package/dist/src/services/test-data/resolved-aliases-retry.golden.json +11 -0
- package/dist/src/services/test-data/resolved-aliases.golden.json +11 -0
- package/dist/src/telemetry/gcp-exporters.d.ts +2 -0
- package/dist/src/telemetry/gcp-exporters.js +69 -5
- package/dist/src/telemetry/gcp-exporters.js.map +1 -1
- package/dist/src/telemetry/gcp-exporters.test.js +52 -0
- package/dist/src/telemetry/gcp-exporters.test.js.map +1 -1
- package/dist/src/telemetry/metrics.js +13 -2
- package/dist/src/telemetry/metrics.js.map +1 -1
- package/dist/src/telemetry/metrics.test.js +61 -1
- package/dist/src/telemetry/metrics.test.js.map +1 -1
- package/dist/src/tools/definitions/model-family-sets/default-legacy.js +5 -2
- package/dist/src/tools/definitions/model-family-sets/default-legacy.js.map +1 -1
- package/dist/src/tools/definitions/model-family-sets/gemini-3.js +7 -4
- package/dist/src/tools/definitions/model-family-sets/gemini-3.js.map +1 -1
- package/dist/src/tools/edit.js +19 -0
- package/dist/src/tools/edit.js.map +1 -1
- package/dist/src/tools/edit.test.js +9 -0
- package/dist/src/tools/edit.test.js.map +1 -1
- package/dist/src/tools/grep.js +13 -1
- package/dist/src/tools/grep.js.map +1 -1
- package/dist/src/tools/ls.js +5 -0
- package/dist/src/tools/ls.js.map +1 -1
- package/dist/src/tools/mcp-client.js +17 -3
- package/dist/src/tools/mcp-client.js.map +1 -1
- package/dist/src/tools/mcp-client.test.js +24 -0
- package/dist/src/tools/mcp-client.test.js.map +1 -1
- package/dist/src/tools/read-file.js +11 -6
- package/dist/src/tools/read-file.js.map +1 -1
- package/dist/src/tools/read-file.test.js +20 -8
- package/dist/src/tools/read-file.test.js.map +1 -1
- package/dist/src/tools/ripGrep.js +13 -1
- package/dist/src/tools/ripGrep.js.map +1 -1
- package/dist/src/tools/shell.js +14 -0
- package/dist/src/tools/shell.js.map +1 -1
- package/dist/src/tools/shell.test.js +5 -0
- package/dist/src/tools/shell.test.js.map +1 -1
- package/dist/src/tools/tools.d.ts +6 -0
- package/dist/src/tools/tools.js.map +1 -1
- package/dist/src/tools/topicTool.js +5 -0
- package/dist/src/tools/topicTool.js.map +1 -1
- package/dist/src/tools/write-file.js +13 -0
- package/dist/src/tools/write-file.js.map +1 -1
- package/dist/src/tools/write-file.test.js +8 -0
- package/dist/src/tools/write-file.test.js.map +1 -1
- package/dist/src/utils/errors.js +3 -8
- package/dist/src/utils/errors.js.map +1 -1
- package/dist/src/utils/filesearch/ignore.js +4 -1
- package/dist/src/utils/filesearch/ignore.js.map +1 -1
- package/dist/src/utils/ignoreFileParser.js +1 -1
- package/dist/src/utils/ignoreFileParser.js.map +1 -1
- package/dist/src/utils/ignorePatterns.js +2 -0
- package/dist/src/utils/ignorePatterns.js.map +1 -1
- package/dist/src/utils/ignorePatterns.test.js +1 -0
- package/dist/src/utils/ignorePatterns.test.js.map +1 -1
- package/dist/src/utils/memoryDiscovery.js +55 -40
- package/dist/src/utils/memoryDiscovery.js.map +1 -1
- package/dist/src/utils/memoryDiscovery.test.js +77 -9
- package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
- package/dist/src/utils/modelUtils.d.ts +14 -0
- package/dist/src/utils/modelUtils.js +17 -0
- package/dist/src/utils/modelUtils.js.map +1 -0
- package/dist/src/utils/modelUtils.test.d.ts +6 -0
- package/dist/src/utils/modelUtils.test.js +23 -0
- package/dist/src/utils/modelUtils.test.js.map +1 -0
- package/dist/src/utils/paths.d.ts +15 -1
- package/dist/src/utils/paths.js +22 -7
- package/dist/src/utils/paths.js.map +1 -1
- package/dist/src/utils/paths.test.js +25 -1
- package/dist/src/utils/paths.test.js.map +1 -1
- package/dist/src/utils/quotaErrorDetection.js +23 -12
- package/dist/src/utils/quotaErrorDetection.js.map +1 -1
- package/dist/src/utils/shell-utils.js +9 -1
- package/dist/src/utils/shell-utils.js.map +1 -1
- package/dist/src/utils/shell-utils.test.js +7 -3
- package/dist/src/utils/shell-utils.test.js.map +1 -1
- package/dist/src/utils/tokenCalculation.js +2 -1
- package/dist/src/utils/tokenCalculation.js.map +1 -1
- package/dist/src/utils/tokenCalculation.test.js +15 -0
- package/dist/src/utils/tokenCalculation.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/dist/google-gemini-cli-core-0.42.0-preview.0.tgz +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stateSnapshotProcessor.test.js","sourceRoot":"","sources":["../../../../src/context/processors/stateSnapshotProcessor.test.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"stateSnapshotProcessor.test.js","sourceRoot":"","sources":["../../../../src/context/processors/stateSnapshotProcessor.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect } from 'vitest';
|
|
7
|
+
import { SimulationHarness } from './simulationHarness.js';
|
|
8
|
+
import { createMockLlmClient } from '../testing/contextTestUtils.js';
|
|
9
|
+
import { generalistProfile } from '../config/profiles.js';
|
|
10
|
+
describe('Context Manager Hysteresis Tests', () => {
|
|
11
|
+
const mockLlmClient = createMockLlmClient(['<SNAPSHOT>']);
|
|
12
|
+
const getHysteresisConfig = (threshold) => ({
|
|
13
|
+
...generalistProfile,
|
|
14
|
+
name: 'Hysteresis Stress Test',
|
|
15
|
+
config: {
|
|
16
|
+
budget: {
|
|
17
|
+
maxTokens: 5000,
|
|
18
|
+
retainedTokens: 1000,
|
|
19
|
+
coalescingThresholdTokens: threshold,
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
const getProjectionTokens = (proj, harness) => proj.reduce((sum, c) => sum + harness.env.tokenCalculator.calculateContentTokens(c), 0);
|
|
24
|
+
it('should block consolidation when deficit is below coalescing threshold', async () => {
|
|
25
|
+
const threshold = 1500;
|
|
26
|
+
const harness = await SimulationHarness.create(getHysteresisConfig(threshold), mockLlmClient);
|
|
27
|
+
// Turn 0: INIT
|
|
28
|
+
await harness.simulateTurn([{ role: 'user', parts: [{ text: 'INIT' }] }]);
|
|
29
|
+
// Turn 1: Add ~500 tokens
|
|
30
|
+
await harness.simulateTurn([
|
|
31
|
+
{ role: 'user', parts: [{ text: 'A'.repeat(500) }] },
|
|
32
|
+
]);
|
|
33
|
+
// Turn 2: Add ~1000 tokens. Total ~1500. Deficit ~500 < 1500.
|
|
34
|
+
await harness.simulateTurn([
|
|
35
|
+
{ role: 'user', parts: [{ text: 'B'.repeat(1000) }] },
|
|
36
|
+
]);
|
|
37
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
38
|
+
let state = await harness.getGoldenState();
|
|
39
|
+
// No snapshot because maxTokens (5000) not exceeded, and deficit < threshold.
|
|
40
|
+
expect(state.finalProjection.some((c) => c.parts?.some((p) => p.text?.includes('<SNAPSHOT>')))).toBe(false);
|
|
41
|
+
// Turn 3: Add ~3000 tokens. Total ~4500.
|
|
42
|
+
// Deficit ~3500 > 1500. TRIGGER!
|
|
43
|
+
await harness.simulateTurn([
|
|
44
|
+
{ role: 'user', parts: [{ text: 'C'.repeat(3000) }] },
|
|
45
|
+
]);
|
|
46
|
+
// Give it a moment for the async task to finish
|
|
47
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
48
|
+
// Exceed maxTokens to force a render that shows the snapshot
|
|
49
|
+
// Add ~3000 tokens. Total ~7500 > 5000.
|
|
50
|
+
await harness.simulateTurn([
|
|
51
|
+
{ role: 'user', parts: [{ text: 'D'.repeat(3000) }] },
|
|
52
|
+
]);
|
|
53
|
+
state = await harness.getGoldenState();
|
|
54
|
+
expect(state.finalProjection.some((c) => c.parts?.some((p) => p.text?.includes('<SNAPSHOT>')))).toBe(true);
|
|
55
|
+
});
|
|
56
|
+
it('should track growth from the new baseline after consolidation', async () => {
|
|
57
|
+
const threshold = 1000;
|
|
58
|
+
const harness = await SimulationHarness.create(getHysteresisConfig(threshold), mockLlmClient);
|
|
59
|
+
// 1. Trigger first consolidation
|
|
60
|
+
// Add ~3000 tokens. Total ~3000. Deficit ~2000 > 1000.
|
|
61
|
+
await harness.simulateTurn([
|
|
62
|
+
{ role: 'user', parts: [{ text: 'A'.repeat(3000) }] },
|
|
63
|
+
]);
|
|
64
|
+
await harness.simulateTurn([{ role: 'user', parts: [{ text: 'B' }] }]); // Make eligible
|
|
65
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
66
|
+
// Exceed maxTokens (5000) to see it
|
|
67
|
+
await harness.simulateTurn([
|
|
68
|
+
{ role: 'user', parts: [{ text: 'X'.repeat(3000) }] },
|
|
69
|
+
]);
|
|
70
|
+
// Get baseline tokens
|
|
71
|
+
let state = await harness.getGoldenState();
|
|
72
|
+
expect(state.finalProjection.some((c) => c.parts?.some((p) => p.text?.includes('<SNAPSHOT>')))).toBe(true);
|
|
73
|
+
const baselineTokens = getProjectionTokens(state.finalProjection, harness);
|
|
74
|
+
// 2. Add nodes again, staying below threshold growth
|
|
75
|
+
// Add ~500 tokens. Growth ~500 < 1000.
|
|
76
|
+
await harness.simulateTurn([
|
|
77
|
+
{ role: 'user', parts: [{ text: 'C'.repeat(500) }] },
|
|
78
|
+
]);
|
|
79
|
+
await harness.simulateTurn([{ role: 'user', parts: [{ text: 'D' }] }]); // Make eligible
|
|
80
|
+
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
81
|
+
state = await harness.getGoldenState();
|
|
82
|
+
const currentTokens = getProjectionTokens(state.finalProjection, harness);
|
|
83
|
+
// Should not have shrunk further (except for D's small addition)
|
|
84
|
+
expect(currentTokens).toBeGreaterThanOrEqual(baselineTokens);
|
|
85
|
+
// 3. Exceed threshold growth
|
|
86
|
+
// Add ~2000 tokens. Growth = ~500 + ~2000 = ~2500 > 1000.
|
|
87
|
+
await harness.simulateTurn([
|
|
88
|
+
{ role: 'user', parts: [{ text: 'E'.repeat(2000) }] },
|
|
89
|
+
]);
|
|
90
|
+
await harness.simulateTurn([{ role: 'user', parts: [{ text: 'F' }] }]); // Make eligible
|
|
91
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
92
|
+
state = await harness.getGoldenState();
|
|
93
|
+
const finalTokens = getProjectionTokens(state.finalProjection, harness);
|
|
94
|
+
// Now it should have consolidated again (E should be replaced by a snapshot eventually)
|
|
95
|
+
expect(finalTokens).toBeLessThan(currentTokens + 2000);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
//# sourceMappingURL=hysteresis.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hysteresis.test.js","sourceRoot":"","sources":["../../../../src/context/system-tests/hysteresis.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,11 +7,7 @@ import { describe, it, expect, vi, beforeAll, afterAll } from 'vitest';
|
|
|
7
7
|
import fs from 'node:fs';
|
|
8
8
|
import { SimulationHarness } from './simulationHarness.js';
|
|
9
9
|
import { createMockLlmClient } from '../testing/contextTestUtils.js';
|
|
10
|
-
import {
|
|
11
|
-
import { createBlobDegradationProcessor } from '../processors/blobDegradationProcessor.js';
|
|
12
|
-
import { createStateSnapshotProcessor } from '../processors/stateSnapshotProcessor.js';
|
|
13
|
-
import { createHistoryTruncationProcessor } from '../processors/historyTruncationProcessor.js';
|
|
14
|
-
import { createStateSnapshotAsyncProcessor } from '../processors/stateSnapshotAsyncProcessor.js';
|
|
10
|
+
import { stressTestProfile } from '../config/profiles.js';
|
|
15
11
|
expect.addSnapshotSerializer({
|
|
16
12
|
test: (val) => typeof val === 'string' &&
|
|
17
13
|
(/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/i.test(val) ||
|
|
@@ -38,46 +34,19 @@ describe('System Lifecycle Golden Tests', () => {
|
|
|
38
34
|
afterAll(() => {
|
|
39
35
|
vi.restoreAllMocks();
|
|
40
36
|
});
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
config: {
|
|
44
|
-
budget: { maxTokens: 1000, retainedTokens: 500 }, // Extremely tight limits
|
|
45
|
-
},
|
|
46
|
-
buildPipelines: (env) => [
|
|
47
|
-
{
|
|
48
|
-
name: 'Pressure Relief', // Emits from eventBus 'retained_exceeded'
|
|
49
|
-
triggers: ['retained_exceeded'],
|
|
50
|
-
processors: [
|
|
51
|
-
createBlobDegradationProcessor('BlobDegradationProcessor', env),
|
|
52
|
-
createToolMaskingProcessor('ToolMaskingProcessor', env, {
|
|
53
|
-
stringLengthThresholdTokens: 50,
|
|
54
|
-
}),
|
|
55
|
-
createStateSnapshotProcessor('StateSnapshotProcessor', env, {}),
|
|
56
|
-
],
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
name: 'Immediate Sanitization', // The magic string the projector is hardcoded to use
|
|
60
|
-
triggers: ['retained_exceeded'],
|
|
61
|
-
processors: [
|
|
62
|
-
createHistoryTruncationProcessor('HistoryTruncationProcessor', env, {}),
|
|
63
|
-
],
|
|
64
|
-
},
|
|
65
|
-
],
|
|
66
|
-
buildAsyncPipelines: (env) => [
|
|
67
|
-
{
|
|
68
|
-
name: 'Async',
|
|
69
|
-
triggers: ['nodes_aged_out'],
|
|
70
|
-
processors: [
|
|
71
|
-
createStateSnapshotAsyncProcessor('StateSnapshotAsyncProcessor', env, {}),
|
|
72
|
-
],
|
|
73
|
-
},
|
|
74
|
-
],
|
|
75
|
-
});
|
|
76
|
-
const mockLlmClient = createMockLlmClient([
|
|
77
|
-
'<MOCKED_STATE_SNAPSHOT_SUMMARY>',
|
|
78
|
-
]);
|
|
37
|
+
// Uses dynamic role-based mocking to differentiate Snapshot vs Distillation output automatically.
|
|
38
|
+
const mockLlmClient = createMockLlmClient();
|
|
79
39
|
it('Scenario 1: Organic Growth with Huge Tool Output & Images', async () => {
|
|
80
|
-
|
|
40
|
+
// Override stressTestProfile limits slightly to ensure immediate overflow
|
|
41
|
+
// without having to push 50,000 characters to cross the generalist boundaries.
|
|
42
|
+
const customProfile = {
|
|
43
|
+
...stressTestProfile,
|
|
44
|
+
config: {
|
|
45
|
+
...stressTestProfile.config,
|
|
46
|
+
budget: { maxTokens: 1000, retainedTokens: 500 },
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
const harness = await SimulationHarness.create(customProfile, mockLlmClient);
|
|
81
50
|
// Turn 0: System Prompt
|
|
82
51
|
await harness.simulateTurn([
|
|
83
52
|
{ role: 'user', parts: [{ text: 'System Instructions' }] },
|
|
@@ -136,6 +105,8 @@ describe('System Lifecycle Golden Tests', () => {
|
|
|
136
105
|
{ role: 'user', parts: [{ text: 'Can we refactor?' }] },
|
|
137
106
|
{ role: 'model', parts: [{ text: 'Yes we can.' }] },
|
|
138
107
|
]);
|
|
108
|
+
// Give the background tasks a moment to inject the snapshot into the graph
|
|
109
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
139
110
|
// Get final state
|
|
140
111
|
const goldenState = await harness.getGoldenState();
|
|
141
112
|
// In a perfectly functioning opportunistic system, the token trajectory should show
|
|
@@ -167,43 +138,93 @@ describe('System Lifecycle Golden Tests', () => {
|
|
|
167
138
|
// Total tokens should cleanly match character count with no synthetic nodes
|
|
168
139
|
expect(goldenState).toMatchSnapshot();
|
|
169
140
|
});
|
|
170
|
-
it('Scenario 3:
|
|
171
|
-
|
|
172
|
-
|
|
141
|
+
it('Scenario 3: Node Distillation of Large Historical Messages', async () => {
|
|
142
|
+
// 1 Turn = ~2520 tokens.
|
|
143
|
+
// retainedTokens = 4000 ensures Turn 0 is kept intact until Turn 1 pushes the total to ~5040.
|
|
144
|
+
const customProfile = {
|
|
145
|
+
...stressTestProfile,
|
|
173
146
|
config: {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
147
|
+
...stressTestProfile.config,
|
|
148
|
+
budget: { maxTokens: 10000, retainedTokens: 4000 },
|
|
149
|
+
processorOptions: {
|
|
150
|
+
...stressTestProfile.config?.processorOptions,
|
|
151
|
+
NodeDistillation: {
|
|
152
|
+
type: 'NodeDistillationProcessor',
|
|
153
|
+
options: {
|
|
154
|
+
nodeThresholdTokens: 1000, // 1250 > 1000, so older messages will be distilled
|
|
155
|
+
},
|
|
156
|
+
},
|
|
184
157
|
},
|
|
185
|
-
|
|
158
|
+
},
|
|
159
|
+
// Disable async pipelines (StateSnapshots) so they don't compete with the Normalization pipeline
|
|
160
|
+
buildAsyncPipelines: () => [],
|
|
186
161
|
};
|
|
187
|
-
const harness = await SimulationHarness.create(
|
|
162
|
+
const harness = await SimulationHarness.create(customProfile, mockLlmClient);
|
|
188
163
|
// Turn 0
|
|
189
164
|
await harness.simulateTurn([
|
|
190
|
-
{ role: 'user', parts: [{ text: 'A'.repeat(
|
|
191
|
-
{ role: 'model', parts: [{ text: 'B'.repeat(
|
|
165
|
+
{ role: 'user', parts: [{ text: 'A'.repeat(5000) }] },
|
|
166
|
+
{ role: 'model', parts: [{ text: 'B'.repeat(5000) }] },
|
|
192
167
|
]);
|
|
193
|
-
// Turn 1
|
|
168
|
+
// Turn 1
|
|
194
169
|
await harness.simulateTurn([
|
|
195
|
-
{ role: 'user', parts: [{ text: 'C'.repeat(
|
|
196
|
-
{ role: 'model', parts: [{ text: 'D'.repeat(
|
|
170
|
+
{ role: 'user', parts: [{ text: 'C'.repeat(5000) }] },
|
|
171
|
+
{ role: 'model', parts: [{ text: 'D'.repeat(5000) }] },
|
|
197
172
|
]);
|
|
198
|
-
// Give the async background pipeline an extra beat to complete its async execution and emit variants
|
|
199
|
-
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
200
173
|
// Turn 2
|
|
201
174
|
await harness.simulateTurn([
|
|
202
|
-
{ role: 'user', parts: [{ text: 'E'.repeat(
|
|
203
|
-
{ role: 'model', parts: [{ text: 'F'.repeat(
|
|
175
|
+
{ role: 'user', parts: [{ text: 'E'.repeat(5000) }] },
|
|
176
|
+
{ role: 'model', parts: [{ text: 'F'.repeat(5000) }] },
|
|
177
|
+
]);
|
|
178
|
+
const goldenState = await harness.getGoldenState();
|
|
179
|
+
// We should see MOCKED_DISTILLED_NODE replacing older bloated messages, while recent messages are untouched.
|
|
180
|
+
expect(goldenState).toMatchSnapshot();
|
|
181
|
+
});
|
|
182
|
+
it('Scenario 4: Async-Driven Background GC via State Snapshots', async () => {
|
|
183
|
+
// Mathematical Token Budgeting:
|
|
184
|
+
// 200 chars ≈ 50 tokens.
|
|
185
|
+
// 1 Turn (User + Model + Overhead) ≈ 50 + 50 + 20 = 120 Tokens.
|
|
186
|
+
const customProfile = {
|
|
187
|
+
...stressTestProfile,
|
|
188
|
+
config: {
|
|
189
|
+
...stressTestProfile.config,
|
|
190
|
+
// Retain 3 Turns (~360 tokens). Max 5 Turns (~600 tokens).
|
|
191
|
+
budget: { maxTokens: 600, retainedTokens: 360 },
|
|
192
|
+
},
|
|
193
|
+
};
|
|
194
|
+
const harness = await SimulationHarness.create(customProfile, mockLlmClient);
|
|
195
|
+
const createMessage = (index) => `Msg ${index} `.repeat(25).padEnd(200, '.');
|
|
196
|
+
// Turn 0 (~120 tokens) Total: 120
|
|
197
|
+
await harness.simulateTurn([
|
|
198
|
+
{ role: 'user', parts: [{ text: createMessage(0) }] },
|
|
199
|
+
{ role: 'model', parts: [{ text: createMessage(1) }] },
|
|
200
|
+
]);
|
|
201
|
+
// Turn 1 (~120 tokens) Total: 240
|
|
202
|
+
await harness.simulateTurn([
|
|
203
|
+
{ role: 'user', parts: [{ text: createMessage(2) }] },
|
|
204
|
+
{ role: 'model', parts: [{ text: createMessage(3) }] },
|
|
205
|
+
]);
|
|
206
|
+
// Turn 2 (~120 tokens) Total: 360 (At retainedTokens boundary)
|
|
207
|
+
await harness.simulateTurn([
|
|
208
|
+
{ role: 'user', parts: [{ text: createMessage(4) }] },
|
|
209
|
+
{ role: 'model', parts: [{ text: createMessage(5) }] },
|
|
210
|
+
]);
|
|
211
|
+
// Turn 3 (~120 tokens) Total: 480 (Exceeds retainedTokens! Triggers GC on Turn 0 & 1)
|
|
212
|
+
await harness.simulateTurn([
|
|
213
|
+
{ role: 'user', parts: [{ text: createMessage(6) }] },
|
|
214
|
+
{ role: 'model', parts: [{ text: createMessage(7) }] },
|
|
215
|
+
]);
|
|
216
|
+
// Give the async background snapshot pipeline time to complete
|
|
217
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
218
|
+
// Turn 4 (~120 tokens).
|
|
219
|
+
// If GC succeeded, Turn 0 and 1 are now a ~10 token snapshot.
|
|
220
|
+
// Total should be: 10 (Snapshot) + 120 (Turn 2) + 120 (Turn 3) + 120 (Turn 4) = ~370 tokens.
|
|
221
|
+
await harness.simulateTurn([
|
|
222
|
+
{ role: 'user', parts: [{ text: createMessage(8) }] },
|
|
223
|
+
{ role: 'model', parts: [{ text: createMessage(9) }] },
|
|
204
224
|
]);
|
|
205
225
|
const goldenState = await harness.getGoldenState();
|
|
206
|
-
// We should see
|
|
226
|
+
// We should see a MOCKED_STATE_SNAPSHOT_SUMMARY rolling up Turns 0 and 1,
|
|
227
|
+
// while Turns 2, 3, and 4 remain fully intact.
|
|
207
228
|
expect(goldenState).toMatchSnapshot();
|
|
208
229
|
});
|
|
209
230
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecycle.golden.test.js","sourceRoot":"","sources":["../../../../src/context/system-tests/lifecycle.golden.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AACvE,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAErE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"lifecycle.golden.test.js","sourceRoot":"","sources":["../../../../src/context/system-tests/lifecycle.golden.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -29,13 +29,10 @@ export declare class SimulationHarness {
|
|
|
29
29
|
static create(config: ContextProfile, mockLlmClient: BaseLlmClient, mockTempDir?: string): Promise<SimulationHarness>;
|
|
30
30
|
private constructor();
|
|
31
31
|
private init;
|
|
32
|
-
/**
|
|
33
|
-
* Simulates a single "Turn" (User input + Model/Tool outputs)
|
|
34
|
-
* A turn might consist of multiple Content messages (e.g. user prompt -> model call -> user response -> model answer)
|
|
35
|
-
*/
|
|
36
32
|
simulateTurn(messages: Content[]): Promise<void>;
|
|
37
33
|
getGoldenState(): Promise<{
|
|
38
34
|
tokenTrajectory: TurnSummary[];
|
|
39
35
|
finalProjection: Content[];
|
|
36
|
+
baseUnits: number;
|
|
40
37
|
}>;
|
|
41
38
|
}
|
|
@@ -9,7 +9,9 @@ import { ContextEnvironmentImpl } from '../pipeline/environmentImpl.js';
|
|
|
9
9
|
import { ContextTracer } from '../tracer.js';
|
|
10
10
|
import { ContextEventBus } from '../eventBus.js';
|
|
11
11
|
import { PipelineOrchestrator } from '../pipeline/orchestrator.js';
|
|
12
|
-
import {
|
|
12
|
+
import { StaticTokenCalculator } from '../utils/contextTokenCalculator.js';
|
|
13
|
+
import { NodeBehaviorRegistry } from '../graph/behaviorRegistry.js';
|
|
14
|
+
import { registerBuiltInBehaviors } from '../graph/builtinBehaviors.js';
|
|
13
15
|
export class SimulationHarness {
|
|
14
16
|
chatHistory;
|
|
15
17
|
contextManager;
|
|
@@ -35,42 +37,25 @@ export class SimulationHarness {
|
|
|
35
37
|
targetDir: mockTempDir,
|
|
36
38
|
sessionId: 'sim-session',
|
|
37
39
|
});
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
const behaviorRegistry = new NodeBehaviorRegistry();
|
|
41
|
+
registerBuiltInBehaviors(behaviorRegistry);
|
|
42
|
+
const calculator = new StaticTokenCalculator(1, behaviorRegistry);
|
|
43
|
+
this.env = new ContextEnvironmentImpl(() => mockLlmClient, 'sim-prompt', 'sim-session', mockTempDir, mockTempDir, this.tracer, 1, // 1 char per token average for estimation (but estimator uses 0.33)
|
|
44
|
+
this.eventBus, calculator, behaviorRegistry);
|
|
40
45
|
this.orchestrator = new PipelineOrchestrator(config.buildPipelines(this.env), config.buildAsyncPipelines(this.env), this.env, this.eventBus, this.tracer);
|
|
41
|
-
this.contextManager = new ContextManager(config, this.env, this.tracer, this.orchestrator, this.chatHistory);
|
|
46
|
+
this.contextManager = new ContextManager(config, this.env, this.tracer, this.orchestrator, this.chatHistory, calculator);
|
|
42
47
|
}
|
|
43
|
-
/**
|
|
44
|
-
* Simulates a single "Turn" (User input + Model/Tool outputs)
|
|
45
|
-
* A turn might consist of multiple Content messages (e.g. user prompt -> model call -> user response -> model answer)
|
|
46
|
-
*/
|
|
47
48
|
async simulateTurn(messages) {
|
|
48
49
|
// 1. Append the new messages
|
|
49
50
|
const currentHistory = this.chatHistory.get();
|
|
50
51
|
this.chatHistory.set([...currentHistory, ...messages]);
|
|
51
|
-
// 2. Measure tokens immediately after append
|
|
52
|
+
// 2. Measure tokens immediately after append
|
|
52
53
|
const tokensBefore = this.env.tokenCalculator.calculateConcreteListTokens(this.contextManager.getNodes());
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
await new Promise((resolve) => setTimeout(resolve,
|
|
56
|
-
//
|
|
57
|
-
let currentView = this.contextManager.getNodes();
|
|
58
|
-
const currentTokens = this.env.tokenCalculator.calculateConcreteListTokens(currentView);
|
|
59
|
-
if (this.config.config.budget &&
|
|
60
|
-
currentTokens > this.config.config.budget.maxTokens) {
|
|
61
|
-
debugLogger.log(`[Turn ${this.currentTurnIndex}] Sync panic triggered! ${currentTokens} > ${this.config.config.budget.maxTokens}`);
|
|
62
|
-
const orchestrator = this.orchestrator;
|
|
63
|
-
// In the V2 simulation, we trigger the 'gc_backstop' to simulate emergency pressure.
|
|
64
|
-
// Since contextManager owns its buffer natively, the simulation now properly matches reality
|
|
65
|
-
// where the manager runs the orchestrator and keeps the resulting modified view.
|
|
66
|
-
const modifiedView = await orchestrator.executeTriggerSync('gc_backstop', currentView, new Set(currentView.map((e) => e.id)), new Set());
|
|
67
|
-
// In the real system, ContextManager triggers this and retains it.
|
|
68
|
-
// We will emulate that behavior internally in the test loop for token counting.
|
|
69
|
-
currentView = modifiedView;
|
|
70
|
-
}
|
|
71
|
-
// 4. Measure tokens after background processors have processed inboxes
|
|
54
|
+
// 3. Yield to event loop and wait for async pipelines to finish
|
|
55
|
+
await this.contextManager.waitForPipelines();
|
|
56
|
+
await new Promise((resolve) => setTimeout(resolve, 100)); // Extra beat for event bus propagation
|
|
57
|
+
// 4. Measure tokens after background processors
|
|
72
58
|
const tokensAfter = this.env.tokenCalculator.calculateConcreteListTokens(this.contextManager.getNodes());
|
|
73
|
-
debugLogger.log(`[Turn ${this.currentTurnIndex}] Tokens AFTER: ${tokensAfter}`);
|
|
74
59
|
this.tokenTrajectory.push({
|
|
75
60
|
turnIndex: this.currentTurnIndex++,
|
|
76
61
|
tokensBeforeBackground: tokensBefore,
|
|
@@ -78,10 +63,11 @@ export class SimulationHarness {
|
|
|
78
63
|
});
|
|
79
64
|
}
|
|
80
65
|
async getGoldenState() {
|
|
81
|
-
const { history: finalProjection } = await this.contextManager.renderHistory();
|
|
66
|
+
const { history: finalProjection, baseUnits } = await this.contextManager.renderHistory();
|
|
82
67
|
return {
|
|
83
68
|
tokenTrajectory: this.tokenTrajectory,
|
|
84
69
|
finalProjection,
|
|
70
|
+
baseUnits,
|
|
85
71
|
};
|
|
86
72
|
}
|
|
87
73
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simulationHarness.js","sourceRoot":"","sources":["../../../../src/context/system-tests/simulationHarness.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAGlE,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"simulationHarness.js","sourceRoot":"","sources":["../../../../src/context/system-tests/simulationHarness.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,6 +22,7 @@ export declare function createDummyNode(turnId: string, type: NodeType, _tokens?
|
|
|
22
22
|
export declare function createDummyToolNode(turnId: string, _intentTokens?: number, _obsTokens?: number, overrides?: Partial<ToolExecution>, id?: string): ToolExecution;
|
|
23
23
|
export interface MockLlmClient extends BaseLlmClient {
|
|
24
24
|
generateContent: Mock;
|
|
25
|
+
countTokens: Mock;
|
|
25
26
|
}
|
|
26
27
|
export declare function createMockLlmClient(responses?: Array<string | GenerateContentResponse>): MockLlmClient;
|
|
27
28
|
export declare function createMockEnvironment(overrides?: Partial<ContextEnvironment>): ContextEnvironment;
|
|
@@ -15,6 +15,9 @@ import { NodeType, } from '../graph/types.js';
|
|
|
15
15
|
import { InboxSnapshotImpl } from '../pipeline/inbox.js';
|
|
16
16
|
import { ContextWorkingBufferImpl } from '../pipeline/contextWorkingBuffer.js';
|
|
17
17
|
import { testTruncateProfile } from './testProfile.js';
|
|
18
|
+
import { StaticTokenCalculator } from '../utils/contextTokenCalculator.js';
|
|
19
|
+
import { NodeBehaviorRegistry } from '../graph/behaviorRegistry.js';
|
|
20
|
+
import { registerBuiltInBehaviors } from '../graph/builtinBehaviors.js';
|
|
18
21
|
/**
|
|
19
22
|
* Creates a valid mock GenerateContentResponse with the provided text.
|
|
20
23
|
* Used to avoid having to manually construct the deeply nested candidate/content/part structure.
|
|
@@ -64,32 +67,46 @@ export function createDummyToolNode(turnId, _intentTokens = 100, _obsTokens = 20
|
|
|
64
67
|
};
|
|
65
68
|
}
|
|
66
69
|
export function createMockLlmClient(responses) {
|
|
67
|
-
const generateContentMock = vi
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
70
|
+
const generateContentMock = vi
|
|
71
|
+
.fn()
|
|
72
|
+
.mockImplementation((options) => {
|
|
73
|
+
// Array-based logic for backwards compatibility, if provided
|
|
74
|
+
if (responses && responses.length > 0) {
|
|
75
|
+
const callCount = generateContentMock.mock.calls.length - 1;
|
|
76
|
+
const idx = callCount < responses.length ? callCount : responses.length - 1;
|
|
77
|
+
const res = responses[idx];
|
|
78
|
+
return Promise.resolve(typeof res === 'string'
|
|
79
|
+
? createMockGenerateContentResponse(res)
|
|
80
|
+
: res);
|
|
76
81
|
}
|
|
77
|
-
|
|
78
|
-
const
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
const lastContent = options.contents[options.contents.length - 1];
|
|
83
|
+
const lastPart = lastContent?.parts?.[lastContent.parts.length - 1];
|
|
84
|
+
const lastPartString = JSON.stringify(lastPart ?? {});
|
|
85
|
+
const contentSample = `${lastPartString.slice(0, 10)}...${lastPartString.slice(-10)}`;
|
|
86
|
+
return Promise.resolve(createMockGenerateContentResponse(`Mock response from: ${options.role}, for: ${contentSample}`));
|
|
87
|
+
});
|
|
88
|
+
const generateJsonMock = vi.fn().mockImplementation(async () => {
|
|
89
|
+
let mockStr = '';
|
|
90
|
+
if (responses && responses.length > 0) {
|
|
91
|
+
const callCount = generateJsonMock.mock.calls.length - 1;
|
|
92
|
+
const idx = callCount < responses.length ? callCount : responses.length - 1;
|
|
93
|
+
const res = responses[idx];
|
|
94
|
+
if (typeof res === 'string') {
|
|
95
|
+
mockStr = res;
|
|
96
|
+
}
|
|
84
97
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
98
|
+
return {
|
|
99
|
+
active_tasks: [],
|
|
100
|
+
discovered_facts: [],
|
|
101
|
+
constraints_and_preferences: [],
|
|
102
|
+
chronological_summary: mockStr,
|
|
103
|
+
};
|
|
104
|
+
});
|
|
90
105
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
91
106
|
return {
|
|
92
107
|
generateContent: generateContentMock,
|
|
108
|
+
generateJson: generateJsonMock,
|
|
109
|
+
countTokens: vi.fn().mockResolvedValue({ totalTokens: 100 }),
|
|
93
110
|
};
|
|
94
111
|
}
|
|
95
112
|
export function createMockEnvironment(overrides) {
|
|
@@ -99,10 +116,13 @@ export function createMockEnvironment(overrides) {
|
|
|
99
116
|
sessionId: 'mock-session',
|
|
100
117
|
});
|
|
101
118
|
const eventBus = new ContextEventBus();
|
|
102
|
-
|
|
119
|
+
const behaviorRegistry = new NodeBehaviorRegistry();
|
|
120
|
+
registerBuiltInBehaviors(behaviorRegistry);
|
|
121
|
+
const calculator = new StaticTokenCalculator(1, behaviorRegistry);
|
|
122
|
+
let env = new ContextEnvironmentImpl(() => llmClient, 'mock-session', 'mock-prompt-id', '/tmp/.gemini/trace', '/tmp/.gemini/tool-outputs', tracer, 1, eventBus, calculator, behaviorRegistry);
|
|
103
123
|
if (overrides) {
|
|
104
124
|
if (overrides.llmClient) {
|
|
105
|
-
env = new ContextEnvironmentImpl(() => overrides.llmClient, env.sessionId, env.promptId, env.traceDir, env.projectTempDir, env.tracer, env.charsPerToken, env.eventBus);
|
|
125
|
+
env = new ContextEnvironmentImpl(() => overrides.llmClient, env.sessionId, env.promptId, env.traceDir, env.projectTempDir, env.tracer, env.charsPerToken, env.eventBus, calculator, behaviorRegistry);
|
|
106
126
|
}
|
|
107
127
|
const { llmClient: _llmClient, ...restOverrides } = overrides;
|
|
108
128
|
Object.assign(env, restOverrides);
|
|
@@ -168,9 +188,12 @@ export function setupContextComponentTest(config, sidecarOverride) {
|
|
|
168
188
|
sessionId: 'test-session',
|
|
169
189
|
});
|
|
170
190
|
const eventBus = new ContextEventBus();
|
|
171
|
-
const
|
|
191
|
+
const behaviorRegistry = new NodeBehaviorRegistry();
|
|
192
|
+
registerBuiltInBehaviors(behaviorRegistry);
|
|
193
|
+
const calculator = new StaticTokenCalculator(1, behaviorRegistry);
|
|
194
|
+
const env = new ContextEnvironmentImpl(() => config.getBaseLlmClient(), 'test prompt-id', 'test-session', '/tmp', '/tmp/gemini-test', tracer, 1, eventBus, calculator, behaviorRegistry);
|
|
172
195
|
const orchestrator = new PipelineOrchestrator(sidecar.buildPipelines(env), sidecar.buildAsyncPipelines(env), env, eventBus, tracer);
|
|
173
|
-
const contextManager = new ContextManager(sidecar, env, tracer, orchestrator, chatHistory);
|
|
196
|
+
const contextManager = new ContextManager(sidecar, env, tracer, orchestrator, chatHistory, calculator);
|
|
174
197
|
// The async async pipeline is now internally managed by ContextManager
|
|
175
198
|
return { chatHistory, contextManager };
|
|
176
199
|
}
|