@machina.ai/cell-cli-core 1.38.1-rc2 → 1.40.1-rc2
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/AFTER_MERGE_PROMPT.md +1 -1
- package/dist/docs/admin/enterprise-controls.md +1 -1
- package/dist/docs/changelogs/index.md +42 -0
- package/dist/docs/changelogs/latest.md +254 -361
- package/dist/docs/changelogs/preview.md +237 -406
- package/dist/docs/cli/acp-mode.md +6 -6
- package/dist/docs/cli/auto-memory.md +143 -0
- package/dist/docs/cli/checkpointing.md +5 -5
- package/dist/docs/cli/cli-reference.md +12 -11
- package/dist/docs/cli/creating-skills.md +2 -2
- package/dist/docs/cli/custom-commands.md +15 -14
- package/dist/docs/cli/enterprise.md +17 -14
- package/dist/docs/cli/gemini-ignore.md +2 -2
- package/dist/docs/cli/generation-settings.md +21 -20
- package/dist/docs/cli/model-routing.md +2 -2
- package/dist/docs/cli/model-steering.md +1 -1
- package/dist/docs/cli/plan-mode.md +11 -6
- package/dist/docs/cli/sandbox.md +7 -5
- package/dist/docs/cli/settings.md +32 -28
- package/dist/docs/cli/system-prompt.md +8 -8
- package/dist/docs/cli/telemetry.md +18 -11
- package/dist/docs/cli/themes.md +2 -2
- package/dist/docs/cli/trusted-folders.md +41 -13
- package/dist/docs/cli/tutorials/mcp-setup.md +1 -1
- package/dist/docs/cli/tutorials/memory-management.md +3 -1
- package/dist/docs/cli/tutorials/plan-mode-steering.md +2 -2
- package/dist/docs/cli/tutorials/session-management.md +1 -1
- package/dist/docs/cli/tutorials/shell-commands.md +1 -1
- package/dist/docs/cli/tutorials/task-planning.md +3 -3
- package/dist/docs/core/index.md +5 -6
- package/dist/docs/core/local-model-routing.md +1 -1
- package/dist/docs/core/remote-agents.md +1 -1
- package/dist/docs/core/subagents.md +38 -8
- package/dist/docs/extensions/best-practices.md +5 -4
- package/dist/docs/extensions/reference.md +6 -5
- package/dist/docs/extensions/releasing.md +6 -5
- package/dist/docs/extensions/writing-extensions.md +11 -11
- package/dist/docs/get-started/{authentication.md → authentication.mdx} +139 -93
- package/dist/docs/get-started/gemini-3.md +1 -1
- package/dist/docs/get-started/index.md +4 -4
- package/dist/docs/get-started/installation.mdx +201 -0
- package/dist/docs/hooks/best-practices.md +18 -17
- package/dist/docs/hooks/index.md +10 -8
- package/dist/docs/hooks/reference.md +10 -10
- package/dist/docs/ide-integration/ide-companion-spec.md +14 -14
- package/dist/docs/ide-integration/index.md +4 -4
- package/dist/docs/index.md +2 -2
- package/dist/docs/integration-tests.md +84 -2
- package/dist/docs/issue-and-pr-automation.md +8 -7
- package/dist/docs/npm.md +2 -2
- package/dist/docs/reference/commands.md +11 -11
- package/dist/docs/reference/configuration.md +150 -47
- package/dist/docs/reference/keyboard-shortcuts.md +79 -2
- package/dist/docs/reference/memport.md +2 -3
- package/dist/docs/reference/policy-engine.md +60 -26
- package/dist/docs/reference/tools.md +38 -4
- package/dist/docs/release-confidence.md +1 -1
- package/dist/docs/releases.md +19 -19
- package/dist/docs/resources/faq.md +5 -5
- package/dist/docs/resources/tos-privacy.md +10 -9
- package/dist/docs/resources/troubleshooting.md +17 -16
- package/dist/docs/resources/uninstall.md +5 -4
- package/dist/docs/sidebar.json +13 -1
- package/dist/docs/tools/ask-user.md +3 -3
- package/dist/docs/tools/file-system.md +7 -7
- package/dist/docs/tools/mcp-resources.md +44 -0
- package/dist/docs/tools/mcp-server.md +42 -39
- package/dist/docs/tools/shell.md +5 -5
- package/dist/docs/tools/tracker.md +61 -0
- package/dist/package.json +5 -4
- package/dist/src/agent/content-utils.d.ts +0 -6
- package/dist/src/agent/content-utils.js +0 -14
- package/dist/src/agent/content-utils.js.map +1 -1
- package/dist/src/agent/content-utils.test.js +1 -18
- package/dist/src/agent/content-utils.test.js.map +1 -1
- package/dist/src/agent/event-translator.js +8 -3
- package/dist/src/agent/event-translator.js.map +1 -1
- package/dist/src/agent/event-translator.test.js +14 -9
- package/dist/src/agent/event-translator.test.js.map +1 -1
- package/dist/src/agent/legacy-agent-session.js +9 -3
- package/dist/src/agent/legacy-agent-session.js.map +1 -1
- package/dist/src/agent/legacy-agent-session.test.js +4 -3
- package/dist/src/agent/legacy-agent-session.test.js.map +1 -1
- package/dist/src/agent/tool-display-utils.d.ts +30 -0
- package/dist/src/agent/tool-display-utils.js +69 -0
- package/dist/src/agent/tool-display-utils.js.map +1 -0
- package/dist/src/agent/tool-display-utils.test.js +101 -0
- package/dist/src/agent/tool-display-utils.test.js.map +1 -0
- package/dist/src/agent/types.d.ts +25 -5
- package/dist/src/agents/a2aUtils.js +28 -15
- package/dist/src/agents/a2aUtils.js.map +1 -1
- package/dist/src/agents/a2aUtils.test.js +43 -0
- package/dist/src/agents/a2aUtils.test.js.map +1 -1
- package/dist/src/agents/agent-tool.d.ts +31 -0
- package/dist/src/agents/agent-tool.js +155 -0
- package/dist/src/agents/agent-tool.js.map +1 -0
- package/dist/src/agents/agent-tool.test.js +110 -0
- package/dist/src/agents/agent-tool.test.js.map +1 -0
- package/dist/src/agents/agentLoader.d.ts +79 -4
- package/dist/src/agents/agentLoader.js +40 -2
- package/dist/src/agents/agentLoader.js.map +1 -1
- package/dist/src/agents/agentLoader.test.js +32 -0
- package/dist/src/agents/agentLoader.test.js.map +1 -1
- package/dist/src/agents/browser/analyzeScreenshot.js +1 -1
- package/dist/src/agents/browser/analyzeScreenshot.js.map +1 -1
- package/dist/src/agents/browser/analyzeScreenshot.test.js +19 -7
- package/dist/src/agents/browser/analyzeScreenshot.test.js.map +1 -1
- package/dist/src/agents/browser/browserAgentInvocation.d.ts +2 -2
- package/dist/src/agents/browser/browserAgentInvocation.js +2 -1
- package/dist/src/agents/browser/browserAgentInvocation.js.map +1 -1
- package/dist/src/agents/browser/browserAgentInvocation.test.js +61 -17
- package/dist/src/agents/browser/browserAgentInvocation.test.js.map +1 -1
- package/dist/src/agents/browser/mcpToolWrapper.js +1 -1
- package/dist/src/agents/browser/mcpToolWrapper.js.map +1 -1
- package/dist/src/agents/browser/mcpToolWrapper.test.js +22 -10
- package/dist/src/agents/browser/mcpToolWrapper.test.js.map +1 -1
- package/dist/src/agents/codebase-investigator.js +2 -2
- package/dist/src/agents/codebase-investigator.js.map +1 -1
- package/dist/src/agents/generalist-agent.js +3 -2
- package/dist/src/agents/generalist-agent.js.map +1 -1
- package/dist/src/agents/generalist-agent.test.js +1 -0
- package/dist/src/agents/generalist-agent.test.js.map +1 -1
- package/dist/src/agents/local-executor.d.ts +1 -1
- package/dist/src/agents/local-executor.js +10 -7
- package/dist/src/agents/local-executor.js.map +1 -1
- package/dist/src/agents/local-executor.test.js +5 -3
- package/dist/src/agents/local-executor.test.js.map +1 -1
- package/dist/src/agents/local-invocation.d.ts +2 -2
- package/dist/src/agents/local-invocation.js +8 -2
- package/dist/src/agents/local-invocation.js.map +1 -1
- package/dist/src/agents/local-invocation.test.js +29 -13
- package/dist/src/agents/local-invocation.test.js.map +1 -1
- package/dist/src/agents/registry.d.ts +2 -0
- package/dist/src/agents/registry.js +20 -19
- package/dist/src/agents/registry.js.map +1 -1
- package/dist/src/agents/registry.test.js +19 -30
- package/dist/src/agents/registry.test.js.map +1 -1
- package/dist/src/agents/remote-invocation.d.ts +3 -4
- package/dist/src/agents/remote-invocation.js +2 -1
- package/dist/src/agents/remote-invocation.js.map +1 -1
- package/dist/src/agents/remote-invocation.test.js +45 -18
- package/dist/src/agents/remote-invocation.test.js.map +1 -1
- package/dist/src/agents/skill-extraction-agent.d.ts +3 -2
- package/dist/src/agents/skill-extraction-agent.js +99 -56
- package/dist/src/agents/skill-extraction-agent.js.map +1 -1
- package/dist/src/agents/skill-extraction-agent.test.js +54 -0
- package/dist/src/agents/skill-extraction-agent.test.js.map +1 -0
- package/dist/src/availability/policyCatalog.js +1 -1
- package/dist/src/availability/policyCatalog.js.map +1 -1
- package/dist/src/availability/policyCatalog.test.js +1 -1
- package/dist/src/availability/policyCatalog.test.js.map +1 -1
- package/dist/src/code_assist/oauth2.js +14 -4
- package/dist/src/code_assist/oauth2.js.map +1 -1
- package/dist/src/commands/memory.d.ts +77 -0
- package/dist/src/commands/memory.js +494 -0
- package/dist/src/commands/memory.js.map +1 -1
- package/dist/src/commands/memory.test.js +720 -1
- package/dist/src/commands/memory.test.js.map +1 -1
- package/dist/src/config/config-agents-reload.test.js +26 -31
- package/dist/src/config/config-agents-reload.test.js.map +1 -1
- package/dist/src/config/config.d.ts +24 -10
- package/dist/src/config/config.js +148 -82
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.test.js +373 -10
- package/dist/src/config/config.test.js.map +1 -1
- package/dist/src/config/constants.d.ts +1 -0
- package/dist/src/config/constants.js +2 -0
- package/dist/src/config/constants.js.map +1 -1
- package/dist/src/config/defaultModelConfigs.js +7 -7
- package/dist/src/config/defaultModelConfigs.js.map +1 -1
- package/dist/src/config/memory.js +1 -1
- package/dist/src/config/memory.js.map +1 -1
- package/dist/src/config/path-validation.test.js +15 -6
- package/dist/src/config/path-validation.test.js.map +1 -1
- package/dist/src/config/projectRegistry.js +113 -32
- package/dist/src/config/projectRegistry.js.map +1 -1
- package/dist/src/config/projectRegistry.test.js +51 -0
- package/dist/src/config/projectRegistry.test.js.map +1 -1
- package/dist/src/config/storage.d.ts +5 -1
- package/dist/src/config/storage.js +14 -1
- package/dist/src/config/storage.js.map +1 -1
- package/dist/src/config/storage.test.js +12 -0
- package/dist/src/config/storage.test.js.map +1 -1
- package/dist/src/confirmation-bus/message-bus.d.ts +4 -1
- package/dist/src/confirmation-bus/message-bus.js +39 -1
- package/dist/src/confirmation-bus/message-bus.js.map +1 -1
- package/dist/src/confirmation-bus/message-bus.test.js +43 -0
- package/dist/src/confirmation-bus/message-bus.test.js.map +1 -1
- package/dist/src/context/config/configLoader.d.ts +13 -0
- package/dist/src/context/config/configLoader.js +65 -0
- package/dist/src/context/config/configLoader.js.map +1 -0
- package/dist/src/context/config/configLoader.test.d.ts +6 -0
- package/dist/src/context/config/configLoader.test.js +79 -0
- package/dist/src/context/config/configLoader.test.js.map +1 -0
- package/dist/src/context/config/profiles.d.ts +17 -0
- package/dist/src/context/config/profiles.js +93 -0
- package/dist/src/context/config/profiles.js.map +1 -0
- package/dist/src/context/config/registry.d.ts +21 -0
- package/dist/src/context/config/registry.js +32 -0
- package/dist/src/context/config/registry.js.map +1 -0
- package/dist/src/context/config/schema.d.ts +45 -0
- package/dist/src/context/config/schema.js +47 -0
- package/dist/src/context/config/schema.js.map +1 -0
- package/dist/src/context/config/types.d.ts +39 -0
- package/dist/src/context/config/types.js +7 -0
- package/dist/src/context/config/types.js.map +1 -0
- package/dist/src/context/contextManager.barrier.test.d.ts +6 -0
- package/dist/src/context/contextManager.barrier.test.js +56 -0
- package/dist/src/context/contextManager.barrier.test.js.map +1 -0
- package/dist/src/context/contextManager.d.ts +49 -0
- package/dist/src/context/contextManager.js +120 -0
- package/dist/src/context/contextManager.js.map +1 -0
- package/dist/src/context/eventBus.d.ts +28 -0
- package/dist/src/context/eventBus.js +27 -0
- package/dist/src/context/eventBus.js.map +1 -0
- package/dist/src/context/graph/behaviorRegistry.d.ts +28 -0
- package/dist/src/context/graph/behaviorRegistry.js +14 -0
- package/dist/src/context/graph/behaviorRegistry.js.map +1 -0
- package/dist/src/context/graph/builtinBehaviors.d.ts +11 -0
- package/dist/src/context/graph/builtinBehaviors.js +145 -0
- package/dist/src/context/graph/builtinBehaviors.js.map +1 -0
- package/dist/src/context/graph/fromGraph.d.ts +9 -0
- package/dist/src/context/graph/fromGraph.js +34 -0
- package/dist/src/context/graph/fromGraph.js.map +1 -0
- package/dist/src/context/graph/mapper.d.ts +16 -0
- package/dist/src/context/graph/mapper.js +16 -0
- package/dist/src/context/graph/mapper.js.map +1 -0
- package/dist/src/context/graph/render.d.ts +15 -0
- package/dist/src/context/graph/render.js +72 -0
- package/dist/src/context/graph/render.js.map +1 -0
- package/dist/src/context/graph/toGraph.d.ts +10 -0
- package/dist/src/context/graph/toGraph.js +172 -0
- package/dist/src/context/graph/toGraph.js.map +1 -0
- package/dist/src/context/graph/types.d.ts +139 -0
- package/dist/src/context/graph/types.js +36 -0
- package/dist/src/context/graph/types.js.map +1 -0
- package/dist/src/context/historyObserver.d.ts +27 -0
- package/dist/src/context/historyObserver.js +64 -0
- package/dist/src/context/historyObserver.js.map +1 -0
- package/dist/src/context/pipeline/contextWorkingBuffer.d.ts +33 -0
- package/dist/src/context/pipeline/contextWorkingBuffer.js +197 -0
- package/dist/src/context/pipeline/contextWorkingBuffer.js.map +1 -0
- package/dist/src/context/pipeline/contextWorkingBuffer.test.d.ts +6 -0
- package/dist/src/context/pipeline/contextWorkingBuffer.test.js +89 -0
- package/dist/src/context/pipeline/contextWorkingBuffer.test.js.map +1 -0
- package/dist/src/context/pipeline/environment.d.ts +27 -0
- package/dist/src/context/pipeline/environment.js +2 -0
- package/dist/src/context/pipeline/environment.js.map +1 -0
- package/dist/src/context/pipeline/environmentImpl.d.ts +28 -0
- package/dist/src/context/pipeline/environmentImpl.js +40 -0
- package/dist/src/context/pipeline/environmentImpl.js.map +1 -0
- package/dist/src/context/pipeline/environmentImpl.test.d.ts +1 -0
- package/dist/src/context/pipeline/environmentImpl.test.js +32 -0
- package/dist/src/context/pipeline/environmentImpl.test.js.map +1 -0
- package/dist/src/context/pipeline/inbox.d.ts +15 -0
- package/dist/src/context/pipeline/inbox.js +52 -0
- package/dist/src/context/pipeline/inbox.js.map +1 -0
- package/dist/src/context/pipeline/inbox.test.d.ts +1 -0
- package/dist/src/context/pipeline/inbox.test.js +36 -0
- package/dist/src/context/pipeline/inbox.test.js.map +1 -0
- package/dist/src/context/pipeline/orchestrator.d.ts +22 -0
- package/dist/src/context/pipeline/orchestrator.js +126 -0
- package/dist/src/context/pipeline/orchestrator.js.map +1 -0
- package/dist/src/context/pipeline/orchestrator.test.d.ts +6 -0
- package/dist/src/context/pipeline/orchestrator.test.js +154 -0
- package/dist/src/context/pipeline/orchestrator.test.js.map +1 -0
- package/dist/src/context/pipeline.d.ts +52 -0
- package/dist/src/context/pipeline.js +7 -0
- package/dist/src/context/pipeline.js.map +1 -0
- package/dist/src/context/processors/blobDegradationProcessor.d.ts +6 -0
- package/dist/src/context/processors/blobDegradationProcessor.js +127 -0
- package/dist/src/context/processors/blobDegradationProcessor.js.map +1 -0
- package/dist/src/context/processors/blobDegradationProcessor.test.d.ts +6 -0
- package/dist/src/context/processors/blobDegradationProcessor.test.js +72 -0
- package/dist/src/context/processors/blobDegradationProcessor.test.js.map +1 -0
- package/dist/src/context/processors/historyTruncationProcessor.d.ts +11 -0
- package/dist/src/context/processors/historyTruncationProcessor.js +61 -0
- package/dist/src/context/processors/historyTruncationProcessor.js.map +1 -0
- package/dist/src/context/processors/nodeDistillationProcessor.d.ts +8 -0
- package/dist/src/context/processors/nodeDistillationProcessor.js +167 -0
- package/dist/src/context/processors/nodeDistillationProcessor.js.map +1 -0
- package/dist/src/context/processors/nodeDistillationProcessor.test.d.ts +6 -0
- package/dist/src/context/processors/nodeDistillationProcessor.test.js +77 -0
- package/dist/src/context/processors/nodeDistillationProcessor.test.js.map +1 -0
- package/dist/src/context/processors/nodeTruncationProcessor.d.ts +8 -0
- package/dist/src/context/processors/nodeTruncationProcessor.js +109 -0
- package/dist/src/context/processors/nodeTruncationProcessor.js.map +1 -0
- package/dist/src/context/processors/nodeTruncationProcessor.test.d.ts +6 -0
- package/dist/src/context/processors/nodeTruncationProcessor.test.js +71 -0
- package/dist/src/context/processors/nodeTruncationProcessor.test.js.map +1 -0
- package/dist/src/context/processors/rollingSummaryProcessor.d.ts +8 -0
- package/dist/src/context/processors/rollingSummaryProcessor.js +129 -0
- package/dist/src/context/processors/rollingSummaryProcessor.js.map +1 -0
- package/dist/src/context/processors/rollingSummaryProcessor.test.d.ts +1 -0
- package/dist/src/context/processors/rollingSummaryProcessor.test.js +60 -0
- package/dist/src/context/processors/rollingSummaryProcessor.test.js.map +1 -0
- package/dist/src/context/processors/stateSnapshotAsyncProcessor.d.ts +9 -0
- package/dist/src/context/processors/stateSnapshotAsyncProcessor.js +75 -0
- package/dist/src/context/processors/stateSnapshotAsyncProcessor.js.map +1 -0
- package/dist/src/context/processors/stateSnapshotAsyncProcessor.test.d.ts +1 -0
- package/dist/src/context/processors/stateSnapshotAsyncProcessor.test.js +80 -0
- package/dist/src/context/processors/stateSnapshotAsyncProcessor.test.js.map +1 -0
- package/dist/src/context/processors/stateSnapshotProcessor.d.ts +9 -0
- package/dist/src/context/processors/stateSnapshotProcessor.js +130 -0
- package/dist/src/context/processors/stateSnapshotProcessor.js.map +1 -0
- package/dist/src/context/processors/stateSnapshotProcessor.test.d.ts +1 -0
- package/dist/src/context/processors/stateSnapshotProcessor.test.js +91 -0
- package/dist/src/context/processors/stateSnapshotProcessor.test.js.map +1 -0
- package/dist/src/context/processors/toolMaskingProcessor.d.ts +8 -0
- package/dist/src/context/processors/toolMaskingProcessor.js +194 -0
- package/dist/src/context/processors/toolMaskingProcessor.js.map +1 -0
- package/dist/src/context/processors/toolMaskingProcessor.test.d.ts +1 -0
- package/dist/src/context/processors/toolMaskingProcessor.test.js +50 -0
- package/dist/src/context/processors/toolMaskingProcessor.test.js.map +1 -0
- package/dist/src/context/system-tests/lifecycle.golden.test.d.ts +6 -0
- package/dist/src/context/system-tests/lifecycle.golden.test.js +195 -0
- package/dist/src/context/system-tests/lifecycle.golden.test.js.map +1 -0
- package/dist/src/context/system-tests/simulationHarness.d.ts +41 -0
- package/dist/src/context/system-tests/simulationHarness.js +88 -0
- package/dist/src/context/system-tests/simulationHarness.js.map +1 -0
- package/dist/src/context/testing/contextTestUtils.d.ts +44 -0
- package/dist/src/context/testing/contextTestUtils.js +176 -0
- package/dist/src/context/testing/contextTestUtils.js.map +1 -0
- package/dist/src/context/testing/testProfile.d.ts +7 -0
- package/dist/src/context/testing/testProfile.js +20 -0
- package/dist/src/context/testing/testProfile.js.map +1 -0
- package/dist/src/context/tracer.d.ts +19 -0
- package/dist/src/context/tracer.js +79 -0
- package/dist/src/context/tracer.js.map +1 -0
- package/dist/src/context/tracer.test.d.ts +6 -0
- package/dist/src/context/tracer.test.js +71 -0
- package/dist/src/context/tracer.test.js.map +1 -0
- package/dist/src/context/utils/contextTokenCalculator.d.ts +53 -0
- package/dist/src/context/utils/contextTokenCalculator.js +97 -0
- package/dist/src/context/utils/contextTokenCalculator.js.map +1 -0
- package/dist/src/context/utils/snapshotGenerator.d.ts +12 -0
- package/dist/src/context/utils/snapshotGenerator.js +43 -0
- package/dist/src/context/utils/snapshotGenerator.js.map +1 -0
- package/dist/src/core/agentChatHistory.d.ts +26 -0
- package/dist/src/core/agentChatHistory.js +50 -0
- package/dist/src/core/agentChatHistory.js.map +1 -0
- package/dist/src/core/client.js +3 -1
- package/dist/src/core/client.js.map +1 -1
- package/dist/src/core/client.test.js +4 -0
- package/dist/src/core/client.test.js.map +1 -1
- package/dist/src/core/contentGenerator.d.ts +8 -1
- package/dist/src/core/contentGenerator.js +46 -4
- package/dist/src/core/contentGenerator.js.map +1 -1
- package/dist/src/core/contentGenerator.test.js +174 -8
- package/dist/src/core/contentGenerator.test.js.map +1 -1
- package/dist/src/core/coreToolHookTriggers.d.ts +1 -1
- package/dist/src/core/coreToolHookTriggers.js +5 -1
- package/dist/src/core/coreToolHookTriggers.js.map +1 -1
- package/dist/src/core/coreToolHookTriggers.test.js +1 -1
- package/dist/src/core/coreToolHookTriggers.test.js.map +1 -1
- package/dist/src/core/geminiChat.d.ts +2 -1
- package/dist/src/core/geminiChat.js +7 -2
- package/dist/src/core/geminiChat.js.map +1 -1
- package/dist/src/core/geminiChat.test.js +19 -6
- package/dist/src/core/geminiChat.test.js.map +1 -1
- package/dist/src/core/geminiChat_network_retry.test.js +42 -0
- package/dist/src/core/geminiChat_network_retry.test.js.map +1 -1
- package/dist/src/core/localLiteRtLmClient.js +2 -0
- package/dist/src/core/localLiteRtLmClient.js.map +1 -1
- package/dist/src/core/localLiteRtLmClient.test.js +7 -0
- package/dist/src/core/localLiteRtLmClient.test.js.map +1 -1
- package/dist/src/core/loggingContentGenerator.js +19 -6
- package/dist/src/core/loggingContentGenerator.js.map +1 -1
- package/dist/src/core/loggingContentGenerator.test.js +55 -0
- package/dist/src/core/loggingContentGenerator.test.js.map +1 -1
- package/dist/src/core/prompts-substitution.test.js +1 -0
- package/dist/src/core/prompts-substitution.test.js.map +1 -1
- package/dist/src/core/prompts.d.ts +1 -1
- package/dist/src/core/prompts.js +2 -2
- package/dist/src/core/prompts.js.map +1 -1
- package/dist/src/core/prompts.test.js +39 -8
- package/dist/src/core/prompts.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/hookRunner.js +8 -0
- package/dist/src/hooks/hookRunner.js.map +1 -1
- package/dist/src/hooks/hookRunner.test.js +23 -0
- package/dist/src/hooks/hookRunner.test.js.map +1 -1
- package/dist/src/ide/ide-client.js +3 -4
- package/dist/src/ide/ide-client.js.map +1 -1
- package/dist/src/index.d.ts +7 -3
- package/dist/src/index.js +7 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcp/mcpLauncher.js +1 -1
- package/dist/src/mcp/mcpLauncher.js.map +1 -1
- package/dist/src/mcp/oauth-provider.test.js +24 -17
- package/dist/src/mcp/oauth-provider.test.js.map +1 -1
- package/dist/src/policy/config.d.ts +2 -0
- package/dist/src/policy/config.js +67 -12
- package/dist/src/policy/config.js.map +1 -1
- package/dist/src/policy/core-tools-mapping.test.d.ts +6 -0
- package/dist/src/policy/core-tools-mapping.test.js +44 -0
- package/dist/src/policy/core-tools-mapping.test.js.map +1 -0
- package/dist/src/policy/policies/agents.toml +10 -0
- package/dist/src/policy/policies/plan.toml +17 -43
- package/dist/src/policy/policies/read-only.toml +24 -38
- package/dist/src/policy/policy-engine.d.ts +1 -1
- package/dist/src/policy/policy-engine.js +72 -67
- package/dist/src/policy/policy-engine.js.map +1 -1
- package/dist/src/policy/policy-engine.test.js +71 -4
- package/dist/src/policy/policy-engine.test.js.map +1 -1
- package/dist/src/policy/sandboxPolicyManager.js +4 -4
- package/dist/src/policy/sandboxPolicyManager.js.map +1 -1
- package/dist/src/policy/shell-safety-regression.test.d.ts +6 -0
- package/dist/src/policy/shell-safety-regression.test.js +86 -0
- package/dist/src/policy/shell-safety-regression.test.js.map +1 -0
- package/dist/src/policy/shell-safety.test.js +24 -0
- package/dist/src/policy/shell-safety.test.js.map +1 -1
- package/dist/src/policy/shell-substitution.test.d.ts +6 -0
- package/dist/src/policy/shell-substitution.test.js +75 -0
- package/dist/src/policy/shell-substitution.test.js.map +1 -0
- package/dist/src/policy/toml-loader.test.js +25 -11
- package/dist/src/policy/toml-loader.test.js.map +1 -1
- package/dist/src/policy/types.d.ts +6 -2
- package/dist/src/policy/types.js +4 -2
- package/dist/src/policy/types.js.map +1 -1
- package/dist/src/prompts/promptProvider.d.ts +1 -1
- package/dist/src/prompts/promptProvider.js +41 -24
- package/dist/src/prompts/promptProvider.js.map +1 -1
- package/dist/src/prompts/promptProvider.test.js +36 -2
- package/dist/src/prompts/promptProvider.test.js.map +1 -1
- package/dist/src/prompts/snippets-memory-v2.test.d.ts +6 -0
- package/dist/src/prompts/snippets-memory-v2.test.js +94 -0
- package/dist/src/prompts/snippets-memory-v2.test.js.map +1 -0
- package/dist/src/prompts/snippets.d.ts +19 -1
- package/dist/src/prompts/snippets.js +33 -6
- package/dist/src/prompts/snippets.js.map +1 -1
- package/dist/src/prompts/snippets.legacy.d.ts +6 -1
- package/dist/src/prompts/snippets.legacy.js +14 -7
- package/dist/src/prompts/snippets.legacy.js.map +1 -1
- package/dist/src/prompts/utils.test.js +1 -0
- package/dist/src/prompts/utils.test.js.map +1 -1
- package/dist/src/routing/modelRouterService.js +1 -1
- package/dist/src/routing/modelRouterService.js.map +1 -1
- package/dist/src/sandbox/linux/LinuxSandboxManager.d.ts +2 -0
- package/dist/src/sandbox/linux/LinuxSandboxManager.js +43 -19
- package/dist/src/sandbox/linux/LinuxSandboxManager.js.map +1 -1
- package/dist/src/sandbox/linux/LinuxSandboxManager.test.js +16 -0
- package/dist/src/sandbox/linux/LinuxSandboxManager.test.js.map +1 -1
- package/dist/src/sandbox/linux/bwrapArgsBuilder.d.ts +3 -7
- package/dist/src/sandbox/linux/bwrapArgsBuilder.js +96 -105
- package/dist/src/sandbox/linux/bwrapArgsBuilder.js.map +1 -1
- package/dist/src/sandbox/linux/bwrapArgsBuilder.test.js +144 -41
- package/dist/src/sandbox/linux/bwrapArgsBuilder.test.js.map +1 -1
- package/dist/src/sandbox/macos/MacOsSandboxManager.js +19 -10
- package/dist/src/sandbox/macos/MacOsSandboxManager.js.map +1 -1
- package/dist/src/sandbox/macos/MacOsSandboxManager.test.js +24 -37
- package/dist/src/sandbox/macos/MacOsSandboxManager.test.js.map +1 -1
- package/dist/src/sandbox/macos/seatbeltArgsBuilder.d.ts +3 -9
- package/dist/src/sandbox/macos/seatbeltArgsBuilder.js +129 -96
- package/dist/src/sandbox/macos/seatbeltArgsBuilder.js.map +1 -1
- package/dist/src/sandbox/macos/seatbeltArgsBuilder.test.js +78 -77
- package/dist/src/sandbox/macos/seatbeltArgsBuilder.test.js.map +1 -1
- package/dist/src/sandbox/utils/fsUtils.d.ts +2 -3
- package/dist/src/sandbox/utils/fsUtils.js +12 -27
- package/dist/src/sandbox/utils/fsUtils.js.map +1 -1
- package/dist/src/sandbox/utils/fsUtils.test.js +87 -29
- package/dist/src/sandbox/utils/fsUtils.test.js.map +1 -1
- package/dist/src/sandbox/windows/GeminiSandbox.cs +186 -77
- package/dist/src/sandbox/windows/WindowsSandboxManager.d.ts +4 -16
- package/dist/src/sandbox/windows/WindowsSandboxManager.js +138 -204
- package/dist/src/sandbox/windows/WindowsSandboxManager.js.map +1 -1
- package/dist/src/sandbox/windows/WindowsSandboxManager.test.js +105 -122
- package/dist/src/sandbox/windows/WindowsSandboxManager.test.js.map +1 -1
- package/dist/src/scheduler/policy.js +1 -2
- package/dist/src/scheduler/policy.js.map +1 -1
- package/dist/src/scheduler/policy.test.js +58 -2
- package/dist/src/scheduler/policy.test.js.map +1 -1
- package/dist/src/scheduler/scheduler.d.ts +2 -1
- package/dist/src/scheduler/scheduler.js +13 -14
- package/dist/src/scheduler/scheduler.js.map +1 -1
- package/dist/src/scheduler/scheduler.test.js +66 -0
- package/dist/src/scheduler/scheduler.test.js.map +1 -1
- package/dist/src/scheduler/scheduler_hooks.test.js +1 -0
- package/dist/src/scheduler/scheduler_hooks.test.js.map +1 -1
- package/dist/src/scheduler/scheduler_parallel.test.js +2 -0
- package/dist/src/scheduler/scheduler_parallel.test.js.map +1 -1
- package/dist/src/scheduler/tool-executor.js +2 -0
- package/dist/src/scheduler/tool-executor.js.map +1 -1
- package/dist/src/services/chatRecordingService.d.ts +12 -153
- package/dist/src/services/chatRecordingService.js +444 -350
- package/dist/src/services/chatRecordingService.js.map +1 -1
- package/dist/src/services/chatRecordingService.test.js +174 -128
- package/dist/src/services/chatRecordingService.test.js.map +1 -1
- package/dist/src/services/chatRecordingTypes.d.ts +111 -0
- package/dist/src/services/chatRecordingTypes.js +10 -0
- package/dist/src/services/chatRecordingTypes.js.map +1 -0
- package/dist/src/services/gitService.d.ts +2 -0
- package/dist/src/services/gitService.js +10 -1
- package/dist/src/services/gitService.js.map +1 -1
- package/dist/src/services/gitService.test.js +6 -2
- package/dist/src/services/gitService.test.js.map +1 -1
- package/dist/src/services/keychainService.d.ts +2 -2
- package/dist/src/services/keychainService.js +9 -9
- package/dist/src/services/keychainService.js.map +1 -1
- package/dist/src/services/keychainService.test.js +7 -7
- package/dist/src/services/keychainService.test.js.map +1 -1
- package/dist/src/services/keychainTypes.d.ts +1 -1
- package/dist/src/services/memoryPatchUtils.d.ts +42 -0
- package/dist/src/services/memoryPatchUtils.js +216 -0
- package/dist/src/services/memoryPatchUtils.js.map +1 -0
- package/dist/src/services/memoryService.d.ts +21 -1
- package/dist/src/services/memoryService.js +405 -64
- package/dist/src/services/memoryService.js.map +1 -1
- package/dist/src/services/memoryService.test.js +686 -2
- package/dist/src/services/memoryService.test.js.map +1 -1
- package/dist/src/services/sandboxManager.d.ts +33 -19
- package/dist/src/services/sandboxManager.integration.test.js +728 -266
- package/dist/src/services/sandboxManager.integration.test.js.map +1 -1
- package/dist/src/services/sandboxManager.js +65 -62
- package/dist/src/services/sandboxManager.js.map +1 -1
- package/dist/src/services/sandboxManager.test.js +17 -114
- package/dist/src/services/sandboxManager.test.js.map +1 -1
- package/dist/src/services/sandboxedFileSystemService.js +72 -62
- package/dist/src/services/sandboxedFileSystemService.js.map +1 -1
- package/dist/src/services/sessionSummaryUtils.d.ts +1 -1
- package/dist/src/services/sessionSummaryUtils.js +111 -38
- package/dist/src/services/sessionSummaryUtils.js.map +1 -1
- package/dist/src/services/sessionSummaryUtils.test.js +204 -51
- package/dist/src/services/sessionSummaryUtils.test.js.map +1 -1
- package/dist/src/services/shellExecutionService.d.ts +19 -0
- package/dist/src/services/shellExecutionService.js +88 -34
- package/dist/src/services/shellExecutionService.js.map +1 -1
- package/dist/src/services/shellExecutionService.test.js +38 -4
- package/dist/src/services/shellExecutionService.test.js.map +1 -1
- package/dist/src/telemetry/activity-monitor.js +1 -0
- package/dist/src/telemetry/activity-monitor.js.map +1 -1
- package/dist/src/telemetry/config.js +3 -0
- package/dist/src/telemetry/config.js.map +1 -1
- package/dist/src/telemetry/conseca-logger.js +18 -20
- package/dist/src/telemetry/conseca-logger.js.map +1 -1
- package/dist/src/telemetry/conseca-logger.test.js +100 -0
- package/dist/src/telemetry/conseca-logger.test.js.map +1 -1
- package/dist/src/telemetry/event-loop-monitor.d.ts +17 -0
- package/dist/src/telemetry/event-loop-monitor.js +76 -0
- package/dist/src/telemetry/event-loop-monitor.js.map +1 -0
- package/dist/src/telemetry/index.d.ts +2 -1
- package/dist/src/telemetry/index.js +2 -1
- package/dist/src/telemetry/index.js.map +1 -1
- package/dist/src/telemetry/llmRole.d.ts +2 -1
- package/dist/src/telemetry/llmRole.js +1 -0
- package/dist/src/telemetry/llmRole.js.map +1 -1
- package/dist/src/telemetry/loggers.test.js +184 -8
- package/dist/src/telemetry/loggers.test.js.map +1 -1
- package/dist/src/telemetry/memory-monitor.d.ts +1 -0
- package/dist/src/telemetry/memory-monitor.js +8 -1
- package/dist/src/telemetry/memory-monitor.js.map +1 -1
- package/dist/src/telemetry/memory-monitor.test.js +6 -1
- package/dist/src/telemetry/memory-monitor.test.js.map +1 -1
- package/dist/src/telemetry/metrics.d.ts +12 -0
- package/dist/src/telemetry/metrics.js +19 -0
- package/dist/src/telemetry/metrics.js.map +1 -1
- package/dist/src/telemetry/sdk.js +20 -1
- package/dist/src/telemetry/sdk.js.map +1 -1
- package/dist/src/telemetry/trace.d.ts +23 -6
- package/dist/src/telemetry/trace.js +71 -22
- package/dist/src/telemetry/trace.js.map +1 -1
- package/dist/src/telemetry/trace.test.js +79 -15
- package/dist/src/telemetry/trace.test.js.map +1 -1
- package/dist/src/telemetry/types.js +61 -15
- package/dist/src/telemetry/types.js.map +1 -1
- package/dist/src/test-utils/mock-tool.d.ts +3 -2
- package/dist/src/test-utils/mock-tool.js +4 -3
- package/dist/src/test-utils/mock-tool.js.map +1 -1
- package/dist/src/tools/activate-skill.js +1 -1
- package/dist/src/tools/activate-skill.js.map +1 -1
- package/dist/src/tools/activate-skill.test.js +6 -2
- package/dist/src/tools/activate-skill.test.js.map +1 -1
- package/dist/src/tools/ask-user.d.ts +2 -2
- package/dist/src/tools/ask-user.js +1 -1
- package/dist/src/tools/ask-user.js.map +1 -1
- package/dist/src/tools/ask-user.test.js +9 -3
- package/dist/src/tools/ask-user.test.js.map +1 -1
- package/dist/src/tools/complete-task.d.ts +2 -2
- package/dist/src/tools/complete-task.js +1 -1
- package/dist/src/tools/complete-task.js.map +1 -1
- package/dist/src/tools/complete-task.test.js +9 -3
- package/dist/src/tools/complete-task.test.js.map +1 -1
- package/dist/src/tools/definitions/base-declarations.d.ts +2 -0
- package/dist/src/tools/definitions/base-declarations.js +3 -0
- package/dist/src/tools/definitions/base-declarations.js.map +1 -1
- package/dist/src/tools/definitions/coreTools.d.ts +3 -1
- package/dist/src/tools/definitions/coreTools.js +13 -1
- package/dist/src/tools/definitions/coreTools.js.map +1 -1
- package/dist/src/tools/definitions/model-family-sets/default-legacy.js +29 -1
- 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 +29 -1
- package/dist/src/tools/definitions/model-family-sets/gemini-3.js.map +1 -1
- package/dist/src/tools/definitions/types.d.ts +2 -0
- package/dist/src/tools/edit.js +20 -4
- package/dist/src/tools/edit.js.map +1 -1
- package/dist/src/tools/edit.test.js +41 -18
- package/dist/src/tools/edit.test.js.map +1 -1
- package/dist/src/tools/enter-plan-mode.d.ts +2 -2
- package/dist/src/tools/enter-plan-mode.js +1 -1
- package/dist/src/tools/enter-plan-mode.js.map +1 -1
- package/dist/src/tools/enter-plan-mode.test.js +10 -4
- package/dist/src/tools/enter-plan-mode.test.js.map +1 -1
- package/dist/src/tools/exit-plan-mode.d.ts +2 -2
- package/dist/src/tools/exit-plan-mode.js +9 -12
- package/dist/src/tools/exit-plan-mode.js.map +1 -1
- package/dist/src/tools/exit-plan-mode.test.js +44 -17
- package/dist/src/tools/exit-plan-mode.test.js.map +1 -1
- package/dist/src/tools/get-internal-docs.js +6 -3
- package/dist/src/tools/get-internal-docs.js.map +1 -1
- package/dist/src/tools/get-internal-docs.test.js +4 -4
- package/dist/src/tools/get-internal-docs.test.js.map +1 -1
- package/dist/src/tools/glob.js +1 -1
- package/dist/src/tools/glob.js.map +1 -1
- package/dist/src/tools/glob.test.js +16 -16
- package/dist/src/tools/glob.test.js.map +1 -1
- package/dist/src/tools/grep.js +21 -12
- package/dist/src/tools/grep.js.map +1 -1
- package/dist/src/tools/grep.test.js +18 -18
- package/dist/src/tools/grep.test.js.map +1 -1
- package/dist/src/tools/line-endings.test.js +3 -3
- package/dist/src/tools/line-endings.test.js.map +1 -1
- package/dist/src/tools/list-mcp-resources.d.ts +24 -0
- package/dist/src/tools/list-mcp-resources.js +74 -0
- package/dist/src/tools/list-mcp-resources.js.map +1 -0
- package/dist/src/tools/list-mcp-resources.test.d.ts +6 -0
- package/dist/src/tools/list-mcp-resources.test.js +79 -0
- package/dist/src/tools/list-mcp-resources.test.js.map +1 -0
- package/dist/src/tools/ls.js +2 -2
- package/dist/src/tools/ls.js.map +1 -1
- package/dist/src/tools/ls.test.js +21 -21
- package/dist/src/tools/ls.test.js.map +1 -1
- package/dist/src/tools/mcp-client-manager.d.ts +3 -1
- package/dist/src/tools/mcp-client-manager.js +24 -1
- package/dist/src/tools/mcp-client-manager.js.map +1 -1
- package/dist/src/tools/mcp-client-manager.test.js +43 -0
- package/dist/src/tools/mcp-client-manager.test.js.map +1 -1
- package/dist/src/tools/mcp-client.js +10 -12
- package/dist/src/tools/mcp-client.js.map +1 -1
- package/dist/src/tools/mcp-client.test.js +14 -2
- package/dist/src/tools/mcp-client.test.js.map +1 -1
- package/dist/src/tools/mcp-tool.d.ts +2 -2
- package/dist/src/tools/mcp-tool.js +1 -1
- package/dist/src/tools/mcp-tool.js.map +1 -1
- package/dist/src/tools/mcp-tool.test.js +51 -21
- package/dist/src/tools/mcp-tool.test.js.map +1 -1
- package/dist/src/tools/memoryTool.d.ts +4 -3
- package/dist/src/tools/memoryTool.js +43 -14
- package/dist/src/tools/memoryTool.js.map +1 -1
- package/dist/src/tools/memoryTool.test.js +29 -9
- package/dist/src/tools/memoryTool.test.js.map +1 -1
- package/dist/src/tools/read-file.js +1 -1
- package/dist/src/tools/read-file.js.map +1 -1
- package/dist/src/tools/read-file.test.js +17 -17
- package/dist/src/tools/read-file.test.js.map +1 -1
- package/dist/src/tools/read-many-files.js +4 -4
- package/dist/src/tools/read-many-files.js.map +1 -1
- package/dist/src/tools/read-many-files.test.js +70 -24
- package/dist/src/tools/read-many-files.test.js.map +1 -1
- package/dist/src/tools/read-mcp-resource.d.ts +25 -0
- package/dist/src/tools/read-mcp-resource.js +120 -0
- package/dist/src/tools/read-mcp-resource.js.map +1 -0
- package/dist/src/tools/read-mcp-resource.test.d.ts +6 -0
- package/dist/src/tools/read-mcp-resource.test.js +110 -0
- package/dist/src/tools/read-mcp-resource.test.js.map +1 -0
- package/dist/src/tools/ripGrep.d.ts +3 -2
- package/dist/src/tools/ripGrep.js +26 -55
- package/dist/src/tools/ripGrep.js.map +1 -1
- package/dist/src/tools/ripGrep.test.js +113 -167
- package/dist/src/tools/ripGrep.test.js.map +1 -1
- package/dist/src/tools/shell.d.ts +2 -2
- package/dist/src/tools/shell.js +51 -21
- package/dist/src/tools/shell.js.map +1 -1
- package/dist/src/tools/shell.test.js +479 -76
- package/dist/src/tools/shell.test.js.map +1 -1
- package/dist/src/tools/shellBackgroundTools.d.ts +3 -3
- package/dist/src/tools/shellBackgroundTools.integration.test.js +6 -2
- package/dist/src/tools/shellBackgroundTools.integration.test.js.map +1 -1
- package/dist/src/tools/shellBackgroundTools.js +2 -2
- package/dist/src/tools/shellBackgroundTools.js.map +1 -1
- package/dist/src/tools/shellBackgroundTools.test.js +30 -10
- package/dist/src/tools/shellBackgroundTools.test.js.map +1 -1
- package/dist/src/tools/tool-error.d.ts +1 -0
- package/dist/src/tools/tool-error.js +1 -0
- package/dist/src/tools/tool-error.js.map +1 -1
- package/dist/src/tools/tool-names.d.ts +5 -4
- package/dist/src/tools/tool-names.js +8 -2
- package/dist/src/tools/tool-names.js.map +1 -1
- package/dist/src/tools/tool-registry.js +137 -114
- package/dist/src/tools/tool-registry.js.map +1 -1
- package/dist/src/tools/tool-registry.test.js +3 -1
- package/dist/src/tools/tool-registry.test.js.map +1 -1
- package/dist/src/tools/tools.d.ts +6 -6
- package/dist/src/tools/tools.js +6 -2
- package/dist/src/tools/tools.js.map +1 -1
- package/dist/src/tools/topicTool.d.ts +2 -2
- package/dist/src/tools/topicTool.js +1 -1
- package/dist/src/tools/topicTool.js.map +1 -1
- package/dist/src/tools/topicTool.test.js +6 -2
- package/dist/src/tools/topicTool.test.js.map +1 -1
- package/dist/src/tools/trackerTools.d.ts +7 -7
- package/dist/src/tools/trackerTools.js +6 -6
- package/dist/src/tools/trackerTools.js.map +1 -1
- package/dist/src/tools/web-fetch.js +1 -1
- package/dist/src/tools/web-fetch.js.map +1 -1
- package/dist/src/tools/web-fetch.test.js +59 -23
- package/dist/src/tools/web-fetch.test.js.map +1 -1
- package/dist/src/tools/web-search.js +1 -1
- package/dist/src/tools/web-search.js.map +1 -1
- package/dist/src/tools/web-search.test.js +5 -5
- package/dist/src/tools/web-search.test.js.map +1 -1
- package/dist/src/tools/write-file.js +22 -4
- package/dist/src/tools/write-file.js.map +1 -1
- package/dist/src/tools/write-file.test.js +29 -11
- package/dist/src/tools/write-file.test.js.map +1 -1
- package/dist/src/tools/write-todos.js +1 -1
- package/dist/src/tools/write-todos.js.map +1 -1
- package/dist/src/utils/compatibility.js +6 -1
- package/dist/src/utils/compatibility.js.map +1 -1
- package/dist/src/utils/compatibility.test.js +23 -0
- package/dist/src/utils/compatibility.test.js.map +1 -1
- package/dist/src/utils/errors.d.ts +3 -0
- package/dist/src/utils/errors.js +6 -0
- package/dist/src/utils/errors.js.map +1 -1
- package/dist/src/utils/fileUtils.d.ts +1 -2
- package/dist/src/utils/fileUtils.js +80 -40
- package/dist/src/utils/fileUtils.js.map +1 -1
- package/dist/src/utils/fileUtils.test.js +61 -0
- package/dist/src/utils/fileUtils.test.js.map +1 -1
- package/dist/src/utils/filesearch/fileSearch.d.ts +2 -0
- package/dist/src/utils/filesearch/fileSearch.js +97 -6
- package/dist/src/utils/filesearch/fileSearch.js.map +1 -1
- package/dist/src/utils/filesearch/fileSearch.test.js +54 -0
- package/dist/src/utils/filesearch/fileSearch.test.js.map +1 -1
- package/dist/src/utils/filesearch/fileWatcher.d.ts +25 -0
- package/dist/src/utils/filesearch/fileWatcher.js +86 -0
- package/dist/src/utils/filesearch/fileWatcher.js.map +1 -0
- package/dist/src/utils/filesearch/fileWatcher.test.js +142 -0
- package/dist/src/utils/filesearch/fileWatcher.test.js.map +1 -0
- package/dist/src/utils/getFolderStructure.js +4 -2
- package/dist/src/utils/getFolderStructure.js.map +1 -1
- package/dist/src/utils/gitIgnoreParser.js +1 -1
- package/dist/src/utils/gitIgnoreParser.js.map +1 -1
- package/dist/src/utils/googleQuotaErrors.d.ts +2 -1
- package/dist/src/utils/googleQuotaErrors.js +30 -35
- package/dist/src/utils/googleQuotaErrors.js.map +1 -1
- package/dist/src/utils/googleQuotaErrors.test.js +24 -0
- package/dist/src/utils/googleQuotaErrors.test.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/memoryDiscovery.js +15 -5
- package/dist/src/utils/memoryDiscovery.js.map +1 -1
- package/dist/src/utils/oauth-flow.js +17 -5
- package/dist/src/utils/oauth-flow.js.map +1 -1
- package/dist/src/utils/oauth-flow.test.js +20 -0
- package/dist/src/utils/oauth-flow.test.js.map +1 -1
- package/dist/src/utils/paths.d.ts +9 -0
- package/dist/src/utils/paths.js +37 -0
- package/dist/src/utils/paths.js.map +1 -1
- package/dist/src/utils/paths.test.js +45 -1
- package/dist/src/utils/paths.test.js.map +1 -1
- package/dist/src/utils/planUtils.d.ts +11 -2
- package/dist/src/utils/planUtils.js +43 -11
- package/dist/src/utils/planUtils.js.map +1 -1
- package/dist/src/utils/planUtils.test.js +10 -9
- package/dist/src/utils/planUtils.test.js.map +1 -1
- package/dist/src/utils/process-utils.d.ts +2 -1
- package/dist/src/utils/process-utils.js +64 -33
- package/dist/src/utils/process-utils.js.map +1 -1
- package/dist/src/utils/process-utils.test.js +9 -0
- package/dist/src/utils/process-utils.test.js.map +1 -1
- package/dist/src/utils/retry.js +18 -6
- package/dist/src/utils/retry.js.map +1 -1
- package/dist/src/utils/retry.test.js +30 -0
- package/dist/src/utils/retry.test.js.map +1 -1
- package/dist/src/utils/sessionOperations.js +3 -2
- package/dist/src/utils/sessionOperations.js.map +1 -1
- package/dist/src/utils/shell-utils.d.ts +2 -0
- package/dist/src/utils/shell-utils.js +237 -107
- package/dist/src/utils/shell-utils.js.map +1 -1
- package/dist/src/utils/tool-utils.d.ts +1 -29
- package/dist/src/utils/tool-utils.js +0 -39
- package/dist/src/utils/tool-utils.js.map +1 -1
- package/dist/src/utils/tool-utils.test.js +2 -76
- package/dist/src/utils/tool-utils.test.js.map +1 -1
- package/dist/src/utils/tool-visibility.d.ts +40 -0
- package/dist/src/utils/tool-visibility.js +111 -0
- package/dist/src/utils/tool-visibility.js.map +1 -0
- package/dist/src/utils/tool-visibility.test.d.ts +6 -0
- package/dist/src/utils/tool-visibility.test.js +96 -0
- package/dist/src/utils/tool-visibility.test.js.map +1 -0
- package/dist/src/utils/trust.d.ts +64 -0
- package/dist/src/utils/trust.js +276 -0
- package/dist/src/utils/trust.js.map +1 -0
- package/dist/src/utils/trust.test.d.ts +6 -0
- package/dist/src/utils/trust.test.js +159 -0
- package/dist/src/utils/trust.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -4
- package/dist/docs/get-started/installation.md +0 -181
- package/dist/src/agents/memory-manager-agent.d.ts +0 -25
- package/dist/src/agents/memory-manager-agent.js +0 -138
- package/dist/src/agents/memory-manager-agent.js.map +0 -1
- package/dist/src/agents/memory-manager-agent.test.js +0 -123
- package/dist/src/agents/memory-manager-agent.test.js.map +0 -1
- package/dist/src/agents/subagent-tool-wrapper.d.ts +0 -38
- package/dist/src/agents/subagent-tool-wrapper.js +0 -58
- package/dist/src/agents/subagent-tool-wrapper.js.map +0 -1
- package/dist/src/agents/subagent-tool-wrapper.test.js +0 -123
- package/dist/src/agents/subagent-tool-wrapper.test.js.map +0 -1
- package/dist/src/agents/subagent-tool.d.ts +0 -18
- package/dist/src/agents/subagent-tool.js +0 -134
- package/dist/src/agents/subagent-tool.js.map +0 -1
- package/dist/src/agents/subagent-tool.test.js +0 -287
- package/dist/src/agents/subagent-tool.test.js.map +0 -1
- package/dist/src/policy/policies/tracker.toml +0 -34
- package/dist/src/prompts/snippets-memory-manager.test.js +0 -31
- package/dist/src/prompts/snippets-memory-manager.test.js.map +0 -1
- /package/dist/src/{agents/memory-manager-agent.test.d.ts → agent/tool-display-utils.test.d.ts} +0 -0
- /package/dist/src/agents/{subagent-tool.test.d.ts → agent-tool.test.d.ts} +0 -0
- /package/dist/src/{prompts/snippets-memory-manager.test.d.ts → agents/skill-extraction-agent.test.d.ts} +0 -0
- /package/dist/src/{agents/subagent-tool-wrapper.test.d.ts → utils/filesearch/fileWatcher.test.d.ts} +0 -0
|
@@ -3,36 +3,215 @@
|
|
|
3
3
|
* Copyright 2025 Google LLC
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
-
import {} from '../scheduler/types.js';
|
|
7
6
|
import {} from '../utils/thoughtUtils.js';
|
|
8
7
|
import { getProjectHash } from '../utils/paths.js';
|
|
9
8
|
import path from 'node:path';
|
|
10
|
-
import fs from 'node:fs';
|
|
9
|
+
import * as fs from 'node:fs';
|
|
11
10
|
import { sanitizeFilenamePart } from '../utils/fileUtils.js';
|
|
11
|
+
import { isNodeError } from '../utils/errors.js';
|
|
12
12
|
import { deleteSessionArtifactsAsync, deleteSubagentSessionDirAndArtifactsAsync, } from '../utils/sessionOperations.js';
|
|
13
|
+
import readline from 'node:readline';
|
|
13
14
|
import { randomUUID } from 'node:crypto';
|
|
14
15
|
import { debugLogger } from '../utils/debugLogger.js';
|
|
15
|
-
|
|
16
|
+
import { SESSION_FILE_PREFIX, } from './chatRecordingTypes.js';
|
|
17
|
+
export * from './chatRecordingTypes.js';
|
|
16
18
|
/**
|
|
17
19
|
* Warning message shown when recording is disabled due to disk full.
|
|
18
20
|
*/
|
|
19
21
|
const ENOSPC_WARNING_MESSAGE = 'Chat recording disabled: No space left on device. ' +
|
|
20
22
|
'The conversation will continue but will not be saved to disk. ' +
|
|
21
23
|
'Free up disk space and restart to enable recording.';
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
24
|
+
function hasProperty(obj, prop) {
|
|
25
|
+
return obj !== null && typeof obj === 'object' && prop in obj;
|
|
26
|
+
}
|
|
27
|
+
function isStringProperty(obj, prop) {
|
|
28
|
+
return hasProperty(obj, prop) && typeof obj[prop] === 'string';
|
|
29
|
+
}
|
|
30
|
+
function isObjectProperty(obj, prop) {
|
|
31
|
+
return (hasProperty(obj, prop) &&
|
|
32
|
+
obj[prop] !== null &&
|
|
33
|
+
typeof obj[prop] === 'object');
|
|
34
|
+
}
|
|
35
|
+
function isRewindRecord(record) {
|
|
36
|
+
return isStringProperty(record, '$rewindTo');
|
|
37
|
+
}
|
|
38
|
+
function isMessageRecord(record) {
|
|
39
|
+
return isStringProperty(record, 'id');
|
|
40
|
+
}
|
|
41
|
+
function isMetadataUpdateRecord(record) {
|
|
42
|
+
return isObjectProperty(record, '$set');
|
|
43
|
+
}
|
|
44
|
+
function isPartialMetadataRecord(record) {
|
|
45
|
+
return (isStringProperty(record, 'sessionId') &&
|
|
46
|
+
isStringProperty(record, 'projectHash'));
|
|
47
|
+
}
|
|
48
|
+
function isTextPart(part) {
|
|
49
|
+
return isStringProperty(part, 'text');
|
|
50
|
+
}
|
|
51
|
+
function isSessionIdRecord(record) {
|
|
52
|
+
return isStringProperty(record, 'sessionId');
|
|
53
|
+
}
|
|
54
|
+
export async function loadConversationRecord(filePath, options) {
|
|
55
|
+
if (!fs.existsSync(filePath)) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
const fileStream = fs.createReadStream(filePath);
|
|
60
|
+
const rl = readline.createInterface({
|
|
61
|
+
input: fileStream,
|
|
62
|
+
crlfDelay: Infinity,
|
|
63
|
+
});
|
|
64
|
+
let metadata = {};
|
|
65
|
+
const messagesMap = new Map();
|
|
66
|
+
const messageIds = [];
|
|
67
|
+
const messageKinds = new Map();
|
|
68
|
+
let firstUserMessageStr;
|
|
69
|
+
for await (const line of rl) {
|
|
70
|
+
if (!line.trim())
|
|
71
|
+
continue;
|
|
72
|
+
try {
|
|
73
|
+
const record = JSON.parse(line);
|
|
74
|
+
if (isRewindRecord(record)) {
|
|
75
|
+
const rewindId = record.$rewindTo;
|
|
76
|
+
if (options?.metadataOnly) {
|
|
77
|
+
const idx = messageIds.indexOf(rewindId);
|
|
78
|
+
if (idx !== -1) {
|
|
79
|
+
const removedIds = messageIds.splice(idx);
|
|
80
|
+
for (const removedId of removedIds) {
|
|
81
|
+
messageKinds.delete(removedId);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
messageIds.length = 0;
|
|
86
|
+
messageKinds.clear();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
let found = false;
|
|
91
|
+
const idsToDelete = [];
|
|
92
|
+
for (const [id] of messagesMap) {
|
|
93
|
+
if (id === rewindId)
|
|
94
|
+
found = true;
|
|
95
|
+
if (found)
|
|
96
|
+
idsToDelete.push(id);
|
|
97
|
+
}
|
|
98
|
+
if (found) {
|
|
99
|
+
for (const id of idsToDelete) {
|
|
100
|
+
messagesMap.delete(id);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
messagesMap.clear();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
else if (isMessageRecord(record)) {
|
|
109
|
+
const id = record.id;
|
|
110
|
+
const isUser = hasProperty(record, 'type') && record.type === 'user';
|
|
111
|
+
const isUserOrAssistant = hasProperty(record, 'type') &&
|
|
112
|
+
(record.type === 'user' || record.type === 'gemini');
|
|
113
|
+
// Track message count and first user message
|
|
114
|
+
if (options?.metadataOnly) {
|
|
115
|
+
messageIds.push(id);
|
|
116
|
+
messageKinds.set(id, { isUser, isUserOrAssistant });
|
|
117
|
+
}
|
|
118
|
+
if (!firstUserMessageStr &&
|
|
119
|
+
isUser &&
|
|
120
|
+
hasProperty(record, 'content') &&
|
|
121
|
+
record['content']) {
|
|
122
|
+
// Basic extraction of first user message for display
|
|
123
|
+
const rawContent = record['content'];
|
|
124
|
+
if (Array.isArray(rawContent)) {
|
|
125
|
+
firstUserMessageStr = rawContent
|
|
126
|
+
.map((p) => (isTextPart(p) ? p['text'] : ''))
|
|
127
|
+
.join('');
|
|
128
|
+
}
|
|
129
|
+
else if (typeof rawContent === 'string') {
|
|
130
|
+
firstUserMessageStr = rawContent;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (!options?.metadataOnly) {
|
|
134
|
+
messagesMap.set(id, record);
|
|
135
|
+
if (options?.maxMessages &&
|
|
136
|
+
messagesMap.size > options.maxMessages) {
|
|
137
|
+
const firstKey = messagesMap.keys().next().value;
|
|
138
|
+
if (typeof firstKey === 'string')
|
|
139
|
+
messagesMap.delete(firstKey);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
else if (isMetadataUpdateRecord(record)) {
|
|
144
|
+
// Metadata update
|
|
145
|
+
metadata = {
|
|
146
|
+
...metadata,
|
|
147
|
+
...record.$set,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
else if (isPartialMetadataRecord(record)) {
|
|
151
|
+
// Initial metadata line
|
|
152
|
+
metadata = { ...metadata, ...record };
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
// ignore parse errors on individual lines
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (!metadata.sessionId || !metadata.projectHash) {
|
|
160
|
+
return await parseLegacyRecordFallback(filePath, options);
|
|
161
|
+
}
|
|
162
|
+
const metadataMessages = Array.isArray(metadata.messages)
|
|
163
|
+
? metadata.messages
|
|
164
|
+
: [];
|
|
165
|
+
const loadedMessages = metadataMessages.length > 0
|
|
166
|
+
? metadataMessages
|
|
167
|
+
: Array.from(messagesMap.values());
|
|
168
|
+
const metadataFirstUserMessage = metadataMessages.find((message) => message.type === 'user') ?? null;
|
|
169
|
+
let fallbackFirstUserMessage = firstUserMessageStr;
|
|
170
|
+
if (!fallbackFirstUserMessage && metadataFirstUserMessage) {
|
|
171
|
+
const rawContent = metadataFirstUserMessage.content;
|
|
172
|
+
if (Array.isArray(rawContent)) {
|
|
173
|
+
fallbackFirstUserMessage = rawContent
|
|
174
|
+
.map((part) => (isTextPart(part) ? part['text'] : ''))
|
|
175
|
+
.join('');
|
|
176
|
+
}
|
|
177
|
+
else if (typeof rawContent === 'string') {
|
|
178
|
+
fallbackFirstUserMessage = rawContent;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
const userMessageCount = options?.metadataOnly
|
|
182
|
+
? Array.from(messageKinds.values()).filter((m) => m.isUser).length
|
|
183
|
+
: loadedMessages.filter((m) => m.type === 'user').length;
|
|
184
|
+
const hasUserOrAssistant = options?.metadataOnly
|
|
185
|
+
? Array.from(messageKinds.values()).some((m) => m.isUserOrAssistant)
|
|
186
|
+
: loadedMessages.some((m) => m.type === 'user' || m.type === 'gemini');
|
|
187
|
+
return {
|
|
188
|
+
sessionId: metadata.sessionId,
|
|
189
|
+
projectHash: metadata.projectHash,
|
|
190
|
+
startTime: metadata.startTime || new Date().toISOString(),
|
|
191
|
+
lastUpdated: metadata.lastUpdated || new Date().toISOString(),
|
|
192
|
+
summary: metadata.summary,
|
|
193
|
+
directories: metadata.directories,
|
|
194
|
+
kind: metadata.kind,
|
|
195
|
+
messages: options?.metadataOnly ? [] : loadedMessages,
|
|
196
|
+
messageCount: options?.metadataOnly
|
|
197
|
+
? metadataMessages.length || messageIds.length
|
|
198
|
+
: loadedMessages.length,
|
|
199
|
+
userMessageCount: options?.metadataOnly && metadataMessages.length > 0
|
|
200
|
+
? metadataMessages.filter((m) => m.type === 'user').length
|
|
201
|
+
: userMessageCount,
|
|
202
|
+
firstUserMessage: fallbackFirstUserMessage,
|
|
203
|
+
hasUserOrAssistantMessage: options?.metadataOnly && metadataMessages.length > 0
|
|
204
|
+
? metadataMessages.some((m) => m.type === 'user' || m.type === 'gemini')
|
|
205
|
+
: hasUserOrAssistant,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
debugLogger.error('Error loading conversation record from JSONL:', error);
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
33
213
|
export class ChatRecordingService {
|
|
34
214
|
conversationFile = null;
|
|
35
|
-
cachedLastConvData = null;
|
|
36
215
|
cachedConversation = null;
|
|
37
216
|
sessionId;
|
|
38
217
|
projectHash;
|
|
@@ -45,28 +224,40 @@ export class ChatRecordingService {
|
|
|
45
224
|
this.sessionId = context.promptId;
|
|
46
225
|
this.projectHash = getProjectHash(context.config.getProjectRoot());
|
|
47
226
|
}
|
|
48
|
-
|
|
49
|
-
* Initializes the chat recording service: creates a new conversation file and associates it with
|
|
50
|
-
* this service instance, or resumes from an existing session if resumedSessionData is provided.
|
|
51
|
-
*
|
|
52
|
-
* @param resumedSessionData Data from a previous session to resume from.
|
|
53
|
-
* @param kind The kind of conversation (main or subagent).
|
|
54
|
-
*/
|
|
55
|
-
initialize(resumedSessionData, kind) {
|
|
227
|
+
async initialize(resumedSessionData, kind) {
|
|
56
228
|
try {
|
|
57
229
|
this.kind = kind;
|
|
58
230
|
if (resumedSessionData) {
|
|
59
|
-
// Resume from existing session
|
|
60
231
|
this.conversationFile = resumedSessionData.filePath;
|
|
61
232
|
this.sessionId = resumedSessionData.conversation.sessionId;
|
|
62
233
|
this.kind = resumedSessionData.conversation.kind;
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
234
|
+
const loadedRecord = await loadConversationRecord(this.conversationFile);
|
|
235
|
+
if (loadedRecord) {
|
|
236
|
+
this.cachedConversation = loadedRecord;
|
|
237
|
+
this.projectHash = this.cachedConversation.projectHash;
|
|
238
|
+
if (this.conversationFile.endsWith('.json')) {
|
|
239
|
+
this.conversationFile = this.conversationFile + 'l'; // e.g. session-foo.jsonl
|
|
240
|
+
// Migrate the entire legacy record to the new file
|
|
241
|
+
const initialMetadata = {
|
|
242
|
+
sessionId: this.sessionId,
|
|
243
|
+
projectHash: this.projectHash,
|
|
244
|
+
startTime: this.cachedConversation.startTime,
|
|
245
|
+
lastUpdated: this.cachedConversation.lastUpdated,
|
|
246
|
+
kind: this.cachedConversation.kind,
|
|
247
|
+
directories: this.cachedConversation.directories,
|
|
248
|
+
summary: this.cachedConversation.summary,
|
|
249
|
+
};
|
|
250
|
+
this.appendRecord(initialMetadata);
|
|
251
|
+
for (const msg of this.cachedConversation.messages) {
|
|
252
|
+
this.appendRecord(msg);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
// Update the session ID in the existing file
|
|
256
|
+
this.updateMetadata({ sessionId: this.sessionId });
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
throw new Error('Failed to load resumed session data from file');
|
|
260
|
+
}
|
|
70
261
|
}
|
|
71
262
|
else {
|
|
72
263
|
// Create new session
|
|
@@ -91,10 +282,10 @@ export class ChatRecordingService {
|
|
|
91
282
|
}
|
|
92
283
|
let filename;
|
|
93
284
|
if (this.kind === 'subagent') {
|
|
94
|
-
filename = `${safeSessionId}.
|
|
285
|
+
filename = `${safeSessionId}.jsonl`;
|
|
95
286
|
}
|
|
96
287
|
else {
|
|
97
|
-
filename = `${SESSION_FILE_PREFIX}${timestamp}-${safeSessionId.slice(0, 8)}.
|
|
288
|
+
filename = `${SESSION_FILE_PREFIX}${timestamp}-${safeSessionId.slice(0, 8)}.jsonl`;
|
|
98
289
|
}
|
|
99
290
|
this.conversationFile = path.join(chatsDir, filename);
|
|
100
291
|
const directories = this.kind === 'subagent'
|
|
@@ -104,34 +295,71 @@ export class ChatRecordingService {
|
|
|
104
295
|
?.getDirectories() ?? []),
|
|
105
296
|
]
|
|
106
297
|
: undefined;
|
|
107
|
-
|
|
298
|
+
const initialMetadata = {
|
|
108
299
|
sessionId: this.sessionId,
|
|
109
300
|
projectHash: this.projectHash,
|
|
110
301
|
startTime: new Date().toISOString(),
|
|
111
302
|
lastUpdated: new Date().toISOString(),
|
|
112
|
-
messages: [],
|
|
113
|
-
directories,
|
|
114
303
|
kind: this.kind,
|
|
115
|
-
|
|
304
|
+
directories,
|
|
305
|
+
};
|
|
306
|
+
this.appendRecord(initialMetadata);
|
|
307
|
+
this.cachedConversation = {
|
|
308
|
+
...initialMetadata,
|
|
309
|
+
messages: [],
|
|
310
|
+
};
|
|
116
311
|
}
|
|
117
|
-
// Clear any queued data since this is a fresh start
|
|
118
312
|
this.queuedThoughts = [];
|
|
119
313
|
this.queuedTokens = null;
|
|
120
314
|
}
|
|
121
315
|
catch (error) {
|
|
122
|
-
|
|
123
|
-
if (error instanceof Error &&
|
|
124
|
-
'code' in error &&
|
|
125
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
126
|
-
error.code === 'ENOSPC') {
|
|
316
|
+
if (isNodeError(error) && error.code === 'ENOSPC') {
|
|
127
317
|
this.conversationFile = null;
|
|
128
318
|
debugLogger.warn(ENOSPC_WARNING_MESSAGE);
|
|
129
|
-
return;
|
|
319
|
+
return;
|
|
130
320
|
}
|
|
131
321
|
debugLogger.error('Error initializing chat recording service:', error);
|
|
132
322
|
throw error;
|
|
133
323
|
}
|
|
134
324
|
}
|
|
325
|
+
appendRecord(record) {
|
|
326
|
+
if (!this.conversationFile)
|
|
327
|
+
return;
|
|
328
|
+
try {
|
|
329
|
+
const line = JSON.stringify(record) + '\n';
|
|
330
|
+
fs.mkdirSync(path.dirname(this.conversationFile), { recursive: true });
|
|
331
|
+
fs.appendFileSync(this.conversationFile, line);
|
|
332
|
+
}
|
|
333
|
+
catch (error) {
|
|
334
|
+
if (isNodeError(error) && error.code === 'ENOSPC') {
|
|
335
|
+
this.conversationFile = null;
|
|
336
|
+
debugLogger.warn(ENOSPC_WARNING_MESSAGE);
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
throw error;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
updateMetadata(updates) {
|
|
344
|
+
if (!this.cachedConversation)
|
|
345
|
+
return;
|
|
346
|
+
Object.assign(this.cachedConversation, updates);
|
|
347
|
+
this.appendRecord({ $set: updates });
|
|
348
|
+
}
|
|
349
|
+
pushMessage(msg) {
|
|
350
|
+
if (!this.cachedConversation)
|
|
351
|
+
return;
|
|
352
|
+
// We append the full message to the log
|
|
353
|
+
this.appendRecord(msg);
|
|
354
|
+
// Now update memory
|
|
355
|
+
const index = this.cachedConversation.messages.findIndex((m) => m.id === msg.id);
|
|
356
|
+
if (index !== -1) {
|
|
357
|
+
this.cachedConversation.messages[index] = msg;
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
this.cachedConversation.messages.push(msg);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
135
363
|
getLastMessage(conversation) {
|
|
136
364
|
return conversation.messages.at(-1);
|
|
137
365
|
}
|
|
@@ -144,59 +372,36 @@ export class ChatRecordingService {
|
|
|
144
372
|
displayContent,
|
|
145
373
|
};
|
|
146
374
|
}
|
|
147
|
-
/**
|
|
148
|
-
* Records a message in the conversation.
|
|
149
|
-
*/
|
|
150
375
|
recordMessage(message) {
|
|
151
|
-
if (!this.conversationFile)
|
|
376
|
+
if (!this.conversationFile || !this.cachedConversation)
|
|
152
377
|
return;
|
|
153
378
|
try {
|
|
154
|
-
this.
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
this.queuedThoughts = [];
|
|
165
|
-
this.queuedTokens = null;
|
|
166
|
-
}
|
|
167
|
-
else {
|
|
168
|
-
// Or else just add it.
|
|
169
|
-
conversation.messages.push(msg);
|
|
170
|
-
}
|
|
171
|
-
});
|
|
379
|
+
const msg = this.newMessage(message.type, message.content, message.displayContent);
|
|
380
|
+
if (msg.type === 'gemini') {
|
|
381
|
+
msg.thoughts = this.queuedThoughts;
|
|
382
|
+
msg.tokens = this.queuedTokens;
|
|
383
|
+
msg.model = message.model;
|
|
384
|
+
this.queuedThoughts = [];
|
|
385
|
+
this.queuedTokens = null;
|
|
386
|
+
}
|
|
387
|
+
this.pushMessage(msg);
|
|
388
|
+
this.updateMetadata({ lastUpdated: new Date().toISOString() });
|
|
172
389
|
}
|
|
173
390
|
catch (error) {
|
|
174
391
|
debugLogger.error('Error saving message to chat history.', error);
|
|
175
392
|
throw error;
|
|
176
393
|
}
|
|
177
394
|
}
|
|
178
|
-
/**
|
|
179
|
-
* Records a thought from the assistant's reasoning process.
|
|
180
|
-
*/
|
|
181
395
|
recordThought(thought) {
|
|
182
396
|
if (!this.conversationFile)
|
|
183
397
|
return;
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
catch (error) {
|
|
191
|
-
debugLogger.error('Error saving thought to chat history.', error);
|
|
192
|
-
throw error;
|
|
193
|
-
}
|
|
398
|
+
this.queuedThoughts.push({
|
|
399
|
+
...thought,
|
|
400
|
+
timestamp: new Date().toISOString(),
|
|
401
|
+
});
|
|
194
402
|
}
|
|
195
|
-
/**
|
|
196
|
-
* Updates the tokens for the last message in the conversation (which should be by Gemini).
|
|
197
|
-
*/
|
|
198
403
|
recordMessageTokens(respUsageMetadata) {
|
|
199
|
-
if (!this.conversationFile)
|
|
404
|
+
if (!this.conversationFile || !this.cachedConversation)
|
|
200
405
|
return;
|
|
201
406
|
try {
|
|
202
407
|
const tokens = {
|
|
@@ -207,18 +412,13 @@ export class ChatRecordingService {
|
|
|
207
412
|
tool: respUsageMetadata.toolUsePromptTokenCount ?? 0,
|
|
208
413
|
total: respUsageMetadata.totalTokenCount ?? 0,
|
|
209
414
|
};
|
|
210
|
-
const
|
|
211
|
-
const lastMsg = this.getLastMessage(conversation);
|
|
212
|
-
// If the last message already has token info, it's because this new token info is for a
|
|
213
|
-
// new message that hasn't been recorded yet.
|
|
415
|
+
const lastMsg = this.getLastMessage(this.cachedConversation);
|
|
214
416
|
if (lastMsg && lastMsg.type === 'gemini' && !lastMsg.tokens) {
|
|
215
417
|
lastMsg.tokens = tokens;
|
|
216
418
|
this.queuedTokens = null;
|
|
217
|
-
this.
|
|
419
|
+
this.pushMessage(lastMsg);
|
|
218
420
|
}
|
|
219
421
|
else {
|
|
220
|
-
// Only queue tokens in memory; no disk I/O needed since the
|
|
221
|
-
// conversation record itself hasn't changed.
|
|
222
422
|
this.queuedTokens = tokens;
|
|
223
423
|
}
|
|
224
424
|
}
|
|
@@ -227,14 +427,9 @@ export class ChatRecordingService {
|
|
|
227
427
|
throw error;
|
|
228
428
|
}
|
|
229
429
|
}
|
|
230
|
-
/**
|
|
231
|
-
* Adds tool calls to the last message in the conversation (which should be by Gemini).
|
|
232
|
-
* This method enriches tool calls with metadata from the ToolRegistry.
|
|
233
|
-
*/
|
|
234
430
|
recordToolCalls(model, toolCalls) {
|
|
235
|
-
if (!this.conversationFile)
|
|
431
|
+
if (!this.conversationFile || !this.cachedConversation)
|
|
236
432
|
return;
|
|
237
|
-
// Enrich tool calls with metadata from the ToolRegistry
|
|
238
433
|
const toolRegistry = this.context.toolRegistry;
|
|
239
434
|
const enrichedToolCalls = toolCalls.map((toolCall) => {
|
|
240
435
|
const toolInstance = toolRegistry.getTool(toolCall.name);
|
|
@@ -246,225 +441,79 @@ export class ChatRecordingService {
|
|
|
246
441
|
};
|
|
247
442
|
});
|
|
248
443
|
try {
|
|
249
|
-
this.
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
// This isn't strictly necessary, but TypeScript apparently can't
|
|
264
|
-
// tell that the first parameter to newMessage() becomes the
|
|
265
|
-
// resulting message's type, and so it thinks that toolCalls may
|
|
266
|
-
// not be present. Confirming the type here satisfies it.
|
|
267
|
-
type: 'gemini',
|
|
268
|
-
toolCalls: enrichedToolCalls,
|
|
269
|
-
thoughts: this.queuedThoughts,
|
|
270
|
-
model,
|
|
271
|
-
};
|
|
272
|
-
// If there are any queued thoughts join them to this message.
|
|
273
|
-
if (this.queuedThoughts.length > 0) {
|
|
274
|
-
newMsg.thoughts = this.queuedThoughts;
|
|
275
|
-
this.queuedThoughts = [];
|
|
276
|
-
}
|
|
277
|
-
// If there's any queued tokens info join it to this message.
|
|
278
|
-
if (this.queuedTokens) {
|
|
279
|
-
newMsg.tokens = this.queuedTokens;
|
|
280
|
-
this.queuedTokens = null;
|
|
281
|
-
}
|
|
282
|
-
conversation.messages.push(newMsg);
|
|
444
|
+
const lastMsg = this.getLastMessage(this.cachedConversation);
|
|
445
|
+
if (!lastMsg ||
|
|
446
|
+
lastMsg.type !== 'gemini' ||
|
|
447
|
+
this.queuedThoughts.length > 0) {
|
|
448
|
+
const newMsg = {
|
|
449
|
+
...this.newMessage('gemini', ''),
|
|
450
|
+
type: 'gemini',
|
|
451
|
+
toolCalls: enrichedToolCalls,
|
|
452
|
+
thoughts: this.queuedThoughts,
|
|
453
|
+
model,
|
|
454
|
+
};
|
|
455
|
+
if (this.queuedThoughts.length > 0) {
|
|
456
|
+
newMsg.thoughts = this.queuedThoughts;
|
|
457
|
+
this.queuedThoughts = [];
|
|
283
458
|
}
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
459
|
+
if (this.queuedTokens) {
|
|
460
|
+
newMsg.tokens = this.queuedTokens;
|
|
461
|
+
this.queuedTokens = null;
|
|
462
|
+
}
|
|
463
|
+
this.pushMessage(newMsg);
|
|
464
|
+
}
|
|
465
|
+
else {
|
|
466
|
+
if (!lastMsg.toolCalls) {
|
|
467
|
+
lastMsg.toolCalls = [];
|
|
468
|
+
}
|
|
469
|
+
// Deep clone toolCalls to avoid modifying memory references directly
|
|
470
|
+
const updatedToolCalls = [...lastMsg.toolCalls];
|
|
471
|
+
for (const toolCall of enrichedToolCalls) {
|
|
472
|
+
const index = updatedToolCalls.findIndex((tc) => tc.id === toolCall.id);
|
|
473
|
+
if (index !== -1) {
|
|
474
|
+
updatedToolCalls[index] = {
|
|
475
|
+
...updatedToolCalls[index],
|
|
476
|
+
...toolCall,
|
|
477
|
+
};
|
|
289
478
|
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
const incomingToolCall = toolCalls.find((tc) => tc.id === toolCall.id);
|
|
293
|
-
if (incomingToolCall) {
|
|
294
|
-
// Merge in the new data to keep preserve thoughts, etc., that were assigned to older
|
|
295
|
-
// versions of the tool call.
|
|
296
|
-
return { ...toolCall, ...incomingToolCall };
|
|
297
|
-
}
|
|
298
|
-
else {
|
|
299
|
-
return toolCall;
|
|
300
|
-
}
|
|
301
|
-
});
|
|
302
|
-
// Add any new tools calls that aren't in the message yet.
|
|
303
|
-
for (const toolCall of enrichedToolCalls) {
|
|
304
|
-
const existingToolCall = lastMsg.toolCalls.find((tc) => tc.id === toolCall.id);
|
|
305
|
-
if (!existingToolCall) {
|
|
306
|
-
lastMsg.toolCalls.push(toolCall);
|
|
307
|
-
}
|
|
479
|
+
else {
|
|
480
|
+
updatedToolCalls.push(toolCall);
|
|
308
481
|
}
|
|
309
482
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
catch (error) {
|
|
313
|
-
debugLogger.error('Error adding tool call to message in chat history.', error);
|
|
314
|
-
throw error;
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
/**
|
|
318
|
-
* Loads up the conversation record from disk.
|
|
319
|
-
*
|
|
320
|
-
* NOTE: The returned object is the live in-memory cache reference.
|
|
321
|
-
* Any mutations to it will be visible to all subsequent reads.
|
|
322
|
-
* Callers that mutate the result MUST call writeConversation() to
|
|
323
|
-
* persist the changes to disk.
|
|
324
|
-
*/
|
|
325
|
-
readConversation() {
|
|
326
|
-
if (this.cachedConversation) {
|
|
327
|
-
return this.cachedConversation;
|
|
328
|
-
}
|
|
329
|
-
try {
|
|
330
|
-
this.cachedLastConvData = fs.readFileSync(this.conversationFile, 'utf8');
|
|
331
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
332
|
-
this.cachedConversation = JSON.parse(this.cachedLastConvData);
|
|
333
|
-
if (!this.cachedConversation) {
|
|
334
|
-
// File is corrupt or contains "null". Fallback to an empty conversation.
|
|
335
|
-
this.cachedConversation = {
|
|
336
|
-
sessionId: this.sessionId,
|
|
337
|
-
projectHash: this.projectHash,
|
|
338
|
-
startTime: new Date().toISOString(),
|
|
339
|
-
lastUpdated: new Date().toISOString(),
|
|
340
|
-
messages: [],
|
|
341
|
-
kind: this.kind,
|
|
342
|
-
};
|
|
343
|
-
}
|
|
344
|
-
return this.cachedConversation;
|
|
345
|
-
}
|
|
346
|
-
catch (error) {
|
|
347
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
348
|
-
if (error.code !== 'ENOENT') {
|
|
349
|
-
debugLogger.error('Error reading conversation file.', error);
|
|
350
|
-
throw error;
|
|
483
|
+
lastMsg.toolCalls = updatedToolCalls;
|
|
484
|
+
this.pushMessage(lastMsg);
|
|
351
485
|
}
|
|
352
|
-
// Placeholder empty conversation if file doesn't exist.
|
|
353
|
-
this.cachedConversation = {
|
|
354
|
-
sessionId: this.sessionId,
|
|
355
|
-
projectHash: this.projectHash,
|
|
356
|
-
startTime: new Date().toISOString(),
|
|
357
|
-
lastUpdated: new Date().toISOString(),
|
|
358
|
-
messages: [],
|
|
359
|
-
kind: this.kind,
|
|
360
|
-
};
|
|
361
|
-
return this.cachedConversation;
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
/**
|
|
365
|
-
* Saves the conversation record; overwrites the file.
|
|
366
|
-
*/
|
|
367
|
-
writeConversation(conversation, { allowEmpty = false } = {}) {
|
|
368
|
-
try {
|
|
369
|
-
if (!this.conversationFile)
|
|
370
|
-
return;
|
|
371
|
-
// Cache the conversation state even if we don't write to disk yet.
|
|
372
|
-
// This ensures that subsequent reads (e.g. during recordMessage)
|
|
373
|
-
// see the initial state (like directories) instead of trying to
|
|
374
|
-
// read a non-existent file from disk.
|
|
375
|
-
this.cachedConversation = conversation;
|
|
376
|
-
// Don't write the file yet until there's at least one message.
|
|
377
|
-
if (conversation.messages.length === 0 && !allowEmpty)
|
|
378
|
-
return;
|
|
379
|
-
const newContent = JSON.stringify(conversation, null, 2);
|
|
380
|
-
// Skip the disk write if nothing actually changed (e.g.
|
|
381
|
-
// updateMessagesFromHistory found no matching tool calls to update).
|
|
382
|
-
// Compare before updating lastUpdated so the timestamp doesn't
|
|
383
|
-
// cause a false diff.
|
|
384
|
-
if (this.cachedLastConvData === newContent)
|
|
385
|
-
return;
|
|
386
|
-
conversation.lastUpdated = new Date().toISOString();
|
|
387
|
-
const contentToWrite = JSON.stringify(conversation, null, 2);
|
|
388
|
-
this.cachedLastConvData = contentToWrite;
|
|
389
|
-
// Ensure directory exists before writing (handles cases where temp dir was cleaned)
|
|
390
|
-
fs.mkdirSync(path.dirname(this.conversationFile), { recursive: true });
|
|
391
|
-
fs.writeFileSync(this.conversationFile, contentToWrite);
|
|
392
486
|
}
|
|
393
487
|
catch (error) {
|
|
394
|
-
|
|
395
|
-
if (error instanceof Error &&
|
|
396
|
-
'code' in error &&
|
|
397
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
|
398
|
-
error.code === 'ENOSPC') {
|
|
399
|
-
this.conversationFile = null;
|
|
400
|
-
this.cachedConversation = null;
|
|
401
|
-
debugLogger.warn(ENOSPC_WARNING_MESSAGE);
|
|
402
|
-
return; // Don't throw - allow the conversation to continue
|
|
403
|
-
}
|
|
404
|
-
debugLogger.error('Error writing conversation file.', error);
|
|
488
|
+
debugLogger.error('Error adding tool call to message in chat history.', error);
|
|
405
489
|
throw error;
|
|
406
490
|
}
|
|
407
491
|
}
|
|
408
|
-
/**
|
|
409
|
-
* Convenient helper for updating the conversation without file reading and writing and time
|
|
410
|
-
* updating boilerplate.
|
|
411
|
-
*/
|
|
412
|
-
updateConversation(updateFn) {
|
|
413
|
-
const conversation = this.readConversation();
|
|
414
|
-
updateFn(conversation);
|
|
415
|
-
this.writeConversation(conversation);
|
|
416
|
-
}
|
|
417
|
-
/**
|
|
418
|
-
* Saves a summary for the current session.
|
|
419
|
-
*/
|
|
420
492
|
saveSummary(summary) {
|
|
421
493
|
if (!this.conversationFile)
|
|
422
494
|
return;
|
|
423
495
|
try {
|
|
424
|
-
this.
|
|
425
|
-
conversation.summary = summary;
|
|
426
|
-
});
|
|
496
|
+
this.updateMetadata({ summary });
|
|
427
497
|
}
|
|
428
498
|
catch (error) {
|
|
429
499
|
debugLogger.error('Error saving summary to chat history.', error);
|
|
430
|
-
// Don't throw - we want graceful degradation
|
|
431
500
|
}
|
|
432
501
|
}
|
|
433
|
-
/**
|
|
434
|
-
* Records workspace directories to the session file.
|
|
435
|
-
* Called when directories are added via /dir add.
|
|
436
|
-
*/
|
|
437
502
|
recordDirectories(directories) {
|
|
438
503
|
if (!this.conversationFile)
|
|
439
504
|
return;
|
|
440
505
|
try {
|
|
441
|
-
this.
|
|
442
|
-
conversation.directories = [...directories];
|
|
443
|
-
});
|
|
506
|
+
this.updateMetadata({ directories: [...directories] });
|
|
444
507
|
}
|
|
445
508
|
catch (error) {
|
|
446
509
|
debugLogger.error('Error saving directories to chat history.', error);
|
|
447
|
-
// Don't throw - we want graceful degradation
|
|
448
510
|
}
|
|
449
511
|
}
|
|
450
|
-
/**
|
|
451
|
-
* Gets the current conversation data (for summary generation).
|
|
452
|
-
*/
|
|
453
512
|
getConversation() {
|
|
454
513
|
if (!this.conversationFile)
|
|
455
514
|
return null;
|
|
456
|
-
|
|
457
|
-
return this.readConversation();
|
|
458
|
-
}
|
|
459
|
-
catch (error) {
|
|
460
|
-
debugLogger.error('Error reading conversation for summary.', error);
|
|
461
|
-
return null;
|
|
462
|
-
}
|
|
515
|
+
return this.cachedConversation;
|
|
463
516
|
}
|
|
464
|
-
/**
|
|
465
|
-
* Gets the path to the current conversation file.
|
|
466
|
-
* Returns null if the service hasn't been initialized yet or recording is disabled.
|
|
467
|
-
*/
|
|
468
517
|
getConversationFilePath() {
|
|
469
518
|
return this.conversationFile;
|
|
470
519
|
}
|
|
@@ -484,7 +533,7 @@ export class ChatRecordingService {
|
|
|
484
533
|
if (!(await fs.promises.stat(chatsDir).catch(() => null))) {
|
|
485
534
|
return; // Nothing to delete
|
|
486
535
|
}
|
|
487
|
-
const matchingFiles = this.getMatchingSessionFiles(chatsDir, shortId);
|
|
536
|
+
const matchingFiles = await this.getMatchingSessionFiles(chatsDir, shortId);
|
|
488
537
|
for (const file of matchingFiles) {
|
|
489
538
|
await this.deleteSessionAndArtifacts(chatsDir, file, tempDir);
|
|
490
539
|
}
|
|
@@ -494,13 +543,10 @@ export class ChatRecordingService {
|
|
|
494
543
|
throw error;
|
|
495
544
|
}
|
|
496
545
|
}
|
|
497
|
-
/**
|
|
498
|
-
* Derives an 8-character shortId from a sessionId, filename, or basename.
|
|
499
|
-
*/
|
|
500
546
|
deriveShortId(sessionIdOrBasename) {
|
|
501
547
|
let shortId = sessionIdOrBasename;
|
|
502
548
|
if (sessionIdOrBasename.startsWith(SESSION_FILE_PREFIX)) {
|
|
503
|
-
const withoutExt = sessionIdOrBasename.replace(
|
|
549
|
+
const withoutExt = sessionIdOrBasename.replace(/\.jsonl?$/, '');
|
|
504
550
|
const parts = withoutExt.split('-');
|
|
505
551
|
shortId = parts[parts.length - 1];
|
|
506
552
|
}
|
|
@@ -515,12 +561,10 @@ export class ChatRecordingService {
|
|
|
515
561
|
}
|
|
516
562
|
return shortId;
|
|
517
563
|
}
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
const files = fs.readdirSync(chatsDir);
|
|
523
|
-
return files.filter((f) => f.startsWith(SESSION_FILE_PREFIX) && f.endsWith(`-${shortId}.json`));
|
|
564
|
+
async getMatchingSessionFiles(chatsDir, shortId) {
|
|
565
|
+
const files = await fs.promises.readdir(chatsDir);
|
|
566
|
+
return files.filter((f) => f.startsWith(SESSION_FILE_PREFIX) &&
|
|
567
|
+
(f.endsWith(`-${shortId}.json`) || f.endsWith(`-${shortId}.jsonl`)));
|
|
524
568
|
}
|
|
525
569
|
/**
|
|
526
570
|
* Deletes a single session file and its associated logs, tool-outputs, and directory.
|
|
@@ -528,15 +572,35 @@ export class ChatRecordingService {
|
|
|
528
572
|
async deleteSessionAndArtifacts(chatsDir, file, tempDir) {
|
|
529
573
|
const filePath = path.join(chatsDir, file);
|
|
530
574
|
try {
|
|
531
|
-
const
|
|
532
|
-
const
|
|
533
|
-
let
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
575
|
+
const CHUNK_SIZE = 4096;
|
|
576
|
+
const buffer = Buffer.alloc(CHUNK_SIZE);
|
|
577
|
+
let firstLine;
|
|
578
|
+
let fd;
|
|
579
|
+
try {
|
|
580
|
+
fd = await fs.promises.open(filePath, 'r');
|
|
581
|
+
const { bytesRead } = await fd.read(buffer, 0, CHUNK_SIZE, 0);
|
|
582
|
+
if (bytesRead === 0) {
|
|
583
|
+
await fd.close();
|
|
584
|
+
await fs.promises.unlink(filePath);
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
587
|
+
const contentChunk = buffer.toString('utf8', 0, bytesRead);
|
|
588
|
+
const newlineIndex = contentChunk.indexOf('\n');
|
|
589
|
+
firstLine =
|
|
590
|
+
newlineIndex !== -1
|
|
591
|
+
? contentChunk.substring(0, newlineIndex)
|
|
592
|
+
: contentChunk;
|
|
593
|
+
}
|
|
594
|
+
finally {
|
|
595
|
+
if (fd !== undefined) {
|
|
596
|
+
await fd.close();
|
|
538
597
|
}
|
|
539
598
|
}
|
|
599
|
+
const content = JSON.parse(firstLine);
|
|
600
|
+
let fullSessionId;
|
|
601
|
+
if (isSessionIdRecord(content)) {
|
|
602
|
+
fullSessionId = content['sessionId'];
|
|
603
|
+
}
|
|
540
604
|
// Delete the session file
|
|
541
605
|
await fs.promises.unlink(filePath);
|
|
542
606
|
if (fullSessionId) {
|
|
@@ -554,69 +618,57 @@ export class ChatRecordingService {
|
|
|
554
618
|
* All messages from (and including) the specified ID onwards are removed.
|
|
555
619
|
*/
|
|
556
620
|
rewindTo(messageId) {
|
|
557
|
-
if (!this.conversationFile)
|
|
621
|
+
if (!this.conversationFile || !this.cachedConversation)
|
|
558
622
|
return null;
|
|
559
|
-
|
|
560
|
-
const conversation = this.readConversation();
|
|
561
|
-
const messageIndex = conversation.messages.findIndex((m) => m.id === messageId);
|
|
623
|
+
const messageIndex = this.cachedConversation.messages.findIndex((m) => m.id === messageId);
|
|
562
624
|
if (messageIndex === -1) {
|
|
563
625
|
debugLogger.error('Message to rewind to not found in conversation history');
|
|
564
|
-
return
|
|
626
|
+
return this.cachedConversation;
|
|
565
627
|
}
|
|
566
|
-
|
|
567
|
-
this.
|
|
568
|
-
return
|
|
628
|
+
this.cachedConversation.messages = this.cachedConversation.messages.slice(0, messageIndex);
|
|
629
|
+
this.appendRecord({ $rewindTo: messageId });
|
|
630
|
+
return this.cachedConversation;
|
|
569
631
|
}
|
|
570
|
-
/**
|
|
571
|
-
* Updates the conversation history based on the provided API Content array.
|
|
572
|
-
* This is used to persist changes made to the history (like masking) back to disk.
|
|
573
|
-
*/
|
|
574
632
|
updateMessagesFromHistory(history) {
|
|
575
|
-
if (!this.conversationFile)
|
|
633
|
+
if (!this.conversationFile || !this.cachedConversation)
|
|
576
634
|
return;
|
|
577
635
|
try {
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
if (
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
let currentCallId = callIds[0];
|
|
594
|
-
for (const part of content.parts) {
|
|
595
|
-
if (part.functionResponse?.id) {
|
|
596
|
-
currentCallId = part.functionResponse.id;
|
|
597
|
-
}
|
|
598
|
-
if (!partsMap.has(currentCallId)) {
|
|
599
|
-
partsMap.set(currentCallId, []);
|
|
600
|
-
}
|
|
601
|
-
partsMap.get(currentCallId).push(part);
|
|
636
|
+
const partsMap = new Map();
|
|
637
|
+
for (const content of history) {
|
|
638
|
+
if (content.role === 'user' && content.parts) {
|
|
639
|
+
const callIds = content.parts
|
|
640
|
+
.map((p) => p.functionResponse?.id)
|
|
641
|
+
.filter((id) => !!id);
|
|
642
|
+
if (callIds.length === 0)
|
|
643
|
+
continue;
|
|
644
|
+
let currentCallId = callIds[0];
|
|
645
|
+
for (const part of content.parts) {
|
|
646
|
+
if (part.functionResponse?.id) {
|
|
647
|
+
currentCallId = part.functionResponse.id;
|
|
648
|
+
}
|
|
649
|
+
if (!partsMap.has(currentCallId)) {
|
|
650
|
+
partsMap.set(currentCallId, []);
|
|
602
651
|
}
|
|
652
|
+
partsMap.get(currentCallId).push(part);
|
|
603
653
|
}
|
|
604
654
|
}
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
toolCall.result = newParts;
|
|
615
|
-
}
|
|
655
|
+
}
|
|
656
|
+
for (const message of this.cachedConversation.messages) {
|
|
657
|
+
let msgChanged = false;
|
|
658
|
+
if (message.type === 'gemini' && message.toolCalls) {
|
|
659
|
+
for (const toolCall of message.toolCalls) {
|
|
660
|
+
const newParts = partsMap.get(toolCall.id);
|
|
661
|
+
if (newParts !== undefined) {
|
|
662
|
+
toolCall.result = newParts;
|
|
663
|
+
msgChanged = true;
|
|
616
664
|
}
|
|
617
665
|
}
|
|
618
666
|
}
|
|
619
|
-
|
|
667
|
+
if (msgChanged) {
|
|
668
|
+
// Push updated message to log
|
|
669
|
+
this.pushMessage(message);
|
|
670
|
+
}
|
|
671
|
+
}
|
|
620
672
|
}
|
|
621
673
|
catch (error) {
|
|
622
674
|
debugLogger.error('Error updating conversation history from memory.', error);
|
|
@@ -624,4 +676,46 @@ export class ChatRecordingService {
|
|
|
624
676
|
}
|
|
625
677
|
}
|
|
626
678
|
}
|
|
679
|
+
async function parseLegacyRecordFallback(filePath, options) {
|
|
680
|
+
try {
|
|
681
|
+
const fileContent = await fs.promises.readFile(filePath, 'utf8');
|
|
682
|
+
const parsed = JSON.parse(fileContent);
|
|
683
|
+
const isLegacyRecord = (val) => typeof val === 'object' && val !== null && 'sessionId' in val;
|
|
684
|
+
if (isLegacyRecord(parsed)) {
|
|
685
|
+
const legacyRecord = parsed;
|
|
686
|
+
if (options?.metadataOnly) {
|
|
687
|
+
let fallbackFirstUserMessageStr;
|
|
688
|
+
const firstUserMessage = legacyRecord.messages?.find((m) => m.type === 'user');
|
|
689
|
+
if (firstUserMessage) {
|
|
690
|
+
const rawContent = firstUserMessage.content;
|
|
691
|
+
if (Array.isArray(rawContent)) {
|
|
692
|
+
fallbackFirstUserMessageStr = rawContent
|
|
693
|
+
.map((p) => (isTextPart(p) ? p['text'] : ''))
|
|
694
|
+
.join('');
|
|
695
|
+
}
|
|
696
|
+
else if (typeof rawContent === 'string') {
|
|
697
|
+
fallbackFirstUserMessageStr = rawContent;
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
return {
|
|
701
|
+
...legacyRecord,
|
|
702
|
+
messages: [],
|
|
703
|
+
messageCount: legacyRecord.messages?.length || 0,
|
|
704
|
+
userMessageCount: legacyRecord.messages?.filter((m) => m.type === 'user').length || 0,
|
|
705
|
+
firstUserMessage: fallbackFirstUserMessageStr,
|
|
706
|
+
hasUserOrAssistantMessage: legacyRecord.messages?.some((m) => m.type === 'user' || m.type === 'gemini') || false,
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
return {
|
|
710
|
+
...legacyRecord,
|
|
711
|
+
userMessageCount: legacyRecord.messages?.filter((m) => m.type === 'user').length || 0,
|
|
712
|
+
hasUserOrAssistantMessage: legacyRecord.messages?.some((m) => m.type === 'user' || m.type === 'gemini') || false,
|
|
713
|
+
};
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
catch {
|
|
717
|
+
// ignore legacy fallback parse error
|
|
718
|
+
}
|
|
719
|
+
return null;
|
|
720
|
+
}
|
|
627
721
|
//# sourceMappingURL=chatRecordingService.js.map
|