@hoilab/ada-cli 0.84.21 → 0.84.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/README.es.md +163 -0
- package/README.md +99 -652
- package/dist/cli/args.d.ts +3 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +11 -0
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/file-processor.d.ts.map +1 -1
- package/dist/cli/file-processor.js +2 -1
- package/dist/cli/file-processor.js.map +1 -1
- package/dist/cli/home-screen.d.ts.map +1 -1
- package/dist/cli/home-screen.js +2 -2
- package/dist/cli/home-screen.js.map +1 -1
- package/dist/cli/startup-ui.d.ts.map +1 -1
- package/dist/cli/startup-ui.js +9 -3
- package/dist/cli/startup-ui.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -1
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +57 -7
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +449 -73
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +4 -3
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/core/compaction/branch-summarization.js +3 -0
- package/dist/core/compaction/branch-summarization.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +4 -3
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +41 -32
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/defaults.d.ts +1 -0
- package/dist/core/defaults.d.ts.map +1 -1
- package/dist/core/defaults.js +9 -0
- package/dist/core/defaults.js.map +1 -1
- package/dist/core/engine-personality.d.ts +12 -0
- package/dist/core/engine-personality.d.ts.map +1 -0
- package/dist/core/engine-personality.js +53 -0
- package/dist/core/engine-personality.js.map +1 -0
- package/dist/core/extensions/index.d.ts +1 -1
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +10 -5
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/types.d.ts +23 -4
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +2 -1
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/memory-engine/audit-export.d.ts +54 -0
- package/dist/core/memory-engine/audit-export.d.ts.map +1 -0
- package/dist/core/memory-engine/audit-export.js +85 -0
- package/dist/core/memory-engine/audit-export.js.map +1 -0
- package/dist/core/memory-engine/audit.d.ts.map +1 -1
- package/dist/core/memory-engine/audit.js +7 -8
- package/dist/core/memory-engine/audit.js.map +1 -1
- package/dist/core/memory-engine/engine.d.ts +2 -3
- package/dist/core/memory-engine/engine.d.ts.map +1 -1
- package/dist/core/memory-engine/engine.js +148 -50
- package/dist/core/memory-engine/engine.js.map +1 -1
- package/dist/core/memory-engine/inverted-index.d.ts.map +1 -1
- package/dist/core/memory-engine/inverted-index.js +67 -10
- package/dist/core/memory-engine/inverted-index.js.map +1 -1
- package/dist/core/memory-engine/keychain.d.ts.map +1 -1
- package/dist/core/memory-engine/keychain.js +1 -6
- package/dist/core/memory-engine/keychain.js.map +1 -1
- package/dist/core/memory-engine/observation-store.d.ts +1 -0
- package/dist/core/memory-engine/observation-store.d.ts.map +1 -1
- package/dist/core/memory-engine/observation-store.js +37 -8
- package/dist/core/memory-engine/observation-store.js.map +1 -1
- package/dist/core/memory-engine/scanner.d.ts.map +1 -1
- package/dist/core/memory-engine/scanner.js +25 -5
- package/dist/core/memory-engine/scanner.js.map +1 -1
- package/dist/core/memory-engine/security.d.ts.map +1 -1
- package/dist/core/memory-engine/security.js +131 -23
- package/dist/core/memory-engine/security.js.map +1 -1
- package/dist/core/memory-engine/session-indexer.d.ts.map +1 -1
- package/dist/core/memory-engine/session-indexer.js +8 -2
- package/dist/core/memory-engine/session-indexer.js.map +1 -1
- package/dist/core/memory-engine/tools.d.ts +2 -2
- package/dist/core/memory-engine/tools.d.ts.map +1 -1
- package/dist/core/memory-engine/tools.js +14 -7
- package/dist/core/memory-engine/tools.js.map +1 -1
- package/dist/core/memory-engine/vault.d.ts.map +1 -1
- package/dist/core/memory-engine/vault.js +2 -2
- package/dist/core/memory-engine/vault.js.map +1 -1
- package/dist/core/model-config.d.ts.map +1 -1
- package/dist/core/model-config.js +2 -1
- package/dist/core/model-config.js.map +1 -1
- package/dist/core/model-resolver.d.ts +1 -0
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +12 -6
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/models-store.d.ts.map +1 -1
- package/dist/core/models-store.js +2 -1
- package/dist/core/models-store.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +11 -6
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/pi-manifest.d.ts.map +1 -1
- package/dist/core/pi-manifest.js +2 -1
- package/dist/core/pi-manifest.js.map +1 -1
- package/dist/core/prompt-optimizer.d.ts +53 -0
- package/dist/core/prompt-optimizer.d.ts.map +1 -0
- package/dist/core/prompt-optimizer.js +138 -0
- package/dist/core/prompt-optimizer.js.map +1 -0
- package/dist/core/provider-attribution.d.ts.map +1 -1
- package/dist/core/provider-attribution.js +1 -1
- package/dist/core/provider-attribution.js.map +1 -1
- package/dist/core/remote-catalog-provider.d.ts.map +1 -1
- package/dist/core/remote-catalog-provider.js +2 -1
- package/dist/core/remote-catalog-provider.js.map +1 -1
- package/dist/core/resource-loader.d.ts +50 -0
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +233 -7
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/sdk.d.ts +8 -0
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +11 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +2 -1
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-diagnostics.d.ts +9 -0
- package/dist/core/settings-diagnostics.d.ts.map +1 -0
- package/dist/core/settings-diagnostics.js +21 -0
- package/dist/core/settings-diagnostics.js.map +1 -0
- package/dist/core/settings-manager.d.ts +52 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +204 -10
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +51 -33
- package/dist/core/skills.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +2 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +0 -5
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +2 -5
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +20 -4
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +2 -2
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/project-memory-tool.d.ts.map +1 -1
- package/dist/core/tools/project-memory-tool.js +4 -1
- package/dist/core/tools/project-memory-tool.js.map +1 -1
- package/dist/core/trust-manager.d.ts.map +1 -1
- package/dist/core/trust-manager.js +2 -1
- package/dist/core/trust-manager.js.map +1 -1
- package/dist/core/workflows/agent-runner.d.ts +86 -0
- package/dist/core/workflows/agent-runner.d.ts.map +1 -0
- package/dist/core/workflows/agent-runner.js +225 -0
- package/dist/core/workflows/agent-runner.js.map +1 -0
- package/dist/core/workflows/builtins.d.ts +41 -0
- package/dist/core/workflows/builtins.d.ts.map +1 -0
- package/dist/core/workflows/builtins.js +282 -0
- package/dist/core/workflows/builtins.js.map +1 -0
- package/dist/core/workflows/goal-engine/engine.d.ts +134 -0
- package/dist/core/workflows/goal-engine/engine.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/engine.js +462 -0
- package/dist/core/workflows/goal-engine/engine.js.map +1 -0
- package/dist/core/workflows/goal-engine/errors.d.ts +7 -0
- package/dist/core/workflows/goal-engine/errors.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/errors.js +9 -0
- package/dist/core/workflows/goal-engine/errors.js.map +1 -0
- package/dist/core/workflows/goal-engine/index.d.ts +13 -0
- package/dist/core/workflows/goal-engine/index.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/index.js +8 -0
- package/dist/core/workflows/goal-engine/index.js.map +1 -0
- package/dist/core/workflows/goal-engine/persistence.d.ts +31 -0
- package/dist/core/workflows/goal-engine/persistence.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/persistence.js +145 -0
- package/dist/core/workflows/goal-engine/persistence.js.map +1 -0
- package/dist/core/workflows/goal-engine/prompts.d.ts +37 -0
- package/dist/core/workflows/goal-engine/prompts.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/prompts.js +131 -0
- package/dist/core/workflows/goal-engine/prompts.js.map +1 -0
- package/dist/core/workflows/goal-engine/state.d.ts +41 -0
- package/dist/core/workflows/goal-engine/state.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/state.js +397 -0
- package/dist/core/workflows/goal-engine/state.js.map +1 -0
- package/dist/core/workflows/goal-engine/tools.d.ts +31 -0
- package/dist/core/workflows/goal-engine/tools.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/tools.js +211 -0
- package/dist/core/workflows/goal-engine/tools.js.map +1 -0
- package/dist/core/workflows/goal-engine/types.d.ts +286 -0
- package/dist/core/workflows/goal-engine/types.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/types.js +17 -0
- package/dist/core/workflows/goal-engine/types.js.map +1 -0
- package/dist/core/workflows/goal-engine/worktree-fingerprint.d.ts +23 -0
- package/dist/core/workflows/goal-engine/worktree-fingerprint.d.ts.map +1 -0
- package/dist/core/workflows/goal-engine/worktree-fingerprint.js +72 -0
- package/dist/core/workflows/goal-engine/worktree-fingerprint.js.map +1 -0
- package/dist/core/workflows/graph-sync.d.ts +67 -0
- package/dist/core/workflows/graph-sync.d.ts.map +1 -0
- package/dist/core/workflows/graph-sync.js +188 -0
- package/dist/core/workflows/graph-sync.js.map +1 -0
- package/dist/core/workflows/graph.d.ts +143 -0
- package/dist/core/workflows/graph.d.ts.map +1 -0
- package/dist/core/workflows/graph.js +319 -0
- package/dist/core/workflows/graph.js.map +1 -0
- package/dist/core/workflows/index.d.ts +18 -0
- package/dist/core/workflows/index.d.ts.map +1 -0
- package/dist/core/workflows/index.js +14 -0
- package/dist/core/workflows/index.js.map +1 -0
- package/dist/core/workflows/journal.d.ts +68 -0
- package/dist/core/workflows/journal.d.ts.map +1 -0
- package/dist/core/workflows/journal.js +83 -0
- package/dist/core/workflows/journal.js.map +1 -0
- package/dist/core/workflows/manager.d.ts +112 -0
- package/dist/core/workflows/manager.d.ts.map +1 -0
- package/dist/core/workflows/manager.js +327 -0
- package/dist/core/workflows/manager.js.map +1 -0
- package/dist/core/workflows/resolve-script.d.ts +35 -0
- package/dist/core/workflows/resolve-script.d.ts.map +1 -0
- package/dist/core/workflows/resolve-script.js +66 -0
- package/dist/core/workflows/resolve-script.js.map +1 -0
- package/dist/core/workflows/runtime.d.ts +49 -0
- package/dist/core/workflows/runtime.d.ts.map +1 -0
- package/dist/core/workflows/runtime.js +301 -0
- package/dist/core/workflows/runtime.js.map +1 -0
- package/dist/core/workflows/shared-store.d.ts +31 -0
- package/dist/core/workflows/shared-store.d.ts.map +1 -0
- package/dist/core/workflows/shared-store.js +80 -0
- package/dist/core/workflows/shared-store.js.map +1 -0
- package/dist/core/workflows/subagent-host.d.ts +50 -0
- package/dist/core/workflows/subagent-host.d.ts.map +1 -0
- package/dist/core/workflows/subagent-host.js +225 -0
- package/dist/core/workflows/subagent-host.js.map +1 -0
- package/dist/core/workflows/tool-workflow.d.ts +22 -0
- package/dist/core/workflows/tool-workflow.d.ts.map +1 -0
- package/dist/core/workflows/tool-workflow.js +120 -0
- package/dist/core/workflows/tool-workflow.js.map +1 -0
- package/dist/core/workflows/types.d.ts +142 -0
- package/dist/core/workflows/types.d.ts.map +1 -0
- package/dist/core/workflows/types.js +26 -0
- package/dist/core/workflows/types.js.map +1 -0
- package/dist/core/workflows/worktree.d.ts +42 -0
- package/dist/core/workflows/worktree.d.ts.map +1 -0
- package/dist/core/workflows/worktree.js +107 -0
- package/dist/core/workflows/worktree.js.map +1 -0
- package/dist/extensions/llama/index.d.ts.map +1 -1
- package/dist/extensions/llama/index.js +2 -0
- package/dist/extensions/llama/index.js.map +1 -1
- package/dist/extensions/llama/provider.d.ts.map +1 -1
- package/dist/extensions/llama/provider.js +6 -2
- package/dist/extensions/llama/provider.js.map +1 -1
- package/dist/index.d.ts +16 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -11
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts +4 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +20 -15
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +4 -3
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/components/home-screen.d.ts.map +1 -1
- package/dist/modes/interactive/components/home-screen.js +2 -2
- package/dist/modes/interactive/components/home-screen.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +2 -3
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +16 -6
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/prompt-optimization.d.ts +16 -0
- package/dist/modes/interactive/components/prompt-optimization.d.ts.map +1 -0
- package/dist/modes/interactive/components/prompt-optimization.js +46 -0
- package/dist/modes/interactive/components/prompt-optimization.js.map +1 -0
- package/dist/modes/interactive/components/settings-selector.d.ts +19 -1
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +247 -46
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-submenu.d.ts +72 -0
- package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -0
- package/dist/modes/interactive/components/settings-submenu.js +165 -0
- package/dist/modes/interactive/components/settings-submenu.js.map +1 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts +8 -3
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/thinking-selector.js +29 -3
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/dist/modes/interactive/external-editor.d.ts.map +1 -1
- package/dist/modes/interactive/external-editor.js +2 -1
- package/dist/modes/interactive/external-editor.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +24 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +677 -34
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +4 -3
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/json-event.d.ts +16 -13
- package/dist/modes/json-event.d.ts.map +1 -1
- package/dist/modes/json-event.js +20 -6
- package/dist/modes/json-event.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +173 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +29 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js +1 -1
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/skills/ada-engine/SKILL.md +153 -0
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js +2 -1
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/management-http.d.ts +5 -3
- package/dist/utils/management-http.d.ts.map +1 -1
- package/dist/utils/management-http.js +14 -10
- package/dist/utils/management-http.js.map +1 -1
- package/dist/utils/text.d.ts +8 -0
- package/dist/utils/text.d.ts.map +1 -0
- package/dist/utils/text.js +9 -0
- package/dist/utils/text.js.map +1 -0
- package/docs/compaction.md +15 -0
- package/docs/custom-provider.md +5 -2
- package/docs/extensions.md +11 -2
- package/docs/json.md +7 -2
- package/docs/llama-cpp.md +2 -0
- package/docs/models.md +8 -2
- package/docs/rpc.md +9 -3
- package/docs/settings.md +2 -2
- package/docs/skills.md +4 -3
- package/examples/extensions/border-status-editor.ts +1 -1
- package/examples/extensions/git-checkpoint.ts +2 -2
- package/examples/extensions/notify.ts +3 -1
- package/examples/extensions/subagent/README.md +1 -1
- package/examples/extensions/subagent/index.ts +6 -1
- package/examples/extensions/titlebar-spinner.ts +1 -1
- package/examples/rpc-extension-ui.ts +1 -1
- package/examples/sdk/06-extensions.ts +1 -1
- package/examples/sdk/README.md +1 -1
- package/npm-shrinkwrap.json +2 -12
- package/package.json +3 -3
|
@@ -24,24 +24,29 @@ import { normalizeToolResultImages } from "../utils/tool-result-images.js";
|
|
|
24
24
|
import { formatNoApiKeyFoundMessage, formatNoModelSelectedMessage } from "./auth-guidance.js";
|
|
25
25
|
import { executeBashWithOperations } from "./bash-executor.js";
|
|
26
26
|
import { calculateContextTokens, collectEntriesForBranchSummary, compact, estimateContextTokens, estimateTokens, generateBranchSummary, prepareCompaction, shouldCompact, } from "./compaction/index.js";
|
|
27
|
-
import { DEFAULT_THINKING_LEVEL } from "./defaults.js";
|
|
27
|
+
import { DEFAULT_THINKING_LEVEL, THINKING_LEVEL_OPTIONS } from "./defaults.js";
|
|
28
|
+
import { buildEnginePersonalityBlock } from "./engine-personality.js";
|
|
28
29
|
import { exportSessionToHtml } from "./export-html/index.js";
|
|
29
30
|
import { createToolHtmlRenderer } from "./export-html/tool-renderer.js";
|
|
30
31
|
import { ExtensionRunner, wrapRegisteredTools, } from "./extensions/index.js";
|
|
31
32
|
import { emitSessionShutdownEvent } from "./extensions/runner.js";
|
|
33
|
+
import { redactSensitive } from "./memory-engine/security.js";
|
|
34
|
+
import { createMemoryEngineTools } from "./memory-engine/tools.js";
|
|
35
|
+
import { expandVaultRefs } from "./memory-engine/vault.js";
|
|
32
36
|
import { ModelRegistry } from "./model-registry.js";
|
|
37
|
+
import { loadProjectMemorySync, saveProjectMemory } from "./project-memory.js";
|
|
38
|
+
import { optimizeUserPrompt } from "./prompt-optimizer.js";
|
|
33
39
|
import { expandPromptTemplate } from "./prompt-templates.js";
|
|
34
40
|
import { CURRENT_SESSION_VERSION, getLatestCompactionEntry } from "./session-manager.js";
|
|
35
|
-
import { loadProjectMemorySync, saveProjectMemory } from "./project-memory.js";
|
|
36
41
|
import { createSyntheticSourceInfo } from "./source-info.js";
|
|
37
42
|
import { buildSystemPrompt } from "./system-prompt.js";
|
|
38
43
|
import { createLocalBashOperations } from "./tools/bash.js";
|
|
39
44
|
import { createAllToolDefinitions } from "./tools/index.js";
|
|
40
|
-
import { createMemoryEngineTools } from "./memory-engine/tools.js";
|
|
41
|
-
import { redactSensitive } from "./memory-engine/security.js";
|
|
42
|
-
import { expandVaultRefs } from "./memory-engine/vault.js";
|
|
43
45
|
import { createToolDefinitionFromAgentTool } from "./tools/tool-definition-wrapper.js";
|
|
44
46
|
import { addUsageToTotals, createUsageTotals } from "./usage-totals.js";
|
|
47
|
+
import { goalSessionTools } from "./workflows/goal-engine/tools.js";
|
|
48
|
+
import { createGraphTool, GraphSync } from "./workflows/graph-sync.js";
|
|
49
|
+
import { createWorkflowTool } from "./workflows/tool-workflow.js";
|
|
45
50
|
/**
|
|
46
51
|
* Parse a skill block from message text.
|
|
47
52
|
* Returns null if the text doesn't contain a skill block.
|
|
@@ -75,8 +80,6 @@ function estimateMessagesTokens(messages) {
|
|
|
75
80
|
// ============================================================================
|
|
76
81
|
// Constants
|
|
77
82
|
// ============================================================================
|
|
78
|
-
/** Standard thinking levels */
|
|
79
|
-
const THINKING_LEVELS = ["off", "minimal", "low", "medium", "high"];
|
|
80
83
|
// ============================================================================
|
|
81
84
|
// AgentSession Class
|
|
82
85
|
// ============================================================================
|
|
@@ -114,6 +117,8 @@ export class AgentSession {
|
|
|
114
117
|
_turnIndex = 0;
|
|
115
118
|
_resourceLoader;
|
|
116
119
|
_customTools;
|
|
120
|
+
_isSubagentSession = false;
|
|
121
|
+
_graphSync;
|
|
117
122
|
_baseToolDefinitions = new Map();
|
|
118
123
|
_cwd;
|
|
119
124
|
_extensionRunnerRef;
|
|
@@ -130,6 +135,10 @@ export class AgentSession {
|
|
|
130
135
|
_extensionErrorListener;
|
|
131
136
|
_extensionErrorUnsubscriber;
|
|
132
137
|
_modelRuntime;
|
|
138
|
+
/** Optimizador autónomo de prompts: "off" | "auto" | "clarify". */
|
|
139
|
+
_promptOptimizerMode = "off";
|
|
140
|
+
/** Clarificación pendiente (modo "clarify"): original + preguntas ya emitidas. */
|
|
141
|
+
_pendingClarification;
|
|
133
142
|
// Tool registry for extension getTools/setTools
|
|
134
143
|
_toolRegistry = new Map();
|
|
135
144
|
_toolDefinitions = new Map();
|
|
@@ -146,6 +155,7 @@ export class AgentSession {
|
|
|
146
155
|
this._scopedModels = config.scopedModels ?? [];
|
|
147
156
|
this._resourceLoader = config.resourceLoader;
|
|
148
157
|
this._customTools = config.customTools ?? [];
|
|
158
|
+
this._isSubagentSession = config.isSubagent === true;
|
|
149
159
|
this._cwd = config.cwd;
|
|
150
160
|
this._modelRuntime = config.modelRuntime;
|
|
151
161
|
this._extensionRunnerRef = config.extensionRunnerRef;
|
|
@@ -163,6 +173,23 @@ export class AgentSession {
|
|
|
163
173
|
activeToolNames: this._initialActiveToolNames,
|
|
164
174
|
includeAllExtensionTools: true,
|
|
165
175
|
});
|
|
176
|
+
// Los subagentes (goals/workflows) HEREDAN el modelo de la sesión principal:
|
|
177
|
+
// misma provider/modelId → misma auth → misma API key del chat.
|
|
178
|
+
this._resourceLoader.setSessionModelGetter?.(() => {
|
|
179
|
+
const m = this.model;
|
|
180
|
+
return m
|
|
181
|
+
? {
|
|
182
|
+
provider: m.provider,
|
|
183
|
+
modelId: m.modelId ?? m.id ?? "",
|
|
184
|
+
}
|
|
185
|
+
: undefined;
|
|
186
|
+
});
|
|
187
|
+
// Cuando un run de workflow arranca (tool del agente o sub-tarea del
|
|
188
|
+
// goal), la sesión emite workflow_started — el desktop lo usa para
|
|
189
|
+
// abrir el panel Engine automáticamente.
|
|
190
|
+
this._resourceLoader.setOnWorkflowRunStarted?.((runId, name) => {
|
|
191
|
+
this._emit({ type: "workflow_started", runId, name });
|
|
192
|
+
});
|
|
166
193
|
// Ada Memory Engine: lazy-initialize (stores, migration, session index)
|
|
167
194
|
// and wire the LLM callback used by review/correction/flush. Best-effort
|
|
168
195
|
// and never blocks startup.
|
|
@@ -190,8 +217,7 @@ export class AgentSession {
|
|
|
190
217
|
content: [
|
|
191
218
|
{
|
|
192
219
|
type: "text",
|
|
193
|
-
text:
|
|
194
|
-
reason,
|
|
220
|
+
text: `Has introducido un dato sensible que no se almacenará en memoria. ${reason}`,
|
|
195
221
|
},
|
|
196
222
|
],
|
|
197
223
|
display: true,
|
|
@@ -285,6 +311,20 @@ export class AgentSession {
|
|
|
285
311
|
}
|
|
286
312
|
};
|
|
287
313
|
this.agent.afterToolCall = async ({ toolCall, args, result, isError }) => {
|
|
314
|
+
// Auto-registro del grafo (best-effort, nunca bloquea el agente).
|
|
315
|
+
try {
|
|
316
|
+
if (!this._graphSync) {
|
|
317
|
+
this._graphSync = new GraphSync({
|
|
318
|
+
graph: () => this._resourceLoader.getGraph?.(),
|
|
319
|
+
cwd: this._cwd,
|
|
320
|
+
activeGoal: () => null, // resuelto en agent_settled vía syncGoal
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
void this._graphSync.onToolResult(toolCall.name, args, result, isError);
|
|
324
|
+
}
|
|
325
|
+
catch {
|
|
326
|
+
// best-effort
|
|
327
|
+
}
|
|
288
328
|
const runner = this._extensionRunner;
|
|
289
329
|
const hookResult = runner.hasHandlers("tool_result")
|
|
290
330
|
? await runner.emitToolResult({
|
|
@@ -350,6 +390,11 @@ export class AgentSession {
|
|
|
350
390
|
followUp: [...this._followUpMessages],
|
|
351
391
|
});
|
|
352
392
|
}
|
|
393
|
+
async _emitSessionCompactFailed(event) {
|
|
394
|
+
if (this._extensionRunner.hasHandlers("session_compact_failed")) {
|
|
395
|
+
await this._extensionRunner.emit({ type: "session_compact_failed", ...event });
|
|
396
|
+
}
|
|
397
|
+
}
|
|
353
398
|
_getIdleWaitPromise() {
|
|
354
399
|
if (!this._idleWaitPromise) {
|
|
355
400
|
this._idleWaitPromise = new Promise((resolve) => {
|
|
@@ -372,11 +417,88 @@ export class AgentSession {
|
|
|
372
417
|
try {
|
|
373
418
|
await this._extensionRunner.emit({ type: "agent_settled" });
|
|
374
419
|
this._emit({ type: "agent_settled" });
|
|
420
|
+
// Ada Intelligence Engine: el GoalEngine es el ÚNICO dueño de la
|
|
421
|
+
// continuación automática del goal (pi-goal). No compite con retry/
|
|
422
|
+
// compaction/steer. Fire-and-forget; nunca bloquea ni rompe el chat.
|
|
423
|
+
try {
|
|
424
|
+
const goalEngine = this._isSubagentSession ? null : this._resourceLoader.getGoalEngine?.();
|
|
425
|
+
if (goalEngine) {
|
|
426
|
+
void this._maybeContinueGoal(goalEngine);
|
|
427
|
+
// Spine del grafo: sync automático del goal activo.
|
|
428
|
+
if (this._graphSync) {
|
|
429
|
+
void (async () => {
|
|
430
|
+
const goals = await goalEngine.list().catch(() => []);
|
|
431
|
+
const active = goals.find((g) => g.status === "active");
|
|
432
|
+
if (active) {
|
|
433
|
+
const full = await goalEngine.get(active.id).catch(() => null);
|
|
434
|
+
if (full) {
|
|
435
|
+
await this._graphSync?.syncGoal({
|
|
436
|
+
id: full.id,
|
|
437
|
+
goal: full.goal,
|
|
438
|
+
phase: full.phase,
|
|
439
|
+
tasks: full.tasks ?? [],
|
|
440
|
+
doneCriteria: full.doneCriteria ?? [],
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
})();
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
catch {
|
|
449
|
+
// best-effort
|
|
450
|
+
}
|
|
375
451
|
}
|
|
376
452
|
finally {
|
|
377
453
|
this._resolveIdleWaitIfIdle();
|
|
378
454
|
}
|
|
379
455
|
}
|
|
456
|
+
/**
|
|
457
|
+
* Confirmación fail-closed del lanzamiento de workflows: emite un evento y
|
|
458
|
+
* espera respuesta humana hasta 15s; sin respuesta → NO lanzar.
|
|
459
|
+
*/
|
|
460
|
+
_confirmWorkflowLaunch(prompt) {
|
|
461
|
+
return new Promise((resolve) => {
|
|
462
|
+
const timeout = setTimeout(() => {
|
|
463
|
+
this._confirmResolvers.delete(prompt);
|
|
464
|
+
resolve(false);
|
|
465
|
+
}, 15_000);
|
|
466
|
+
this._confirmResolvers.set(prompt, (ok) => {
|
|
467
|
+
clearTimeout(timeout);
|
|
468
|
+
this._confirmResolvers.delete(prompt);
|
|
469
|
+
resolve(ok);
|
|
470
|
+
});
|
|
471
|
+
this._emit({ type: "notification", message: `[workflow] ${prompt}`, level: "warning" });
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
/** Respuesta a una confirmación pendiente (la UI la llama). */
|
|
475
|
+
resolveWorkflowConfirmation(prompt, ok) {
|
|
476
|
+
const resolver = this._confirmResolvers.get(prompt);
|
|
477
|
+
if (!resolver)
|
|
478
|
+
return false;
|
|
479
|
+
resolver(ok);
|
|
480
|
+
return true;
|
|
481
|
+
}
|
|
482
|
+
/** Si hay un goal activo aprobado, avanza un turno del bucle. */
|
|
483
|
+
async _maybeContinueGoal(goalEngine) {
|
|
484
|
+
const goals = await goalEngine.list().catch(() => []);
|
|
485
|
+
const active = goals.find((g) => g.status === "active");
|
|
486
|
+
if (!active)
|
|
487
|
+
return;
|
|
488
|
+
// Freno por defecto del engine: si está desactivado no continúa.
|
|
489
|
+
if (!this.settingsManager.getGoalEngineEnabled())
|
|
490
|
+
return;
|
|
491
|
+
// markers anti-duplicados: solo avanzar si no hay un turno ya en curso.
|
|
492
|
+
if (this._isAgentRunActive)
|
|
493
|
+
return;
|
|
494
|
+
this._isAgentRunActive = true;
|
|
495
|
+
try {
|
|
496
|
+
await goalEngine.tick(active.id).catch(() => { });
|
|
497
|
+
}
|
|
498
|
+
finally {
|
|
499
|
+
this._isAgentRunActive = false;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
380
502
|
// =========================================================================
|
|
381
503
|
// Automatic project memory (claude-mem style)
|
|
382
504
|
// =========================================================================
|
|
@@ -488,6 +610,7 @@ Task: given the CURRENT MEMORY and the LATEST CONVERSATION TURN, produce the COM
|
|
|
488
610
|
// Track last assistant message for auto-compaction check
|
|
489
611
|
_lastAssistantMessage = undefined;
|
|
490
612
|
_lastAutoMemorizeAt = 0;
|
|
613
|
+
_confirmResolvers = new Map();
|
|
491
614
|
/** Vault expansion redactions by user-message id (frontend + persistence). */
|
|
492
615
|
_vaultRedactions = new Map();
|
|
493
616
|
_userMessageSeq = 0;
|
|
@@ -922,7 +1045,19 @@ Task: given the CURRENT MEMORY and the LATEST CONVERSATION TURN, produce the COM
|
|
|
922
1045
|
}
|
|
923
1046
|
const loaderSystemPrompt = this._resourceLoader.getSystemPrompt();
|
|
924
1047
|
const loaderAppendSystemPrompt = this._resourceLoader.getAppendSystemPrompt();
|
|
925
|
-
|
|
1048
|
+
// Ada Intelligence Engine: PERSONALIDAD SIEMPRE presente (sesión principal).
|
|
1049
|
+
// No depende de que el modelo lea la skill: el árbol de decisión y los
|
|
1050
|
+
// procedimientos van inline en el prompt, cada turno.
|
|
1051
|
+
let enginePrompt;
|
|
1052
|
+
if (!this._isSubagentSession &&
|
|
1053
|
+
(this.settingsManager.getGoalEngineEnabled() || this.settingsManager.getWorkflowsEnabled())) {
|
|
1054
|
+
enginePrompt = buildEnginePersonalityBlock();
|
|
1055
|
+
}
|
|
1056
|
+
const appendSystemPrompt = enginePrompt
|
|
1057
|
+
? [enginePrompt, ...(loaderAppendSystemPrompt.length > 0 ? [loaderAppendSystemPrompt.join("\n\n")] : [])].join("\n\n")
|
|
1058
|
+
: loaderAppendSystemPrompt.length > 0
|
|
1059
|
+
? loaderAppendSystemPrompt.join("\n\n")
|
|
1060
|
+
: undefined;
|
|
926
1061
|
const loadedSkills = this._resourceLoader.getSkills().skills;
|
|
927
1062
|
const loadedContextFiles = this._resourceLoader.getAgentsFiles().agentsFiles;
|
|
928
1063
|
this._baseSystemPromptOptions = {
|
|
@@ -1382,13 +1517,135 @@ Task: given the CURRENT MEMORY and the LATEST CONVERSATION TURN, produce the COM
|
|
|
1382
1517
|
if (images.length === 0)
|
|
1383
1518
|
images = undefined;
|
|
1384
1519
|
}
|
|
1385
|
-
|
|
1520
|
+
// ── Optimizador autónomo de prompt ───────────────────────────────────
|
|
1521
|
+
// Mejora la petición del usuario (claridad, contexto, formato, criterios,
|
|
1522
|
+
// alcance) ANTES de que llegue al modelo. Fail-open: cualquier error o
|
|
1523
|
+
// timeout usa el prompt original — nunca degrada la experiencia.
|
|
1524
|
+
let finalText = text;
|
|
1525
|
+
if (this._promptOptimizerMode !== "off" && typeof text === "string" && !text.startsWith("/")) {
|
|
1526
|
+
try {
|
|
1527
|
+
const result = await this._runPromptOptimizer(text);
|
|
1528
|
+
if (result) {
|
|
1529
|
+
if (result.decision === "clarify" && this._promptOptimizerMode === "clarify") {
|
|
1530
|
+
// Preguntar primero y esperar respuesta; no enviamos aún.
|
|
1531
|
+
this._pendingClarification = { original: text, questions: result.questions };
|
|
1532
|
+
this._emit({
|
|
1533
|
+
type: "prompt_optimization",
|
|
1534
|
+
decision: "clarify",
|
|
1535
|
+
original: text,
|
|
1536
|
+
questions: result.questions,
|
|
1537
|
+
summary: result.summary,
|
|
1538
|
+
});
|
|
1539
|
+
const questions = result.questions.map((q, i) => `${i + 1}. ${q}`).join("\n");
|
|
1540
|
+
await this.sendCustomMessage({
|
|
1541
|
+
customType: "clarify-questions",
|
|
1542
|
+
content: [
|
|
1543
|
+
{
|
|
1544
|
+
type: "text",
|
|
1545
|
+
text: `🔎 Para dejar tu petición sin huecos, necesito aclarar:\n${questions}\n\nResponde a las preguntas y continuaré.`,
|
|
1546
|
+
},
|
|
1547
|
+
],
|
|
1548
|
+
display: true,
|
|
1549
|
+
details: { q: result.questions },
|
|
1550
|
+
}, { triggerTurn: false });
|
|
1551
|
+
return;
|
|
1552
|
+
}
|
|
1553
|
+
if (result.enhanced && result.enhanced !== text) {
|
|
1554
|
+
finalText = result.enhanced;
|
|
1555
|
+
this._emit({
|
|
1556
|
+
type: "prompt_optimization",
|
|
1557
|
+
decision: "enhance",
|
|
1558
|
+
original: text,
|
|
1559
|
+
enhanced: result.enhanced,
|
|
1560
|
+
summary: result.summary,
|
|
1561
|
+
});
|
|
1562
|
+
// Mensaje persistente en el chat (CLI + desktop): muestra el
|
|
1563
|
+
// antes → después para que el usuario vea la mejora.
|
|
1564
|
+
void this.sendCustomMessage({
|
|
1565
|
+
customType: "prompt-optimization",
|
|
1566
|
+
content: [{ type: "text", text: result.enhanced }],
|
|
1567
|
+
display: true,
|
|
1568
|
+
details: { original: text, summary: result.summary },
|
|
1569
|
+
}, { triggerTurn: false });
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
catch {
|
|
1574
|
+
// fail-open: continuamos con el prompt original
|
|
1575
|
+
}
|
|
1576
|
+
}
|
|
1577
|
+
await this.prompt(finalText, {
|
|
1386
1578
|
expandPromptTemplates: options?.expandPromptTemplates ?? false,
|
|
1387
1579
|
streamingBehavior: options?.deliverAs,
|
|
1388
1580
|
images,
|
|
1389
1581
|
source: "extension",
|
|
1390
1582
|
});
|
|
1391
1583
|
}
|
|
1584
|
+
/**
|
|
1585
|
+
* Ejecuta el optimizador con el modelo de la sesión. Timeout de 12s,
|
|
1586
|
+
* nunca lanza (devuelve undefined → fail-open).
|
|
1587
|
+
*/
|
|
1588
|
+
async _runPromptOptimizer(text) {
|
|
1589
|
+
const model = this.model;
|
|
1590
|
+
if (!model)
|
|
1591
|
+
return undefined;
|
|
1592
|
+
try {
|
|
1593
|
+
const answers = this._pendingClarification?.answers;
|
|
1594
|
+
const result = await Promise.race([
|
|
1595
|
+
optimizeUserPrompt({
|
|
1596
|
+
text,
|
|
1597
|
+
// En modo auto nunca bloqueamos al usuario: si el LLM pide
|
|
1598
|
+
// clarificar, forzamos una mejora con supuestos razonables.
|
|
1599
|
+
forceEnhance: this._promptOptimizerMode === "auto",
|
|
1600
|
+
context: {
|
|
1601
|
+
projectDir: this._cwd,
|
|
1602
|
+
// Si el usuario ya respondió a las preguntas de la ronda
|
|
1603
|
+
// anterior, se las pasamos al optimizador como contexto.
|
|
1604
|
+
recentMessages: answers?.length
|
|
1605
|
+
? [...answers, ...(this._recentUserPrompts(3) ?? [])]
|
|
1606
|
+
: this._recentUserPrompts(3),
|
|
1607
|
+
},
|
|
1608
|
+
}, async (systemPrompt, userContent) => {
|
|
1609
|
+
const completed = await this._modelRuntime.completeSimple(model, {
|
|
1610
|
+
systemPrompt,
|
|
1611
|
+
messages: [{ role: "user", content: userContent }],
|
|
1612
|
+
signal: AbortSignal.timeout(20_000),
|
|
1613
|
+
});
|
|
1614
|
+
return contentText(completed.content, "").trim();
|
|
1615
|
+
}),
|
|
1616
|
+
new Promise((resolve) => setTimeout(() => resolve(undefined), 25_000)),
|
|
1617
|
+
]);
|
|
1618
|
+
if (!result)
|
|
1619
|
+
return undefined;
|
|
1620
|
+
this._pendingClarification = undefined;
|
|
1621
|
+
return result;
|
|
1622
|
+
}
|
|
1623
|
+
catch {
|
|
1624
|
+
return undefined;
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
/** Últimos prompts de usuario (para dar contexto al optimizador). */
|
|
1628
|
+
_recentUserPrompts(max) {
|
|
1629
|
+
const out = [];
|
|
1630
|
+
const messages = this.agent.state.messages;
|
|
1631
|
+
for (let i = messages.length - 1; i >= 0 && out.length < max; i--) {
|
|
1632
|
+
const m = messages[i];
|
|
1633
|
+
if (m.role === "user") {
|
|
1634
|
+
const t = contentText(m.content, "");
|
|
1635
|
+
if (t.trim())
|
|
1636
|
+
out.unshift(t.slice(0, 500));
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1639
|
+
return out;
|
|
1640
|
+
}
|
|
1641
|
+
/** Ajusta el modo del optimizador autónomo de prompts. */
|
|
1642
|
+
setPromptOptimizerMode(mode) {
|
|
1643
|
+
this._promptOptimizerMode = mode;
|
|
1644
|
+
}
|
|
1645
|
+
/** Modo actual del optimizador autónomo de prompts. */
|
|
1646
|
+
getPromptOptimizerMode() {
|
|
1647
|
+
return this._promptOptimizerMode;
|
|
1648
|
+
}
|
|
1392
1649
|
/**
|
|
1393
1650
|
* Clear all queued messages and return them.
|
|
1394
1651
|
* Useful for restoring to editor when user aborts.
|
|
@@ -1447,19 +1704,24 @@ Task: given the CURRENT MEMORY and the LATEST CONVERSATION TURN, produce the COM
|
|
|
1447
1704
|
}
|
|
1448
1705
|
/**
|
|
1449
1706
|
* Set model directly.
|
|
1450
|
-
* Validates that auth is configured
|
|
1707
|
+
* Validates that auth is configured and saves to the session transcript.
|
|
1708
|
+
* Persists to global defaults only when options.persist is true.
|
|
1451
1709
|
* @throws Error if no auth is configured for the model
|
|
1452
1710
|
*/
|
|
1453
|
-
async setModel(model) {
|
|
1711
|
+
async setModel(model, options = {}) {
|
|
1454
1712
|
if (!(await this._modelRuntime.checkAuth(model.provider))) {
|
|
1455
1713
|
throw new Error(`No API key for ${model.provider}/${model.id}`);
|
|
1456
1714
|
}
|
|
1457
1715
|
const previousModel = this.model;
|
|
1458
|
-
const thinkingLevel = this._getThinkingLevelForModelSwitch();
|
|
1716
|
+
const thinkingLevel = this._getThinkingLevelForModelSwitch(model);
|
|
1459
1717
|
this.agent.state.model = model;
|
|
1460
1718
|
this.sessionManager.appendModelChange(model.provider, model.id);
|
|
1461
|
-
|
|
1462
|
-
|
|
1719
|
+
if (options.persist) {
|
|
1720
|
+
this.settingsManager.setDefaultModelAndProvider(model.provider, model.id);
|
|
1721
|
+
}
|
|
1722
|
+
// Re-clamp session thinking level for new model's capabilities.
|
|
1723
|
+
// Per-model thinking level overrides take priority over session carry-over.
|
|
1724
|
+
// Model persistence does not implicitly rewrite the global thinking default.
|
|
1463
1725
|
this.setThinkingLevel(thinkingLevel);
|
|
1464
1726
|
await this._emitModelSelect(model, previousModel, "set");
|
|
1465
1727
|
}
|
|
@@ -1469,13 +1731,13 @@ Task: given the CURRENT MEMORY and the LATEST CONVERSATION TURN, produce the COM
|
|
|
1469
1731
|
* @param direction - "forward" (default) or "backward"
|
|
1470
1732
|
* @returns The new model info, or undefined if only one model available
|
|
1471
1733
|
*/
|
|
1472
|
-
async cycleModel(direction = "forward") {
|
|
1734
|
+
async cycleModel(direction = "forward", options = {}) {
|
|
1473
1735
|
if (this._scopedModels.length > 0) {
|
|
1474
|
-
return this._cycleScopedModel(direction);
|
|
1736
|
+
return this._cycleScopedModel(direction, options);
|
|
1475
1737
|
}
|
|
1476
|
-
return this._cycleAvailableModel(direction);
|
|
1738
|
+
return this._cycleAvailableModel(direction, options);
|
|
1477
1739
|
}
|
|
1478
|
-
async _cycleScopedModel(direction) {
|
|
1740
|
+
async _cycleScopedModel(direction, options) {
|
|
1479
1741
|
const availableIds = new Set(this._modelRuntime.getAvailableSnapshot().map((model) => `${model.provider}\0${model.id}`));
|
|
1480
1742
|
const scopedModels = this._scopedModels.filter((scoped) => availableIds.has(`${scoped.model.provider}\0${scoped.model.id}`));
|
|
1481
1743
|
if (scopedModels.length <= 1)
|
|
@@ -1487,20 +1749,23 @@ Task: given the CURRENT MEMORY and the LATEST CONVERSATION TURN, produce the COM
|
|
|
1487
1749
|
const len = scopedModels.length;
|
|
1488
1750
|
const nextIndex = direction === "forward" ? (currentIndex + 1) % len : (currentIndex - 1 + len) % len;
|
|
1489
1751
|
const next = scopedModels[nextIndex];
|
|
1490
|
-
const thinkingLevel = this._getThinkingLevelForModelSwitch(next.thinkingLevel);
|
|
1752
|
+
const thinkingLevel = this._getThinkingLevelForModelSwitch(next.model, next.thinkingLevel);
|
|
1491
1753
|
// Apply model
|
|
1492
1754
|
this.agent.state.model = next.model;
|
|
1493
1755
|
this.sessionManager.appendModelChange(next.model.provider, next.model.id);
|
|
1494
|
-
|
|
1495
|
-
|
|
1756
|
+
if (options.persist) {
|
|
1757
|
+
this.settingsManager.setDefaultModelAndProvider(next.model.provider, next.model.id);
|
|
1758
|
+
}
|
|
1759
|
+
// Apply session thinking level.
|
|
1496
1760
|
// - Explicit scoped model thinking level overrides current session level
|
|
1497
1761
|
// - Undefined scoped model thinking level inherits the current session preference
|
|
1498
1762
|
// setThinkingLevel clamps to model capabilities.
|
|
1763
|
+
// Model persistence does not implicitly rewrite the global thinking default.
|
|
1499
1764
|
this.setThinkingLevel(thinkingLevel);
|
|
1500
1765
|
await this._emitModelSelect(next.model, currentModel, "cycle");
|
|
1501
1766
|
return { model: next.model, thinkingLevel: this.thinkingLevel, isScoped: true };
|
|
1502
1767
|
}
|
|
1503
|
-
async _cycleAvailableModel(direction) {
|
|
1768
|
+
async _cycleAvailableModel(direction, options) {
|
|
1504
1769
|
const availableModels = this._modelRuntime.getAvailableSnapshot();
|
|
1505
1770
|
if (availableModels.length <= 1)
|
|
1506
1771
|
return undefined;
|
|
@@ -1511,11 +1776,14 @@ Task: given the CURRENT MEMORY and the LATEST CONVERSATION TURN, produce the COM
|
|
|
1511
1776
|
const len = availableModels.length;
|
|
1512
1777
|
const nextIndex = direction === "forward" ? (currentIndex + 1) % len : (currentIndex - 1 + len) % len;
|
|
1513
1778
|
const nextModel = availableModels[nextIndex];
|
|
1514
|
-
const thinkingLevel = this._getThinkingLevelForModelSwitch();
|
|
1779
|
+
const thinkingLevel = this._getThinkingLevelForModelSwitch(nextModel);
|
|
1515
1780
|
this.agent.state.model = nextModel;
|
|
1516
1781
|
this.sessionManager.appendModelChange(nextModel.provider, nextModel.id);
|
|
1517
|
-
|
|
1518
|
-
|
|
1782
|
+
if (options.persist) {
|
|
1783
|
+
this.settingsManager.setDefaultModelAndProvider(nextModel.provider, nextModel.id);
|
|
1784
|
+
}
|
|
1785
|
+
// Re-clamp session thinking level for new model's capabilities.
|
|
1786
|
+
// Model persistence does not implicitly rewrite the global thinking default.
|
|
1519
1787
|
this.setThinkingLevel(thinkingLevel);
|
|
1520
1788
|
await this._emitModelSelect(nextModel, currentModel, "cycle");
|
|
1521
1789
|
return { model: nextModel, thinkingLevel: this.thinkingLevel, isScoped: false };
|
|
@@ -1526,20 +1794,21 @@ Task: given the CURRENT MEMORY and the LATEST CONVERSATION TURN, produce the COM
|
|
|
1526
1794
|
/**
|
|
1527
1795
|
* Set thinking level.
|
|
1528
1796
|
* Clamps to model capabilities based on available thinking levels.
|
|
1529
|
-
* Saves to session
|
|
1797
|
+
* Saves the clamped level to the session transcript only if the level actually changes.
|
|
1798
|
+
* Persists the requested level to global defaults only when options.persist is true.
|
|
1530
1799
|
*/
|
|
1531
|
-
setThinkingLevel(level) {
|
|
1800
|
+
setThinkingLevel(level, options = {}) {
|
|
1532
1801
|
const availableLevels = this.getAvailableThinkingLevels();
|
|
1533
1802
|
const effectiveLevel = availableLevels.includes(level) ? level : this._clampThinkingLevel(level, availableLevels);
|
|
1534
1803
|
// Only persist if actually changing
|
|
1535
1804
|
const previousLevel = this.agent.state.thinkingLevel;
|
|
1536
1805
|
const isChanging = effectiveLevel !== previousLevel;
|
|
1537
1806
|
this.agent.state.thinkingLevel = effectiveLevel;
|
|
1807
|
+
if (options.persist) {
|
|
1808
|
+
this.settingsManager.setDefaultThinkingLevel(level);
|
|
1809
|
+
}
|
|
1538
1810
|
if (isChanging) {
|
|
1539
1811
|
this.sessionManager.appendThinkingLevelChange(effectiveLevel);
|
|
1540
|
-
if (this.supportsThinking() || effectiveLevel !== "off") {
|
|
1541
|
-
this.settingsManager.setDefaultThinkingLevel(effectiveLevel);
|
|
1542
|
-
}
|
|
1543
1812
|
this._emit({ type: "thinking_level_changed", level: effectiveLevel });
|
|
1544
1813
|
void this._extensionRunner.emit({
|
|
1545
1814
|
type: "thinking_level_select",
|
|
@@ -1552,14 +1821,14 @@ Task: given the CURRENT MEMORY and the LATEST CONVERSATION TURN, produce the COM
|
|
|
1552
1821
|
* Cycle to next thinking level.
|
|
1553
1822
|
* @returns New level, or undefined if model doesn't support thinking
|
|
1554
1823
|
*/
|
|
1555
|
-
cycleThinkingLevel() {
|
|
1824
|
+
cycleThinkingLevel(options = {}) {
|
|
1556
1825
|
if (!this.supportsThinking())
|
|
1557
1826
|
return undefined;
|
|
1558
1827
|
const levels = this.getAvailableThinkingLevels();
|
|
1559
1828
|
const currentIndex = levels.indexOf(this.thinkingLevel);
|
|
1560
1829
|
const nextIndex = (currentIndex + 1) % levels.length;
|
|
1561
1830
|
const nextLevel = levels[nextIndex];
|
|
1562
|
-
this.setThinkingLevel(nextLevel);
|
|
1831
|
+
this.setThinkingLevel(nextLevel, options);
|
|
1563
1832
|
return nextLevel;
|
|
1564
1833
|
}
|
|
1565
1834
|
/**
|
|
@@ -1568,7 +1837,7 @@ Task: given the CURRENT MEMORY and the LATEST CONVERSATION TURN, produce the COM
|
|
|
1568
1837
|
*/
|
|
1569
1838
|
getAvailableThinkingLevels() {
|
|
1570
1839
|
if (!this.model)
|
|
1571
|
-
return
|
|
1840
|
+
return [...THINKING_LEVEL_OPTIONS];
|
|
1572
1841
|
return getSupportedThinkingLevels(this.model);
|
|
1573
1842
|
}
|
|
1574
1843
|
/**
|
|
@@ -1577,10 +1846,17 @@ Task: given the CURRENT MEMORY and the LATEST CONVERSATION TURN, produce the COM
|
|
|
1577
1846
|
supportsThinking() {
|
|
1578
1847
|
return !!this.model?.reasoning;
|
|
1579
1848
|
}
|
|
1580
|
-
_getThinkingLevelForModelSwitch(explicitLevel) {
|
|
1849
|
+
_getThinkingLevelForModelSwitch(targetModel, explicitLevel) {
|
|
1581
1850
|
if (explicitLevel !== undefined) {
|
|
1582
1851
|
return explicitLevel;
|
|
1583
1852
|
}
|
|
1853
|
+
// Per-model default takes priority when switching to a model that has one
|
|
1854
|
+
if (targetModel) {
|
|
1855
|
+
const perModel = this.settingsManager.getModelThinkingLevel(targetModel.provider, targetModel.id);
|
|
1856
|
+
if (perModel !== undefined) {
|
|
1857
|
+
return perModel;
|
|
1858
|
+
}
|
|
1859
|
+
}
|
|
1584
1860
|
if (!this.supportsThinking()) {
|
|
1585
1861
|
return this.settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;
|
|
1586
1862
|
}
|
|
@@ -1615,15 +1891,30 @@ Task: given the CURRENT MEMORY and the LATEST CONVERSATION TURN, produce the COM
|
|
|
1615
1891
|
// =========================================================================
|
|
1616
1892
|
// Compaction
|
|
1617
1893
|
// =========================================================================
|
|
1894
|
+
/** Generate Pi's built-in compaction summary for manual and automatic compaction. */
|
|
1895
|
+
async _runDefaultCompaction(preparation, requestModel, apiKey, headers, customInstructions, signal, env, reason) {
|
|
1896
|
+
return compact(preparation, requestModel, apiKey, headers, customInstructions, signal, this.thinkingLevel, this.agent.streamFunction, env, this.settingsManager.getRetrySettings(), this._summarizationRetryCallbacks({ source: "compaction", reason }), undefined);
|
|
1897
|
+
}
|
|
1618
1898
|
/**
|
|
1619
1899
|
* Manually compact the session context.
|
|
1620
|
-
*
|
|
1900
|
+
*
|
|
1901
|
+
* This is the manual entry point used by `/compact`, RPC, and extensions. It is
|
|
1902
|
+
* separate from automatic threshold/overflow compaction, which enters through
|
|
1903
|
+
* `_checkCompaction()` and `_runAutoCompaction()`. After preparation and the
|
|
1904
|
+
* `session_before_compact` hook, both paths call the lower-level `compact()`
|
|
1905
|
+
* function imported from `./compaction/index.ts`, unless the hook cancels or
|
|
1906
|
+
* supplies a custom result.
|
|
1907
|
+
*
|
|
1908
|
+
* Aborts the current agent operation first. Manual compaction never retries or
|
|
1909
|
+
* continues the interrupted agent turn.
|
|
1910
|
+
*
|
|
1621
1911
|
* @param customInstructions Optional instructions for the compaction summary
|
|
1622
1912
|
*/
|
|
1623
1913
|
async compact(customInstructions) {
|
|
1624
1914
|
await this.abort();
|
|
1625
1915
|
this._compactionAbortController = new AbortController();
|
|
1626
1916
|
this._emit({ type: "compaction_start", reason: "manual" });
|
|
1917
|
+
let fromExtension = false;
|
|
1627
1918
|
try {
|
|
1628
1919
|
if (!this.model) {
|
|
1629
1920
|
throw new Error(formatNoModelSelectedMessage());
|
|
@@ -1641,7 +1932,6 @@ Task: given the CURRENT MEMORY and the LATEST CONVERSATION TURN, produce the COM
|
|
|
1641
1932
|
throw new Error("Nothing to compact (session too small)");
|
|
1642
1933
|
}
|
|
1643
1934
|
let extensionCompaction;
|
|
1644
|
-
let fromExtension = false;
|
|
1645
1935
|
if (this._extensionRunner.hasHandlers("session_before_compact")) {
|
|
1646
1936
|
const result = (await this._extensionRunner.emit({
|
|
1647
1937
|
type: "session_before_compact",
|
|
@@ -1674,8 +1964,8 @@ Task: given the CURRENT MEMORY and the LATEST CONVERSATION TURN, produce the COM
|
|
|
1674
1964
|
details = extensionCompaction.details;
|
|
1675
1965
|
}
|
|
1676
1966
|
else {
|
|
1677
|
-
//
|
|
1678
|
-
const result = await
|
|
1967
|
+
// Shared default summary generator, also used by automatic compaction.
|
|
1968
|
+
const result = await this._runDefaultCompaction(preparation, requestModel, apiKey, headers, customInstructions, this._compactionAbortController.signal, env, "manual");
|
|
1679
1969
|
summary = result.summary;
|
|
1680
1970
|
firstKeptEntryId = result.firstKeptEntryId;
|
|
1681
1971
|
tokensBefore = result.tokensBefore;
|
|
@@ -1723,6 +2013,7 @@ Task: given the CURRENT MEMORY and the LATEST CONVERSATION TURN, produce the COM
|
|
|
1723
2013
|
catch (error) {
|
|
1724
2014
|
const message = error instanceof Error ? error.message : String(error);
|
|
1725
2015
|
const aborted = message === "Compaction cancelled" || (error instanceof Error && error.name === "AbortError");
|
|
2016
|
+
const errorMessage = aborted ? undefined : `Compaction failed: ${message}`;
|
|
1726
2017
|
this._compactionAbortController = undefined;
|
|
1727
2018
|
this._emit({
|
|
1728
2019
|
type: "compaction_end",
|
|
@@ -1730,7 +2021,14 @@ Task: given the CURRENT MEMORY and the LATEST CONVERSATION TURN, produce the COM
|
|
|
1730
2021
|
result: undefined,
|
|
1731
2022
|
aborted,
|
|
1732
2023
|
willRetry: false,
|
|
1733
|
-
errorMessage
|
|
2024
|
+
errorMessage,
|
|
2025
|
+
});
|
|
2026
|
+
await this._emitSessionCompactFailed({
|
|
2027
|
+
reason: "manual",
|
|
2028
|
+
errorMessage,
|
|
2029
|
+
aborted,
|
|
2030
|
+
willRetry: false,
|
|
2031
|
+
fromExtension,
|
|
1734
2032
|
});
|
|
1735
2033
|
throw error;
|
|
1736
2034
|
}
|
|
@@ -1752,16 +2050,25 @@ Task: given the CURRENT MEMORY and the LATEST CONVERSATION TURN, produce the COM
|
|
|
1752
2050
|
this._branchSummaryAbortController?.abort();
|
|
1753
2051
|
}
|
|
1754
2052
|
/**
|
|
1755
|
-
*
|
|
1756
|
-
*
|
|
2053
|
+
* Dispatch automatic compaction after `agent_end` or before prompt submission.
|
|
2054
|
+
* Manual compaction does not call this method; it enters through `compact()`.
|
|
1757
2055
|
*
|
|
1758
|
-
*
|
|
1759
|
-
* 1.
|
|
1760
|
-
* remove the assistant message, compact, and
|
|
1761
|
-
* 2.
|
|
2056
|
+
* Automatic cases:
|
|
2057
|
+
* 1. Overflow with retry: a context-overflow error or recoverable length stop;
|
|
2058
|
+
* remove the failed assistant message, compact, and retry the turn once.
|
|
2059
|
+
* 2. Overflow without retry: a successful response exceeded the configured
|
|
2060
|
+
* context window; compact but preserve the completed response.
|
|
2061
|
+
* 3. Threshold without retry: valid or estimated context usage crossed the
|
|
2062
|
+
* configured threshold; compact without retrying the completed response.
|
|
2063
|
+
*
|
|
2064
|
+
* Each case calls `_runAutoCompaction()`. After preparation and the
|
|
2065
|
+
* `session_before_compact` hook, that method calls the lower-level `compact()`
|
|
2066
|
+
* function imported from `./compaction/index.ts`, unless the hook cancels or
|
|
2067
|
+
* supplies a custom result.
|
|
1762
2068
|
*
|
|
1763
2069
|
* @param assistantMessage The assistant message to check
|
|
1764
2070
|
* @param skipAbortedCheck If false, include aborted messages (for pre-prompt check). Default: true
|
|
2071
|
+
* @returns Whether the post-run loop should call `agent.continue()` for overflow recovery or queued messages
|
|
1765
2072
|
*/
|
|
1766
2073
|
async _checkCompaction(assistantMessage, skipAbortedCheck = true) {
|
|
1767
2074
|
const settings = this.settingsManager.getCompactionSettings();
|
|
@@ -1784,38 +2091,49 @@ Task: given the CURRENT MEMORY and the LATEST CONVERSATION TURN, produce the COM
|
|
|
1784
2091
|
if (assistantIsFromBeforeCompaction) {
|
|
1785
2092
|
return false;
|
|
1786
2093
|
}
|
|
1787
|
-
//
|
|
2094
|
+
// Automatic cases 1 and 2: context overflow.
|
|
1788
2095
|
// A length stop is recoverable when output ended below the model's original desired limit,
|
|
1789
2096
|
// independent of the configured context size or any context-clamped provider request limit.
|
|
1790
|
-
|
|
1791
|
-
// assistant answer already completed and agent.continue() cannot continue from an assistant.
|
|
2097
|
+
const contextOverflow = sameModel && isContextOverflow(assistantMessage, contextWindow);
|
|
1792
2098
|
const recoverableLength = sameModel && isRecoverableLength(assistantMessage, this.model?.maxTokens ?? 0);
|
|
1793
|
-
if (
|
|
2099
|
+
if (contextOverflow || recoverableLength) {
|
|
1794
2100
|
const willRetry = assistantMessage.stopReason !== "stop";
|
|
2101
|
+
// Case 2: the response completed successfully. Compact, but do not retry because
|
|
2102
|
+
// agent.continue() cannot continue from a completed assistant response.
|
|
1795
2103
|
if (!willRetry) {
|
|
1796
2104
|
return await this._runAutoCompaction("overflow", false);
|
|
1797
2105
|
}
|
|
1798
2106
|
if (this._overflowRecoveryAttempted) {
|
|
2107
|
+
const errorMessage = contextOverflow
|
|
2108
|
+
? "Context overflow recovery failed after one compact-and-retry attempt. Try reducing context or switching to a larger-context model."
|
|
2109
|
+
: "Truncated response recovery failed after one compact-and-retry attempt.";
|
|
1799
2110
|
this._emit({
|
|
1800
2111
|
type: "compaction_end",
|
|
1801
2112
|
reason: "overflow",
|
|
1802
2113
|
result: undefined,
|
|
1803
2114
|
aborted: false,
|
|
1804
2115
|
willRetry: false,
|
|
1805
|
-
errorMessage
|
|
2116
|
+
errorMessage,
|
|
2117
|
+
});
|
|
2118
|
+
await this._emitSessionCompactFailed({
|
|
2119
|
+
reason: "overflow",
|
|
2120
|
+
errorMessage,
|
|
2121
|
+
aborted: false,
|
|
2122
|
+
willRetry: false,
|
|
2123
|
+
fromExtension: false,
|
|
1806
2124
|
});
|
|
1807
2125
|
return false;
|
|
1808
2126
|
}
|
|
2127
|
+
// Case 1: remove the failed or truncated message from agent state, compact, and
|
|
2128
|
+
// retry once. The message remains in session history but is excluded from retry context.
|
|
1809
2129
|
this._overflowRecoveryAttempted = true;
|
|
1810
|
-
// Remove the failed or truncated message from agent state. It remains in session history,
|
|
1811
|
-
// but must not be included in the compact-and-retry context.
|
|
1812
2130
|
const messages = this.agent.state.messages;
|
|
1813
2131
|
if (messages.length > 0 && messages[messages.length - 1].role === "assistant") {
|
|
1814
2132
|
this.agent.state.messages = messages.slice(0, -1);
|
|
1815
2133
|
}
|
|
1816
2134
|
return await this._runAutoCompaction("overflow", willRetry);
|
|
1817
2135
|
}
|
|
1818
|
-
// Case
|
|
2136
|
+
// Case 3: threshold compaction without retry.
|
|
1819
2137
|
// For error messages or all-zero usage messages, estimate from the last valid response.
|
|
1820
2138
|
// This ensures sessions that hit persistent API errors (e.g. 529) or malformed zero-usage
|
|
1821
2139
|
// responses can still compact and do not reset context accounting.
|
|
@@ -1824,16 +2142,18 @@ Task: given the CURRENT MEMORY and the LATEST CONVERSATION TURN, produce the COM
|
|
|
1824
2142
|
if (assistantMessage.stopReason === "error" || directContextTokens === 0) {
|
|
1825
2143
|
const messages = this.agent.state.messages;
|
|
1826
2144
|
const estimate = estimateContextTokens(messages);
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
2145
|
+
// Without provider usage, estimate.tokens is the pure message-size estimate.
|
|
2146
|
+
// Only usage-backed estimates need the stale pre-compaction check.
|
|
2147
|
+
if (estimate.lastUsageIndex !== null) {
|
|
2148
|
+
// Verify the usage source is post-compaction. Kept pre-compaction messages
|
|
2149
|
+
// have stale usage reflecting the old (larger) context and would falsely
|
|
2150
|
+
// trigger compaction right after one just finished.
|
|
2151
|
+
const usageMsg = messages[estimate.lastUsageIndex];
|
|
2152
|
+
if (compactionEntry &&
|
|
2153
|
+
usageMsg.role === "assistant" &&
|
|
2154
|
+
usageMsg.timestamp <= new Date(compactionEntry.timestamp).getTime()) {
|
|
2155
|
+
return false;
|
|
2156
|
+
}
|
|
1837
2157
|
}
|
|
1838
2158
|
contextTokens = estimate.tokens;
|
|
1839
2159
|
}
|
|
@@ -1846,11 +2166,19 @@ Task: given the CURRENT MEMORY and the LATEST CONVERSATION TURN, produce the COM
|
|
|
1846
2166
|
return false;
|
|
1847
2167
|
}
|
|
1848
2168
|
/**
|
|
1849
|
-
*
|
|
2169
|
+
* Execute threshold or overflow compaction. Manual compaction uses
|
|
2170
|
+
* `AgentSession.compact()` instead. Both paths call the lower-level `compact()`
|
|
2171
|
+
* function imported from `./compaction/index.ts` after preparation and extension
|
|
2172
|
+
* interception.
|
|
2173
|
+
*
|
|
2174
|
+
* @param reason Automatic trigger selected by `_checkCompaction()`
|
|
2175
|
+
* @param willRetry Whether to continue the interrupted turn after overflow compaction
|
|
2176
|
+
* @returns Whether the post-run loop should call `agent.continue()`
|
|
1850
2177
|
*/
|
|
1851
2178
|
async _runAutoCompaction(reason, willRetry) {
|
|
1852
2179
|
const settings = this.settingsManager.getCompactionSettings();
|
|
1853
2180
|
let started = false;
|
|
2181
|
+
let fromExtension = false;
|
|
1854
2182
|
try {
|
|
1855
2183
|
if (!this.model) {
|
|
1856
2184
|
return false;
|
|
@@ -1865,7 +2193,6 @@ Task: given the CURRENT MEMORY and the LATEST CONVERSATION TURN, produce the COM
|
|
|
1865
2193
|
this._autoCompactionAbortController = new AbortController();
|
|
1866
2194
|
started = true;
|
|
1867
2195
|
let extensionCompaction;
|
|
1868
|
-
let fromExtension = false;
|
|
1869
2196
|
if (this._extensionRunner.hasHandlers("session_before_compact")) {
|
|
1870
2197
|
const extensionResult = (await this._extensionRunner.emit({
|
|
1871
2198
|
type: "session_before_compact",
|
|
@@ -1884,6 +2211,12 @@ Task: given the CURRENT MEMORY and the LATEST CONVERSATION TURN, produce the COM
|
|
|
1884
2211
|
aborted: true,
|
|
1885
2212
|
willRetry: false,
|
|
1886
2213
|
});
|
|
2214
|
+
await this._emitSessionCompactFailed({
|
|
2215
|
+
reason,
|
|
2216
|
+
aborted: true,
|
|
2217
|
+
willRetry: false,
|
|
2218
|
+
fromExtension: false,
|
|
2219
|
+
});
|
|
1887
2220
|
return false;
|
|
1888
2221
|
}
|
|
1889
2222
|
if (extensionResult?.compaction) {
|
|
@@ -1905,8 +2238,8 @@ Task: given the CURRENT MEMORY and the LATEST CONVERSATION TURN, produce the COM
|
|
|
1905
2238
|
details = extensionCompaction.details;
|
|
1906
2239
|
}
|
|
1907
2240
|
else {
|
|
1908
|
-
//
|
|
1909
|
-
const compactResult = await
|
|
2241
|
+
// Shared default summary generator, also used by manual compaction.
|
|
2242
|
+
const compactResult = await this._runDefaultCompaction(preparation, requestModel, apiKey, headers, undefined, this._autoCompactionAbortController.signal, env, reason);
|
|
1910
2243
|
summary = compactResult.summary;
|
|
1911
2244
|
firstKeptEntryId = compactResult.firstKeptEntryId;
|
|
1912
2245
|
tokensBefore = compactResult.tokensBefore;
|
|
@@ -1921,6 +2254,12 @@ Task: given the CURRENT MEMORY and the LATEST CONVERSATION TURN, produce the COM
|
|
|
1921
2254
|
aborted: true,
|
|
1922
2255
|
willRetry: false,
|
|
1923
2256
|
});
|
|
2257
|
+
await this._emitSessionCompactFailed({
|
|
2258
|
+
reason,
|
|
2259
|
+
aborted: true,
|
|
2260
|
+
willRetry: false,
|
|
2261
|
+
fromExtension,
|
|
2262
|
+
});
|
|
1924
2263
|
return false;
|
|
1925
2264
|
}
|
|
1926
2265
|
this.sessionManager.appendCompaction(summary, firstKeptEntryId, tokensBefore, details, fromExtension, usage);
|
|
@@ -1967,15 +2306,23 @@ Task: given the CURRENT MEMORY and the LATEST CONVERSATION TURN, produce the COM
|
|
|
1967
2306
|
catch (error) {
|
|
1968
2307
|
const errorMessage = error instanceof Error ? error.message : "compaction failed";
|
|
1969
2308
|
if (started) {
|
|
2309
|
+
const formattedErrorMessage = reason === "overflow"
|
|
2310
|
+
? `Context overflow recovery failed: ${errorMessage}`
|
|
2311
|
+
: `Auto-compaction failed: ${errorMessage}`;
|
|
1970
2312
|
this._emit({
|
|
1971
2313
|
type: "compaction_end",
|
|
1972
2314
|
reason,
|
|
1973
2315
|
result: undefined,
|
|
1974
2316
|
aborted: false,
|
|
1975
2317
|
willRetry: false,
|
|
1976
|
-
errorMessage:
|
|
1977
|
-
|
|
1978
|
-
|
|
2318
|
+
errorMessage: formattedErrorMessage,
|
|
2319
|
+
});
|
|
2320
|
+
await this._emitSessionCompactFailed({
|
|
2321
|
+
reason,
|
|
2322
|
+
errorMessage: formattedErrorMessage,
|
|
2323
|
+
aborted: false,
|
|
2324
|
+
willRetry: false,
|
|
2325
|
+
fromExtension,
|
|
1979
2326
|
});
|
|
1980
2327
|
}
|
|
1981
2328
|
return false;
|
|
@@ -2290,13 +2637,42 @@ Task: given the CURRENT MEMORY and the LATEST CONVERSATION TURN, produce the COM
|
|
|
2290
2637
|
}
|
|
2291
2638
|
// Ada Memory Engine tools (memory_add/replace/remove/search,
|
|
2292
2639
|
// session_search, scratchpad, memory_status). Exposed when enabled.
|
|
2640
|
+
// Solo en la sesión principal: un subagente no debe poder mutar la
|
|
2641
|
+
// memoria durable del usuario (anti-recursión, igual que goal_* y
|
|
2642
|
+
// workflow abajo). Hasta ahora la propiedad se sostenía solo por la
|
|
2643
|
+
// allowlist de tools del call site, no por una guardia aquí.
|
|
2293
2644
|
const memoryEngine = this._resourceLoader.getMemoryEngine();
|
|
2294
|
-
if (memoryEngine && this.settingsManager.getProjectMemoryEnabled()) {
|
|
2645
|
+
if (memoryEngine && !this._isSubagentSession && this.settingsManager.getProjectMemoryEnabled()) {
|
|
2295
2646
|
const engineTools = createMemoryEngineTools(memoryEngine);
|
|
2296
2647
|
for (const [name, tool] of Object.entries(engineTools)) {
|
|
2297
2648
|
this._baseToolDefinitions.set(name, tool);
|
|
2298
2649
|
}
|
|
2299
2650
|
}
|
|
2651
|
+
// Ada Intelligence Engine: tools del GoalEngine (resuelven el goal
|
|
2652
|
+
// activo por llamada). Registradas si el GoalEngine está habilitado.
|
|
2653
|
+
// Los subagentes NO reciben goal_*/workflow tools: solo el agente
|
|
2654
|
+
// principal orquesta el engine (anti-recursión y control de presupuesto).
|
|
2655
|
+
const goalEngine = this._isSubagentSession ? null : this._resourceLoader.getGoalEngine?.();
|
|
2656
|
+
if (goalEngine && this.settingsManager.getGoalEngineEnabled()) {
|
|
2657
|
+
for (const tool of goalSessionTools(goalEngine, () => this.sessionManager.getSessionId())) {
|
|
2658
|
+
this._baseToolDefinitions.set(tool.name, tool);
|
|
2659
|
+
}
|
|
2660
|
+
// graph_add_nodes: registros puntuales (QA_FINDING/RISK/DECISION).
|
|
2661
|
+
// El spine se auto-registra vía GraphSync — esto es complemento.
|
|
2662
|
+
if (this.settingsManager.getGraphEnabled()) {
|
|
2663
|
+
this._baseToolDefinitions.set("graph_add_nodes", createGraphTool(() => this._resourceLoader.getGraph?.()));
|
|
2664
|
+
}
|
|
2665
|
+
}
|
|
2666
|
+
// Tool `workflow` SOLO en la sesión principal: los subagentes no
|
|
2667
|
+
// orquestan workflows (anti-anidamiento y control de presupuesto).
|
|
2668
|
+
if (!this._isSubagentSession) {
|
|
2669
|
+
this._baseToolDefinitions.set("workflow", createWorkflowTool({
|
|
2670
|
+
getManager: () => this._resourceLoader.getWorkflowManager?.(),
|
|
2671
|
+
confirm: (prompt) => this._confirmWorkflowLaunch(prompt),
|
|
2672
|
+
agentDir: this._resourceLoader.getAgentDir(),
|
|
2673
|
+
sessionId: () => this.sessionManager.getSessionId(),
|
|
2674
|
+
}));
|
|
2675
|
+
}
|
|
2300
2676
|
const extensionsResult = this._resourceLoader.getExtensions();
|
|
2301
2677
|
if (options.flagValues) {
|
|
2302
2678
|
for (const [name, value] of options.flagValues) {
|