micro-models-agent 2.11.0 → 2.13.1
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 +39 -0
- package/dist/assets/app.js +22 -2
- package/dist/assets/index.html +39 -9
- package/dist/assets/js/dom.js +15 -0
- package/dist/assets/js/feed.js +129 -10
- package/dist/assets/js/sidebar.js +512 -0
- package/dist/assets/js/tabs.js +30 -5
- package/dist/assets/setup.js +267 -8
- package/dist/assets/styles.css +168 -3
- package/dist/cli/cache-line.js +1 -0
- package/dist/cli/command-suggest.js +5 -4
- package/dist/cli/commands.js +231 -122
- package/dist/cli/completer.js +132 -31
- package/dist/cli/index.js +1 -0
- package/dist/cli/json-payload.js +4 -4
- package/dist/cli/main.js +166 -61
- package/dist/cli/onboarding-commands.js +126 -0
- package/dist/cli/plugin-commands.js +2 -1
- package/dist/cli/relaunch.js +16 -13
- package/dist/cli/repl-commands-lsp.js +75 -0
- package/dist/cli/repl-commands-skills.js +105 -0
- package/dist/cli/repl-commands.js +589 -266
- package/dist/cli/repl.js +436 -177
- package/dist/cli/run-result.js +5 -6
- package/dist/cli/security-commands.js +37 -28
- package/dist/cli/setup-order.js +4 -55
- package/dist/cli/setup-prompt.js +3 -2
- package/dist/cli/setup.js +27 -107
- package/dist/cli/web-command.js +98 -0
- package/dist/config/budget.js +5 -5
- package/dist/config/config.js +103 -96
- package/dist/config/defaults.js +38 -8
- package/dist/config/domains.js +24 -27
- package/dist/config/env.js +46 -0
- package/dist/config/experts.js +2 -0
- package/dist/config/index.js +1 -0
- package/dist/config/paths.js +56 -0
- package/dist/config/redact.js +44 -0
- package/dist/config/registry-extra.js +334 -0
- package/dist/config/registry.js +584 -0
- package/dist/config/security.js +35 -36
- package/dist/config/timeouts.js +74 -0
- package/dist/config/utils.js +16 -15
- package/dist/core/agent/artifact-progress.js +59 -0
- package/dist/core/agent/artifact-resolve.js +79 -0
- package/dist/core/agent/audit-gate.js +7 -3
- package/dist/core/agent/compaction.js +2 -2
- package/dist/core/agent/constants.js +33 -4
- package/dist/core/agent/context-log.js +454 -0
- package/dist/core/agent/context-renderer.js +5 -0
- package/dist/core/agent/critic-gate.js +132 -0
- package/dist/core/agent/hallucination-gate.js +148 -38
- package/dist/core/agent/loop-state.js +15 -0
- package/dist/core/agent/prefix-monitor.js +1 -1
- package/dist/core/agent/reasoning-resolver.js +10 -1
- package/dist/core/agent/token-tracker.js +7 -4
- package/dist/core/agent/tool-batch.js +93 -18
- package/dist/core/agent/tool-images.js +18 -0
- package/dist/core/agent/tool-output.js +65 -11
- package/dist/core/agent/tool-pairing.js +60 -0
- package/dist/core/agent-moe.js +25 -24
- package/dist/core/agent.js +429 -108
- package/dist/core/bootstrap/agent-phase.js +66 -0
- package/dist/core/bootstrap/config-phase.js +86 -0
- package/dist/core/bootstrap/modules-phase.js +269 -0
- package/dist/core/bootstrap/provider-phase.js +183 -0
- package/dist/core/bootstrap/session-phase.js +204 -0
- package/dist/core/bootstrap/state.js +94 -0
- package/dist/core/bootstrap/workspace-phase.js +115 -0
- package/dist/core/bootstrap.js +92 -660
- package/dist/core/crash-handler.js +17 -7
- package/dist/core/environment.js +37 -12
- package/dist/core/host-plan.js +43 -0
- package/dist/core/host.js +23 -0
- package/dist/core/index.js +1 -0
- package/dist/core/prompt-builder.js +17 -1
- package/dist/core/prompt-overflow.js +42 -43
- package/dist/core/session-logger.js +122 -30
- package/dist/core/system-prompt.js +117 -0
- package/dist/core/version.js +6 -4
- package/dist/core/web-host.js +34 -0
- package/dist/core/workspace.js +19 -15
- package/dist/i18n/en.json +89 -3
- package/dist/i18n/index.js +37 -3
- package/dist/i18n/ru.json +89 -3
- package/dist/index.js +7 -3
- package/dist/llm/image-utils.js +55 -64
- package/dist/llm/llm-errors.js +9 -0
- package/dist/llm/model-loader.js +10 -32
- package/dist/llm/models-dev.js +121 -0
- package/dist/llm/openai-compat.js +146 -73
- package/dist/llm/orchestrator.js +33 -11
- package/dist/llm/provider-budget.js +2 -2
- package/dist/llm/provider-context.js +233 -0
- package/dist/llm/provider.js +1 -1
- package/dist/llm/response.js +5 -0
- package/dist/llm/token-counter.js +27 -11
- package/dist/logger/app-logger.js +48 -22
- package/dist/logger/file-log.js +28 -19
- package/dist/logger/index.js +1 -0
- package/dist/main.js +888 -139
- package/dist/migration/backup.js +14 -3
- package/dist/migration/detect.js +12 -3
- package/dist/migration/index.js +1 -0
- package/dist/modules/artifacts/store.js +9 -8
- package/dist/modules/browser/actions.js +6 -0
- package/dist/modules/browser/bridge-client.js +14 -12
- package/dist/modules/browser/bridge-path.js +4 -4
- package/dist/modules/browser/console-buffer.js +37 -0
- package/dist/modules/browser/cookie-store.js +5 -0
- package/dist/modules/browser/driver-types.js +1 -0
- package/dist/modules/browser/driver.js +19 -11
- package/dist/modules/browser/index.js +3 -1
- package/dist/modules/browser/module.js +2 -1
- package/dist/modules/browser/session.js +10 -30
- package/dist/modules/browser/snapshot.js +19 -13
- package/dist/modules/browser/types.js +1 -0
- package/dist/modules/certification/cli.js +28 -20
- package/dist/modules/certification/fact-checker.js +9 -1
- package/dist/modules/certification/loader.js +9 -2
- package/dist/modules/certification/manifest.js +83 -21
- package/dist/modules/certification/runner.js +23 -13
- package/dist/modules/certification/scenarios.js +20 -20
- package/dist/modules/certification/syntax-scenarios.js +1 -2
- package/dist/modules/context/chunk-query.js +11 -9
- package/dist/modules/context/fact-extractor.js +37 -39
- package/dist/modules/context/index.js +1 -0
- package/dist/modules/context/manager.js +106 -80
- package/dist/modules/critic/client.js +176 -0
- package/dist/modules/critic/evidence.js +81 -0
- package/dist/modules/critic/provider.js +45 -0
- package/dist/modules/critic/tools.js +78 -0
- package/dist/modules/critic/types.js +1 -0
- package/dist/modules/execution/audit-runners.js +28 -34
- package/dist/modules/execution/auditor.js +53 -49
- package/dist/modules/execution/execution-plugin.js +142 -102
- package/dist/modules/execution/index.js +1 -1
- package/dist/modules/execution/input-from.js +37 -13
- package/dist/modules/execution/module.js +368 -191
- package/dist/modules/execution/moe-executor.js +53 -26
- package/dist/modules/execution/plan-actions.js +320 -202
- package/dist/modules/execution/plan-checks.js +35 -0
- package/dist/modules/execution/plan-coverage.js +36 -33
- package/dist/modules/execution/plan-steps.js +11 -3
- package/dist/modules/execution/plan-store.js +83 -17
- package/dist/modules/execution/plan-tool.js +89 -35
- package/dist/modules/execution/plan-validator.js +30 -10
- package/dist/modules/execution/planner.js +22 -13
- package/dist/modules/execution/stuck-detector.js +196 -93
- package/dist/modules/execution/tracker.js +22 -8
- package/dist/modules/execution/verifier.js +69 -48
- package/dist/modules/execution/windows-commands.js +12 -12
- package/dist/modules/hallucination/artifact-claim.js +93 -0
- package/dist/modules/hallucination/confidence.js +13 -11
- package/dist/modules/hallucination/consistency.js +10 -2
- package/dist/modules/hallucination/detector.js +10 -5
- package/dist/modules/hallucination/factual.js +43 -26
- package/dist/modules/hallucination/index.js +1 -0
- package/dist/modules/hallucination/js-identifiers.js +44 -45
- package/dist/modules/hallucination/llm-judge.js +17 -12
- package/dist/modules/hallucination/success-claim.js +59 -0
- package/dist/modules/indexer/cache.js +52 -4
- package/dist/modules/indexer/index.js +1 -0
- package/dist/modules/indexer/map-command.js +2 -4
- package/dist/modules/indexer/map-select.js +16 -16
- package/dist/modules/indexer/module.js +47 -12
- package/dist/modules/indexer/project-profile.js +8 -7
- package/dist/modules/indexer/symbols.js +15 -15
- package/dist/modules/indexer/walker.js +159 -29
- package/dist/modules/lsp/check-tool.js +7 -5
- package/dist/modules/lsp/client.js +39 -39
- package/dist/modules/lsp/command.js +17 -24
- package/dist/modules/lsp/config.js +12 -11
- package/dist/modules/lsp/index.js +1 -0
- package/dist/modules/lsp/module.js +48 -46
- package/dist/modules/lsp/probe.js +13 -14
- package/dist/modules/lsp/project-root.js +14 -17
- package/dist/modules/lsp/startup-check.js +18 -16
- package/dist/modules/mcp/client.js +59 -62
- package/dist/modules/mcp/index.js +1 -0
- package/dist/modules/mcp/module.js +66 -37
- package/dist/modules/mcp/registry.js +5 -0
- package/dist/modules/memory/index.js +1 -0
- package/dist/modules/memory/module.js +12 -8
- package/dist/modules/memory/search.js +4 -1
- package/dist/modules/memory/store.js +40 -2
- package/dist/modules/onboarding/init.js +47 -0
- package/dist/modules/onboarding/meet.js +30 -0
- package/dist/modules/onboarding/mode.js +30 -0
- package/dist/modules/onboarding/prompts.js +43 -0
- package/dist/modules/pipelines/engine.js +10 -0
- package/dist/modules/pipelines/index.js +1 -0
- package/dist/modules/pipelines/parser.js +4 -1
- package/dist/modules/pipelines/template.js +4 -0
- package/dist/modules/plugins/builtin/lint-on-write.js +80 -67
- package/dist/modules/plugins/builtin/notify.js +2 -0
- package/dist/modules/plugins/index.js +1 -0
- package/dist/modules/plugins/loader.js +18 -3
- package/dist/modules/plugins/manager.js +37 -17
- package/dist/modules/pricing/index.js +10 -11
- package/dist/modules/pricing/prices.js +12 -12
- package/dist/modules/processes/index.js +1 -0
- package/dist/modules/processes/kill-tree.js +27 -31
- package/dist/modules/processes/registry.js +44 -25
- package/dist/modules/processes/runner.js +4 -4
- package/dist/modules/providers/capabilities.js +28 -0
- package/dist/modules/providers/create.js +3 -4
- package/dist/modules/providers/factory.js +7 -7
- package/dist/modules/providers/fallback.js +12 -12
- package/dist/modules/providers/health.js +4 -4
- package/dist/modules/providers/manager.js +50 -19
- package/dist/modules/providers/naming.js +15 -0
- package/dist/modules/providers/preflight.js +71 -0
- package/dist/modules/providers/presets.js +39 -8
- package/dist/modules/providers/registry.js +7 -2
- package/dist/modules/reasoning/policy.js +8 -6
- package/dist/modules/reasoning/probe.js +30 -25
- package/dist/modules/security/audit-log.js +19 -36
- package/dist/modules/security/audit-notifier.js +35 -75
- package/dist/modules/security/command-validator.js +99 -51
- package/dist/modules/security/content-scanner.js +8 -8
- package/dist/modules/security/data-sanitizer.js +9 -16
- package/dist/modules/security/encryption.js +32 -52
- package/dist/modules/security/index.js +2 -1
- package/dist/modules/security/network-validator.js +120 -43
- package/dist/modules/security/path-validator.js +61 -46
- package/dist/modules/security/protected-paths.js +73 -0
- package/dist/modules/security/rate-limiter.js +17 -49
- package/dist/modules/security/security-policies.js +25 -57
- package/dist/modules/security/session-encryption.js +32 -71
- package/dist/modules/security/session-isolation.js +15 -28
- package/dist/modules/session/auto-name.js +63 -0
- package/dist/modules/session/export.js +98 -0
- package/dist/modules/session/index.js +1 -0
- package/dist/modules/session/manager.js +79 -28
- package/dist/modules/session/module.js +4 -3
- package/dist/modules/session/store.js +57 -20
- package/dist/modules/setup/answers.js +35 -0
- package/dist/modules/setup/apply.js +79 -0
- package/dist/modules/setup/discovery.js +72 -0
- package/dist/modules/skills/index.js +1 -0
- package/dist/modules/skills/loader.js +9 -1
- package/dist/modules/skills/module.js +11 -0
- package/dist/modules/updater/changelog-reader.js +15 -16
- package/dist/modules/updater/checker.js +9 -4
- package/dist/modules/updater/dev-detect.js +7 -6
- package/dist/modules/updater/index.js +1 -0
- package/dist/modules/updater/module.js +17 -15
- package/dist/modules/user-profile/compressor.js +2 -0
- package/dist/modules/user-profile/index.js +1 -0
- package/dist/modules/user-profile/profile.js +10 -1
- package/dist/modules/webui/answer-api.js +29 -0
- package/dist/modules/webui/assets.js +50 -0
- package/dist/modules/webui/body.js +21 -0
- package/dist/modules/webui/commands-settings.js +209 -0
- package/dist/modules/webui/commands-shared.js +60 -0
- package/dist/modules/webui/commands.js +174 -0
- package/dist/modules/webui/config-api.js +134 -0
- package/dist/modules/webui/file-api.js +202 -0
- package/dist/modules/webui/forward.js +159 -0
- package/dist/modules/webui/history-api.js +112 -0
- package/dist/modules/webui/host-state.js +60 -0
- package/dist/modules/webui/i18n-api.js +9 -0
- package/dist/modules/webui/limits.js +6 -0
- package/dist/modules/webui/log-forward.js +20 -0
- package/dist/modules/webui/memory-commands.js +64 -0
- package/dist/modules/webui/model-cache.js +18 -0
- package/dist/modules/webui/module.js +148 -0
- package/dist/modules/webui/persist.js +24 -0
- package/dist/modules/webui/prompt-io.js +97 -0
- package/dist/modules/webui/providers-api.js +337 -0
- package/dist/modules/webui/providers-view.js +56 -0
- package/dist/modules/webui/reasoning-view.js +15 -0
- package/dist/modules/webui/run-agent.js +81 -0
- package/dist/modules/webui/server.js +284 -0
- package/dist/modules/webui/sessions-api.js +178 -0
- package/dist/modules/webui/settings-api.js +561 -0
- package/dist/modules/webui/setup-api.js +201 -0
- package/dist/modules/webui/state.js +74 -0
- package/dist/modules/webui/util.js +261 -0
- package/dist/output/bus.js +7 -2
- package/dist/output/channel.js +80 -28
- package/dist/output/format.js +2 -1
- package/dist/output/index.js +1 -0
- package/dist/output/json-sink.js +5 -3
- package/dist/output/machine.js +4 -3
- package/dist/output/session-sink.js +4 -4
- package/dist/tools/approve.js +4 -0
- package/dist/tools/attach-image.js +5 -4
- package/dist/tools/auto-fixer.js +26 -44
- package/dist/tools/auto-tags.js +83 -0
- package/dist/tools/bash.js +193 -116
- package/dist/tools/browser.js +76 -31
- package/dist/tools/chunk-query.js +14 -6
- package/dist/tools/create-dir.js +9 -5
- package/dist/tools/delete-file.js +9 -5
- package/dist/tools/download-file.js +32 -7
- package/dist/tools/edit-file.js +52 -14
- package/dist/tools/enable-tools.js +6 -6
- package/dist/tools/executor.js +132 -27
- package/dist/tools/file-info.js +3 -1
- package/dist/tools/filter-tools.js +3 -3
- package/dist/tools/glob-tool.js +4 -1
- package/dist/tools/grep-tool.js +13 -10
- package/dist/tools/hidden-tools-block.js +6 -6
- package/dist/tools/index.js +16 -8
- package/dist/tools/list-dir.js +4 -2
- package/dist/tools/load-skill.js +7 -0
- package/dist/tools/mcp-call.js +15 -4
- package/dist/tools/meet-done.js +14 -0
- package/dist/tools/move-file.js +14 -7
- package/dist/tools/path-utils.js +29 -29
- package/dist/tools/pipeline-run.js +29 -7
- package/dist/tools/preview.js +1 -1
- package/dist/tools/process-ids.js +31 -0
- package/dist/tools/process-kill.js +9 -16
- package/dist/tools/process-list.js +1 -0
- package/dist/tools/process-log.js +11 -16
- package/dist/tools/process-wait.js +63 -0
- package/dist/tools/prompt-io.js +4 -3
- package/dist/tools/question.js +172 -25
- package/dist/tools/read-file.js +55 -34
- package/dist/tools/recall.js +14 -8
- package/dist/tools/registry.js +6 -5
- package/dist/tools/remember.js +8 -4
- package/dist/tools/scope-request.js +11 -6
- package/dist/tools/search-history.js +5 -2
- package/dist/tools/session-info.js +2 -0
- package/dist/tools/set-thinking.js +8 -4
- package/dist/tools/subagent.js +59 -39
- package/dist/tools/syntax-validator.js +292 -90
- package/dist/tools/user-input.js +22 -18
- package/dist/tools/web-browse.js +9 -3
- package/dist/tools/web-fetch.js +12 -23
- package/dist/tools/web-search.js +7 -5
- package/dist/tools/write-file.js +45 -15
- package/dist/ui/action-log.js +13 -0
- package/dist/ui/box.js +4 -3
- package/dist/ui/colors.js +2 -0
- package/dist/ui/diff.js +6 -5
- package/dist/ui/index.js +1 -0
- package/dist/ui/line-editor.js +230 -122
- package/dist/ui/line-math.js +10 -2
- package/dist/ui/md-formatter.js +57 -37
- package/dist/ui/output.js +8 -3
- package/dist/ui/plan-view.js +21 -10
- package/dist/ui/renderer.js +393 -67
- package/dist/ui/spinner.js +16 -5
- package/dist/ui/table.js +15 -17
- package/dist/ui/theme.js +143 -0
- package/dist/utils/child-run.js +20 -0
- package/dist/utils/error.js +1 -1
- package/dist/utils/index.js +2 -0
- package/dist/utils/retry.js +2 -2
- package/dist/utils/truncate.js +1 -1
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -2609,6 +2609,8 @@ The path was joined onto the working directory because it does not exist as give
|
|
|
2609
2609
|
{issues}
|
|
2610
2610
|
Summary: {summary}`,
|
|
2611
2611
|
"critic.advice": `A verifier flagged issues worth checking before you finish:
|
|
2612
|
+
{issues}`,
|
|
2613
|
+
"critic.repeat": `The verifier repeats a previously flagged problem — do not produce the same answer again. Change the approach, or finish honestly if the complaint does not apply:
|
|
2612
2614
|
{issues}`,
|
|
2613
2615
|
"tool.subagent_queued": "Sub-agent task queued: {task}",
|
|
2614
2616
|
"tool.subagent_artifact": `Sub-agent completed. Full result saved to artifact: {path}
|
|
@@ -3404,6 +3406,7 @@ Apply a matching solution from these results. If none is relevant — do NOT rep
|
|
|
3404
3406
|
"ui.todo_action": "{action} · {count}",
|
|
3405
3407
|
"ui.tool_running": "{tool}…",
|
|
3406
3408
|
"ui.step_context": "step {id}: {desc}",
|
|
3409
|
+
"ui.draft_retracted": "↳ draft rejected by verification, refining…",
|
|
3407
3410
|
"indexer.map_header": "Project map",
|
|
3408
3411
|
"indexer.top_directories": "Top directories",
|
|
3409
3412
|
"indexer.files": "Files",
|
|
@@ -3578,6 +3581,46 @@ Updated: {updatedAt}`,
|
|
|
3578
3581
|
"web.sidebar.session": "session",
|
|
3579
3582
|
"web.sidebar.usage": "usage",
|
|
3580
3583
|
"web.sidebar.env": "environment",
|
|
3584
|
+
"web.sidebar.tab_session": "Session",
|
|
3585
|
+
"web.sidebar.tab_map": "Map",
|
|
3586
|
+
"web.sidebar.tab_trace": "Trace",
|
|
3587
|
+
"web.sidebar.map_status": "status",
|
|
3588
|
+
"web.sidebar.map_ready": "ready",
|
|
3589
|
+
"web.sidebar.map_indexing": "indexing…",
|
|
3590
|
+
"web.sidebar.map_stale": "stale",
|
|
3591
|
+
"web.sidebar.map_updated": "updated",
|
|
3592
|
+
"web.sidebar.map_never": "never",
|
|
3593
|
+
"web.sidebar.map_today": "today, {time}",
|
|
3594
|
+
"web.sidebar.map_watcher": "watcher",
|
|
3595
|
+
"web.sidebar.map_on": "on",
|
|
3596
|
+
"web.sidebar.map_off": "off",
|
|
3597
|
+
"web.sidebar.map_files": "files",
|
|
3598
|
+
"web.sidebar.map_symbols": "symbols",
|
|
3599
|
+
"web.sidebar.map_tokens": "tokens",
|
|
3600
|
+
"web.sidebar.map_root": "root",
|
|
3601
|
+
"web.sidebar.map_languages": "languages",
|
|
3602
|
+
"web.sidebar.map_reindex": "Re-index",
|
|
3603
|
+
"web.sidebar.map_reindexing": "re-indexing…",
|
|
3604
|
+
"web.sidebar.map_reindex_failed": "re-index failed",
|
|
3605
|
+
"web.sidebar.trace_empty": "no events yet",
|
|
3606
|
+
"web.sidebar.trace_turn": "turn {n}",
|
|
3607
|
+
"web.sidebar.trace_text": "composing… {count} chars",
|
|
3608
|
+
"web.sidebar.trace_plan": "plan update",
|
|
3609
|
+
"web.sidebar.trace_question": "question",
|
|
3610
|
+
"web.sidebar.detail_metadata": "metadata",
|
|
3611
|
+
"web.sidebar.detail_arguments": "arguments",
|
|
3612
|
+
"web.sidebar.detail_output": "output",
|
|
3613
|
+
"web.sidebar.detail_error": "error",
|
|
3614
|
+
"web.sidebar.detail_text": "text",
|
|
3615
|
+
"web.sidebar.detail_plan": "plan",
|
|
3616
|
+
"web.sidebar.detail_reasoning": "reasoning",
|
|
3617
|
+
"web.sidebar.detail_status": "status",
|
|
3618
|
+
"web.sidebar.detail_ok": "ok",
|
|
3619
|
+
"web.sidebar.detail_fail": "failed",
|
|
3620
|
+
"web.sidebar.detail_duration": "duration",
|
|
3621
|
+
"web.sidebar.detail_time": "time",
|
|
3622
|
+
"web.sidebar.detail_tool_call": "tool call",
|
|
3623
|
+
"web.sidebar.detail_session": "session",
|
|
3581
3624
|
"web.env.dir": "dir",
|
|
3582
3625
|
"web.env.agents": "AGENTS.md",
|
|
3583
3626
|
"web.env.map": "map",
|
|
@@ -3972,6 +4015,7 @@ Updated: {updatedAt}`,
|
|
|
3972
4015
|
"web.history.loading": "loading…",
|
|
3973
4016
|
"web.history.unavailable": "— history unavailable",
|
|
3974
4017
|
"web.history.empty": "— empty session —",
|
|
4018
|
+
"web.scroll.latest": "latest",
|
|
3975
4019
|
"web.tool.output_one": "output · {count} char",
|
|
3976
4020
|
"web.tool.output_few": "output · {count} chars",
|
|
3977
4021
|
"web.tool.output_many": "output · {count} chars",
|
|
@@ -4015,7 +4059,7 @@ Updated: {updatedAt}`,
|
|
|
4015
4059
|
"web.setup.language.title": "Choose your language",
|
|
4016
4060
|
"web.setup.language.hint": "Used for the interface.",
|
|
4017
4061
|
"web.setup.provider.title": "Choose a provider",
|
|
4018
|
-
"web.setup.provider.hint": "For a local model pick the OpenAI-compatible option
|
|
4062
|
+
"web.setup.provider.hint": "For a local model pick the OpenAI-compatible option, scan for your server, then test the connection before continuing.",
|
|
4019
4063
|
"web.setup.provider.base_url": "Base URL",
|
|
4020
4064
|
"web.setup.provider.scan": "Scan for local servers",
|
|
4021
4065
|
"web.setup.provider.scan_found_one": "Found {count} server",
|
|
@@ -4024,6 +4068,10 @@ Updated: {updatedAt}`,
|
|
|
4024
4068
|
"web.setup.provider.scan_none": "No local servers found — enter the URL manually.",
|
|
4025
4069
|
"web.setup.provider.scan_failed": "Scan failed. Enter the URL manually.",
|
|
4026
4070
|
"web.setup.provider.required": "Please enter a base URL.",
|
|
4071
|
+
"web.setup.provider.test": "Test connection",
|
|
4072
|
+
"web.setup.provider.testing": "Testing…",
|
|
4073
|
+
"web.setup.provider.test_ok": "Server reachable.",
|
|
4074
|
+
"web.setup.provider.test_fail": "Could not reach the server at this URL.",
|
|
4027
4075
|
"web.setup.key.title": "API key",
|
|
4028
4076
|
"web.setup.key.hint": "Leave empty for local servers. Stored only in your config file and never shown again.",
|
|
4029
4077
|
"web.setup.key.label": "Key",
|
|
@@ -4042,15 +4090,54 @@ Updated: {updatedAt}`,
|
|
|
4042
4090
|
"web.setup.model.test_fail": "Could not reach the model.",
|
|
4043
4091
|
"web.setup.model.required": "Please choose or type a model.",
|
|
4044
4092
|
"web.setup.context.title": "Context & iterations",
|
|
4045
|
-
"web.setup.context.hint": "
|
|
4093
|
+
"web.setup.context.hint": "Must match the context your provider gives this model. Press Detect, or copy the value from LM Studio / Ollama / provider docs.",
|
|
4046
4094
|
"web.setup.context.contextWindow": "Context window (tokens)",
|
|
4047
4095
|
"web.setup.context.maxToolIterations": "Max tool iterations",
|
|
4048
4096
|
"web.setup.context.required": "Enter a positive number.",
|
|
4097
|
+
"web.setup.context.detect": "Detect from provider",
|
|
4098
|
+
"web.setup.context.detecting": "Detecting…",
|
|
4099
|
+
"web.setup.context.detect_ok": "Context set from provider: {count} tokens.",
|
|
4100
|
+
"web.setup.context.detect_fail": "Could not detect context — enter it manually.",
|
|
4049
4101
|
"web.setup.security.title": "Security",
|
|
4050
|
-
"web.setup.security.hint": "Safe defaults are on; turn off only what you need.",
|
|
4102
|
+
"web.setup.security.hint": "Safe defaults are on; turn off only what you need. Nothing is blocked silently — each toggle only asks the agent to confirm first.",
|
|
4051
4103
|
"web.setup.security.paths": "Restrict file access to the workspace",
|
|
4104
|
+
"web.setup.security.paths_desc": "The agent reads and writes only inside the workspace, and asks before touching .git, .env, keys and other sensitive paths.",
|
|
4052
4105
|
"web.setup.security.bash": "Block dangerous shell commands",
|
|
4106
|
+
"web.setup.security.bash_desc": "Blocks destructive commands (rm, sudo, ssh, curl, shutdown, …). The agent asks instead of running them.",
|
|
4053
4107
|
"web.setup.security.flags": "Block dangerous command flags",
|
|
4108
|
+
"web.setup.security.flags_desc": "Blocks risky flags (--force, -rf, …) that make safe commands dangerous. Works together with the command block.",
|
|
4109
|
+
"web.setup.security.configure": "Configure",
|
|
4110
|
+
"web.setup.security.advanced": "Advanced security settings",
|
|
4111
|
+
"web.setup.security.popup_hint": "One item per line. Empty list = disabled. Changes apply only to this install; you can edit them later in Settings → Security.",
|
|
4112
|
+
"web.setup.security.popup_done": "Done",
|
|
4113
|
+
"web.setup.security.reset": "Reset to defaults",
|
|
4114
|
+
"web.setup.security.denied": "Always denied paths",
|
|
4115
|
+
"web.setup.security.allowed": "Only allowed paths (empty = all except denied)",
|
|
4116
|
+
"web.setup.security.blacklist": "Always blocked commands",
|
|
4117
|
+
"web.setup.security.whitelist": "Only allowed commands (empty = all except blocked)",
|
|
4118
|
+
"web.setup.security.log_commands": "Log every executed command to the audit log",
|
|
4119
|
+
"web.setup.security.dangerous_flags": "Blocked command flags",
|
|
4120
|
+
"web.setup.security.dangerous_operators": "Blocked shell operators",
|
|
4121
|
+
"web.setup.security.network_enabled": "Network protection (block private/internal addresses)",
|
|
4122
|
+
"web.setup.security.denied_domains": "Always denied domains",
|
|
4123
|
+
"web.setup.security.allowed_domains": "Only allowed domains (empty = all except denied)",
|
|
4124
|
+
"web.setup.security.request_timeout": "Network request timeout (ms)",
|
|
4125
|
+
"web.setup.security.max_response_size": "Max response size (bytes)",
|
|
4126
|
+
"web.setup.security.max_recursion": "Max subagent recursion depth",
|
|
4127
|
+
"web.setup.security.max_file_ops": "Max file operations per session",
|
|
4128
|
+
"web.setup.security.rate_rpm": "Max LLM requests per minute",
|
|
4129
|
+
"web.setup.security.rate_parallel": "Max parallel tasks",
|
|
4130
|
+
"web.setup.security.content_scan": "Scan file content for dangerous patterns",
|
|
4131
|
+
"web.setup.security.session_encryption": "Encrypt session logs on disk",
|
|
4132
|
+
"web.setup.security.audit_enabled": "Send security events to the audit notifier",
|
|
4133
|
+
"web.setup.security.audit_severity": "Minimum severity to notify",
|
|
4134
|
+
"web.setup.security.audit_events": "Notified event types",
|
|
4135
|
+
"web.setup.security.audit_retries": "Webhook max retries",
|
|
4136
|
+
"web.setup.security.audit_timeout": "Webhook timeout (ms)",
|
|
4137
|
+
"web.setup.security.severity.low": "low",
|
|
4138
|
+
"web.setup.security.severity.medium": "medium",
|
|
4139
|
+
"web.setup.security.severity.high": "high",
|
|
4140
|
+
"web.setup.security.severity.critical": "critical",
|
|
4054
4141
|
"web.setup.review.title": "Review",
|
|
4055
4142
|
"web.setup.review.hint": "Check the values, then finish. Settings are saved to your config.",
|
|
4056
4143
|
"web.setup.review.provider": "Provider",
|
|
@@ -4423,6 +4510,8 @@ var init_ru = __esm(() => {
|
|
|
4423
4510
|
{issues}
|
|
4424
4511
|
Сводка: {summary}`,
|
|
4425
4512
|
"critic.advice": `Верификатор отметил проблемы, которые стоит проверить до завершения:
|
|
4513
|
+
{issues}`,
|
|
4514
|
+
"critic.repeat": `Верификатор повторяет уже отмеченную проблему — не выдавай тот же ответ снова. Смени подход или заверши честно, если жалоба неприменима:
|
|
4426
4515
|
{issues}`,
|
|
4427
4516
|
"tool.subagent_queued": "Задача подагенту добавлена: {task}",
|
|
4428
4517
|
"tool.subagent_artifact": `Суб-агент завершён. Полный результат сохранён в артефакт: {path}
|
|
@@ -5221,6 +5310,7 @@ var init_ru = __esm(() => {
|
|
|
5221
5310
|
"ui.todo_action": "{action} · {count}",
|
|
5222
5311
|
"ui.tool_running": "{tool}…",
|
|
5223
5312
|
"ui.step_context": "шаг {id}: {desc}",
|
|
5313
|
+
"ui.draft_retracted": "↳ черновик отклонён проверкой, уточняю…",
|
|
5224
5314
|
"indexer.map_header": "Карта проекта",
|
|
5225
5315
|
"indexer.top_directories": "Основные директории",
|
|
5226
5316
|
"indexer.files": "Файлы",
|
|
@@ -5398,6 +5488,46 @@ var init_ru = __esm(() => {
|
|
|
5398
5488
|
"web.sidebar.session": "сессия",
|
|
5399
5489
|
"web.sidebar.usage": "использование",
|
|
5400
5490
|
"web.sidebar.env": "окружение",
|
|
5491
|
+
"web.sidebar.tab_session": "Сессия",
|
|
5492
|
+
"web.sidebar.tab_map": "Карта",
|
|
5493
|
+
"web.sidebar.tab_trace": "Трассировка",
|
|
5494
|
+
"web.sidebar.map_status": "статус",
|
|
5495
|
+
"web.sidebar.map_ready": "готово",
|
|
5496
|
+
"web.sidebar.map_indexing": "индексация…",
|
|
5497
|
+
"web.sidebar.map_stale": "устарело",
|
|
5498
|
+
"web.sidebar.map_updated": "обновлено",
|
|
5499
|
+
"web.sidebar.map_never": "никогда",
|
|
5500
|
+
"web.sidebar.map_today": "сегодня, {time}",
|
|
5501
|
+
"web.sidebar.map_watcher": "вотчер",
|
|
5502
|
+
"web.sidebar.map_on": "вкл.",
|
|
5503
|
+
"web.sidebar.map_off": "выкл.",
|
|
5504
|
+
"web.sidebar.map_files": "файлы",
|
|
5505
|
+
"web.sidebar.map_symbols": "символы",
|
|
5506
|
+
"web.sidebar.map_tokens": "токены",
|
|
5507
|
+
"web.sidebar.map_root": "корень",
|
|
5508
|
+
"web.sidebar.map_languages": "языки",
|
|
5509
|
+
"web.sidebar.map_reindex": "Переиндексировать",
|
|
5510
|
+
"web.sidebar.map_reindexing": "переиндексация…",
|
|
5511
|
+
"web.sidebar.map_reindex_failed": "не удалось переиндексировать",
|
|
5512
|
+
"web.sidebar.trace_empty": "событий пока нет",
|
|
5513
|
+
"web.sidebar.trace_turn": "ход {n}",
|
|
5514
|
+
"web.sidebar.trace_text": "печатает… {count} симв.",
|
|
5515
|
+
"web.sidebar.trace_plan": "обновление плана",
|
|
5516
|
+
"web.sidebar.trace_question": "вопрос",
|
|
5517
|
+
"web.sidebar.detail_metadata": "метаданные",
|
|
5518
|
+
"web.sidebar.detail_arguments": "аргументы",
|
|
5519
|
+
"web.sidebar.detail_output": "вывод",
|
|
5520
|
+
"web.sidebar.detail_error": "ошибка",
|
|
5521
|
+
"web.sidebar.detail_text": "текст",
|
|
5522
|
+
"web.sidebar.detail_plan": "план",
|
|
5523
|
+
"web.sidebar.detail_reasoning": "размышление",
|
|
5524
|
+
"web.sidebar.detail_status": "статус",
|
|
5525
|
+
"web.sidebar.detail_ok": "ok",
|
|
5526
|
+
"web.sidebar.detail_fail": "ошибка",
|
|
5527
|
+
"web.sidebar.detail_duration": "длительность",
|
|
5528
|
+
"web.sidebar.detail_time": "время",
|
|
5529
|
+
"web.sidebar.detail_tool_call": "вызов тула",
|
|
5530
|
+
"web.sidebar.detail_session": "сессия",
|
|
5401
5531
|
"web.env.dir": "директория",
|
|
5402
5532
|
"web.env.agents": "AGENTS.md",
|
|
5403
5533
|
"web.env.map": "карта",
|
|
@@ -5765,6 +5895,7 @@ var init_ru = __esm(() => {
|
|
|
5765
5895
|
"web.history.loading": "загрузка…",
|
|
5766
5896
|
"web.history.unavailable": "— история недоступна",
|
|
5767
5897
|
"web.history.empty": "— пустая сессия —",
|
|
5898
|
+
"web.scroll.latest": "к новому",
|
|
5768
5899
|
"web.tool.output_one": "вывод · {count} символ",
|
|
5769
5900
|
"web.tool.output_few": "вывод · {count} символа",
|
|
5770
5901
|
"web.tool.output_many": "вывод · {count} символов",
|
|
@@ -5835,7 +5966,7 @@ var init_ru = __esm(() => {
|
|
|
5835
5966
|
"web.setup.language.title": "Выберите язык",
|
|
5836
5967
|
"web.setup.language.hint": "Используется для интерфейса.",
|
|
5837
5968
|
"web.setup.provider.title": "Выберите провайдера",
|
|
5838
|
-
"web.setup.provider.hint": "Для локальной модели выберите OpenAI-совместимый
|
|
5969
|
+
"web.setup.provider.hint": "Для локальной модели выберите OpenAI-совместимый вариант, просканируйте сервер и проверьте подключение перед продолжением.",
|
|
5839
5970
|
"web.setup.provider.base_url": "Базовый URL",
|
|
5840
5971
|
"web.setup.provider.scan": "Найти локальные серверы",
|
|
5841
5972
|
"web.setup.provider.scan_found_one": "Найден {count} сервер",
|
|
@@ -5844,6 +5975,10 @@ var init_ru = __esm(() => {
|
|
|
5844
5975
|
"web.setup.provider.scan_none": "Локальные серверы не найдены — введите URL вручную.",
|
|
5845
5976
|
"web.setup.provider.scan_failed": "Сканирование не удалось. Введите URL вручную.",
|
|
5846
5977
|
"web.setup.provider.required": "Укажите базовый URL.",
|
|
5978
|
+
"web.setup.provider.test": "Проверить подключение",
|
|
5979
|
+
"web.setup.provider.testing": "Проверка…",
|
|
5980
|
+
"web.setup.provider.test_ok": "Сервер отвечает.",
|
|
5981
|
+
"web.setup.provider.test_fail": "Не удалось связаться с сервером по этому URL.",
|
|
5847
5982
|
"web.setup.key.title": "API-ключ",
|
|
5848
5983
|
"web.setup.key.hint": "Для локальных серверов можно оставить пустым. Хранится только в файле конфигурации и больше не показывается.",
|
|
5849
5984
|
"web.setup.key.label": "Ключ",
|
|
@@ -5862,15 +5997,54 @@ var init_ru = __esm(() => {
|
|
|
5862
5997
|
"web.setup.model.test_fail": "Не удалось связаться с моделью.",
|
|
5863
5998
|
"web.setup.model.required": "Выберите или введите модель.",
|
|
5864
5999
|
"web.setup.context.title": "Контекст и итерации",
|
|
5865
|
-
"web.setup.context.hint": "
|
|
6000
|
+
"web.setup.context.hint": "Должно совпадать с контекстом, который провайдер выделяет этой модели. Нажмите «Определить» либо сверьтесь с LM Studio / Ollama / документацией провайдера.",
|
|
5866
6001
|
"web.setup.context.contextWindow": "Окно контекста (токены)",
|
|
5867
6002
|
"web.setup.context.maxToolIterations": "Максимум итераций тулов",
|
|
5868
6003
|
"web.setup.context.required": "Введите положительное число.",
|
|
6004
|
+
"web.setup.context.detect": "Определить у провайдера",
|
|
6005
|
+
"web.setup.context.detecting": "Определение…",
|
|
6006
|
+
"web.setup.context.detect_ok": "Контекст от провайдера: {count} токенов.",
|
|
6007
|
+
"web.setup.context.detect_fail": "Не удалось определить контекст — введите вручную.",
|
|
5869
6008
|
"web.setup.security.title": "Безопасность",
|
|
5870
|
-
"web.setup.security.hint": "Безопасные значения включены; отключайте только нужное.",
|
|
6009
|
+
"web.setup.security.hint": "Безопасные значения включены; отключайте только нужное. Ничего не блокируется молча — каждый переключатель лишь требует подтверждения перед опасным действием.",
|
|
5871
6010
|
"web.setup.security.paths": "Ограничить доступ к файлам рабочей папкой",
|
|
6011
|
+
"web.setup.security.paths_desc": "Агент читает и пишет только внутри рабочей папки, а перед доступом к .git, .env, ключам и другим чувствительным путям спросит подтверждения.",
|
|
5872
6012
|
"web.setup.security.bash": "Блокировать опасные shell-команды",
|
|
6013
|
+
"web.setup.security.bash_desc": "Блокирует разрушительные команды (rm, sudo, ssh, curl, shutdown, …). Вместо запуска агент спросит подтверждения.",
|
|
5873
6014
|
"web.setup.security.flags": "Блокировать опасные флаги команд",
|
|
6015
|
+
"web.setup.security.flags_desc": "Блокирует рискованные флаги (--force, -rf, …), которые делают безопасные команды опасными. Работает вместе с блокировкой команд.",
|
|
6016
|
+
"web.setup.security.configure": "Настроить",
|
|
6017
|
+
"web.setup.security.advanced": "Расширенные настройки безопасности",
|
|
6018
|
+
"web.setup.security.popup_hint": "По одному элементу в строке. Пустой список = выключено. Изменения применяются только к этой установке; позже их можно править в Настройках → Безопасность.",
|
|
6019
|
+
"web.setup.security.popup_done": "Готово",
|
|
6020
|
+
"web.setup.security.reset": "Сбросить к значениям по умолчанию",
|
|
6021
|
+
"web.setup.security.denied": "Всегда запрещённые пути",
|
|
6022
|
+
"web.setup.security.allowed": "Разрешены только эти пути (пусто = все, кроме запрещённых)",
|
|
6023
|
+
"web.setup.security.blacklist": "Всегда блокируемые команды",
|
|
6024
|
+
"web.setup.security.whitelist": "Разрешены только эти команды (пусто = все, кроме блокируемых)",
|
|
6025
|
+
"web.setup.security.log_commands": "Писать каждую выполненную команду в аудит-лог",
|
|
6026
|
+
"web.setup.security.dangerous_flags": "Блокируемые флаги команд",
|
|
6027
|
+
"web.setup.security.dangerous_operators": "Блокируемые shell-операторы",
|
|
6028
|
+
"web.setup.security.network_enabled": "Сетевая защита (блокировать приватные/внутренние адреса)",
|
|
6029
|
+
"web.setup.security.denied_domains": "Всегда запрещённые домены",
|
|
6030
|
+
"web.setup.security.allowed_domains": "Разрешены только эти домены (пусто = все, кроме запрещённых)",
|
|
6031
|
+
"web.setup.security.request_timeout": "Таймаут сетевых запросов (мс)",
|
|
6032
|
+
"web.setup.security.max_response_size": "Максимум размера ответа (байты)",
|
|
6033
|
+
"web.setup.security.max_recursion": "Максимум глубины рекурсии субагентов",
|
|
6034
|
+
"web.setup.security.max_file_ops": "Максимум файловых операций за сессию",
|
|
6035
|
+
"web.setup.security.rate_rpm": "Максимум LLM-запросов в минуту",
|
|
6036
|
+
"web.setup.security.rate_parallel": "Максимум параллельных задач",
|
|
6037
|
+
"web.setup.security.content_scan": "Сканировать содержимое файлов на опасные паттерны",
|
|
6038
|
+
"web.setup.security.session_encryption": "Шифровать логи сессий на диске",
|
|
6039
|
+
"web.setup.security.audit_enabled": "Отправлять события безопасности в аудит-нотификатор",
|
|
6040
|
+
"web.setup.security.audit_severity": "Минимальная severity для уведомления",
|
|
6041
|
+
"web.setup.security.audit_events": "Типы событий для уведомления",
|
|
6042
|
+
"web.setup.security.audit_retries": "Повторы вебхука",
|
|
6043
|
+
"web.setup.security.audit_timeout": "Таймаут вебхука (мс)",
|
|
6044
|
+
"web.setup.security.severity.low": "низкая",
|
|
6045
|
+
"web.setup.security.severity.medium": "средняя",
|
|
6046
|
+
"web.setup.security.severity.high": "высокая",
|
|
6047
|
+
"web.setup.security.severity.critical": "критическая",
|
|
5874
6048
|
"web.setup.review.title": "Проверка",
|
|
5875
6049
|
"web.setup.review.hint": "Проверьте значения и завершите. Настройки сохранятся в конфиг.",
|
|
5876
6050
|
"web.setup.review.provider": "Провайдер",
|
|
@@ -9386,6 +9560,13 @@ function defaultUserAgent() {
|
|
|
9386
9560
|
cachedUserAgent = `micro-models-agent/${readMmaVersion()}`;
|
|
9387
9561
|
return cachedUserAgent;
|
|
9388
9562
|
}
|
|
9563
|
+
function normalizeReasoningEffort(level) {
|
|
9564
|
+
if (!level || level === "default" || level === "none")
|
|
9565
|
+
return;
|
|
9566
|
+
if (level === "max")
|
|
9567
|
+
return "high";
|
|
9568
|
+
return level;
|
|
9569
|
+
}
|
|
9389
9570
|
function buildRequestBody(opts) {
|
|
9390
9571
|
const body = {
|
|
9391
9572
|
model: opts.model,
|
|
@@ -9403,13 +9584,15 @@ function buildRequestBody(opts) {
|
|
|
9403
9584
|
if (opts.stream && opts.streamUsage)
|
|
9404
9585
|
body.stream_options = { include_usage: true };
|
|
9405
9586
|
const strategy = opts.reasoningStrategy ?? "openai-effort";
|
|
9406
|
-
const
|
|
9407
|
-
if (strategy === "openai-effort"
|
|
9408
|
-
|
|
9587
|
+
const effort = normalizeReasoningEffort(opts.reasoningEffort);
|
|
9588
|
+
if (strategy === "openai-effort") {
|
|
9589
|
+
if (effort)
|
|
9590
|
+
body.reasoning_effort = effort;
|
|
9409
9591
|
} else if (strategy === "template-kwarg") {
|
|
9410
|
-
body.chat_template_kwargs = { enable_thinking:
|
|
9411
|
-
} else if (strategy === "prompt-tag"
|
|
9412
|
-
|
|
9592
|
+
body.chat_template_kwargs = { enable_thinking: opts.reasoningEffort !== "none" };
|
|
9593
|
+
} else if (strategy === "prompt-tag") {
|
|
9594
|
+
if (effort)
|
|
9595
|
+
body.reasoning_effort = effort;
|
|
9413
9596
|
}
|
|
9414
9597
|
if (opts.tools && opts.tools.length > 0) {
|
|
9415
9598
|
body.tools = opts.tools.map((t2) => ({
|
|
@@ -9456,6 +9639,9 @@ class OpenAICompatProvider {
|
|
|
9456
9639
|
this.userAgent = config.userAgent ?? defaultUserAgent();
|
|
9457
9640
|
this.debug = config.logger ? config.logger.debug.bind(config.logger) : null;
|
|
9458
9641
|
}
|
|
9642
|
+
get idleTimeoutMs() {
|
|
9643
|
+
return this.retryConfig.noDataTimeoutMs ?? 180000;
|
|
9644
|
+
}
|
|
9459
9645
|
async* chat(messages, tools, signal, options) {
|
|
9460
9646
|
if (!this.rateLimiter.canMakeRequest()) {
|
|
9461
9647
|
const waitMs = Math.min(this.rateLimiter.msUntilRequest(), LLM_MAX_RATE_WAIT_MS);
|
|
@@ -9486,7 +9672,7 @@ class OpenAICompatProvider {
|
|
|
9486
9672
|
}
|
|
9487
9673
|
if (!hasToolCall && !hasText) {
|
|
9488
9674
|
this.debug?.("LLM streaming produced no text/tool_call — falling back to non-streaming");
|
|
9489
|
-
const fallback = await this.doNonStreaming(effectiveMessages, tools, signal, options);
|
|
9675
|
+
const fallback = await this.doNonStreaming(effectiveMessages, tools, signal, options, this.idleTimeoutMs);
|
|
9490
9676
|
this.debug?.("LLM non-streaming fallback result", { chunks: fallback.length });
|
|
9491
9677
|
for (const chunk of fallback) {
|
|
9492
9678
|
if (hasReasoning && chunk.type === "reasoning")
|
|
@@ -9513,9 +9699,9 @@ ${tag}`;
|
|
|
9513
9699
|
return copy;
|
|
9514
9700
|
}
|
|
9515
9701
|
async* doStream(messages, tools, signal, options) {
|
|
9516
|
-
const { baseDelay, maxDelay, maxStreamRetries
|
|
9702
|
+
const { baseDelay, maxDelay, maxStreamRetries } = this.retryConfig;
|
|
9517
9703
|
const streamRetries = maxStreamRetries ?? 2;
|
|
9518
|
-
const idleTimeoutMs =
|
|
9704
|
+
const idleTimeoutMs = this.idleTimeoutMs;
|
|
9519
9705
|
let usedNonStreamingFallback = false;
|
|
9520
9706
|
for (let attempt = 0;; attempt++) {
|
|
9521
9707
|
let emitted = false;
|
|
@@ -9534,7 +9720,7 @@ ${tag}`;
|
|
|
9534
9720
|
if (err?.stalledAfterToolCall === true && !usedNonStreamingFallback) {
|
|
9535
9721
|
usedNonStreamingFallback = true;
|
|
9536
9722
|
this.debug?.("LLM stream stalled after tool_call — falling back to non-streaming request");
|
|
9537
|
-
const fallback = await this.doNonStreaming(messages, tools, signal, options);
|
|
9723
|
+
const fallback = await this.doNonStreaming(messages, tools, signal, options, idleTimeoutMs);
|
|
9538
9724
|
this.debug?.("LLM non-streaming fallback result", { chunks: fallback.length });
|
|
9539
9725
|
for (const chunk of fallback) {
|
|
9540
9726
|
if (chunk.type === "reasoning")
|
|
@@ -9581,8 +9767,12 @@ ${tag}`;
|
|
|
9581
9767
|
signal: abortSignal
|
|
9582
9768
|
});
|
|
9583
9769
|
} catch (err) {
|
|
9584
|
-
if (err?.name === "AbortError")
|
|
9770
|
+
if (err?.name === "AbortError") {
|
|
9771
|
+
if (isTimeout()) {
|
|
9772
|
+
throw new Error(t("error.llm_timeout", { timeout: LLM_REQUEST_TIMEOUT_MS }));
|
|
9773
|
+
}
|
|
9585
9774
|
throw err;
|
|
9775
|
+
}
|
|
9586
9776
|
const wrapped = err instanceof Error ? err : new Error(String(err));
|
|
9587
9777
|
if (wrapped instanceof LlmError) {
|
|
9588
9778
|
wrapped.markTerminal();
|
|
@@ -9609,6 +9799,7 @@ ${tag}`;
|
|
|
9609
9799
|
cleanup();
|
|
9610
9800
|
throw new Error(t("error.no_response_body"));
|
|
9611
9801
|
}
|
|
9802
|
+
cleanup();
|
|
9612
9803
|
const decoder = new TextDecoder;
|
|
9613
9804
|
let buffer = "";
|
|
9614
9805
|
const toolCallAccs = new Map;
|
|
@@ -9774,7 +9965,7 @@ ${tag}`;
|
|
|
9774
9965
|
streamUsage: this.cache?.requestStreamUsage === true
|
|
9775
9966
|
};
|
|
9776
9967
|
}
|
|
9777
|
-
buildRequestSetup(signal) {
|
|
9968
|
+
buildRequestSetup(signal, totalTimeoutMs = LLM_REQUEST_TIMEOUT_MS) {
|
|
9778
9969
|
const headers = {
|
|
9779
9970
|
"Content-Type": "application/json",
|
|
9780
9971
|
"User-Agent": this.userAgent
|
|
@@ -9791,7 +9982,7 @@ ${tag}`;
|
|
|
9791
9982
|
const timeoutId = setTimeout(() => {
|
|
9792
9983
|
timedOut = true;
|
|
9793
9984
|
controller.abort();
|
|
9794
|
-
},
|
|
9985
|
+
}, totalTimeoutMs);
|
|
9795
9986
|
const abortSignal = (() => {
|
|
9796
9987
|
if (!signal)
|
|
9797
9988
|
return controller.signal;
|
|
@@ -9815,7 +10006,7 @@ ${tag}`;
|
|
|
9815
10006
|
controller
|
|
9816
10007
|
};
|
|
9817
10008
|
}
|
|
9818
|
-
async doNonStreaming(messages, tools, signal, options) {
|
|
10009
|
+
async doNonStreaming(messages, tools, signal, options, totalTimeoutMs = LLM_REQUEST_TIMEOUT_MS) {
|
|
9819
10010
|
const maxTokens = options?.maxTokens ?? this.config.maxCompletionTokens ?? DEFAULT_MAX_COMPLETION_TOKENS;
|
|
9820
10011
|
const body = buildRequestBody({
|
|
9821
10012
|
model: this.model,
|
|
@@ -9827,7 +10018,7 @@ ${tag}`;
|
|
|
9827
10018
|
reasoningStrategy: options?.reasoningStrategy,
|
|
9828
10019
|
...this.cacheHints()
|
|
9829
10020
|
});
|
|
9830
|
-
const { headers, abortSignal, cleanup, isTimeout } = this.buildRequestSetup(signal);
|
|
10021
|
+
const { headers, abortSignal, cleanup, isTimeout } = this.buildRequestSetup(signal, totalTimeoutMs);
|
|
9831
10022
|
try {
|
|
9832
10023
|
const response = await this.fetchWithRetry(`${this.config.baseUrl}/chat/completions`, {
|
|
9833
10024
|
method: "POST",
|
|
@@ -9892,7 +10083,7 @@ ${tag}`;
|
|
|
9892
10083
|
return chunks;
|
|
9893
10084
|
} catch (err) {
|
|
9894
10085
|
if (isTimeout() && err?.name === "AbortError") {
|
|
9895
|
-
throw new Error(t("error.llm_timeout", { timeout:
|
|
10086
|
+
throw new Error(t("error.llm_timeout", { timeout: totalTimeoutMs }));
|
|
9896
10087
|
}
|
|
9897
10088
|
throw err instanceof Error ? err : new Error(String(err));
|
|
9898
10089
|
} finally {
|
|
@@ -10281,6 +10472,14 @@ var init_cache = __esm(() => {
|
|
|
10281
10472
|
});
|
|
10282
10473
|
|
|
10283
10474
|
// src/modules/providers/manager.ts
|
|
10475
|
+
var exports_manager = {};
|
|
10476
|
+
__export(exports_manager, {
|
|
10477
|
+
reasoningStrategyForProvider: () => reasoningStrategyForProvider,
|
|
10478
|
+
presetOf: () => presetOf,
|
|
10479
|
+
activeProviderEndpoint: () => activeProviderEndpoint,
|
|
10480
|
+
ProviderManager: () => ProviderManager
|
|
10481
|
+
});
|
|
10482
|
+
|
|
10284
10483
|
class ProviderManager {
|
|
10285
10484
|
entries;
|
|
10286
10485
|
lastKnownFallback;
|
|
@@ -10420,6 +10619,12 @@ class ProviderManager {
|
|
|
10420
10619
|
this.cache.clear();
|
|
10421
10620
|
}
|
|
10422
10621
|
}
|
|
10622
|
+
function presetOf(type) {
|
|
10623
|
+
const spec = BUILTIN_PROVIDERS.find((p) => p.type === type);
|
|
10624
|
+
if (!spec)
|
|
10625
|
+
return;
|
|
10626
|
+
return { label: spec.label, baseUrl: spec.baseUrl };
|
|
10627
|
+
}
|
|
10423
10628
|
function activeProviderEndpoint(config) {
|
|
10424
10629
|
const entries = Array.isArray(config?.entries) ? config.entries : [];
|
|
10425
10630
|
const active = entries.find((e) => e.label === config?.active || e.type === config?.active) ?? entries[0];
|
|
@@ -10428,6 +10633,10 @@ function activeProviderEndpoint(config) {
|
|
|
10428
10633
|
}
|
|
10429
10634
|
return { baseUrl: config?.baseUrl ?? "", apiKey: config?.apiKey, type: config?.type ?? "openai-compat" };
|
|
10430
10635
|
}
|
|
10636
|
+
function reasoningStrategyForProvider(config) {
|
|
10637
|
+
const type = activeProviderEndpoint(config).type;
|
|
10638
|
+
return BUILTIN_PROVIDERS.find((p) => p.type === type)?.capabilities.reasoningStrategy ?? "none";
|
|
10639
|
+
}
|
|
10431
10640
|
var init_manager = __esm(() => {
|
|
10432
10641
|
init_create();
|
|
10433
10642
|
init_cache();
|
|
@@ -10629,6 +10838,8 @@ function cachePath2() {
|
|
|
10629
10838
|
async function probeReasoningSupport(provider, strategy, signal) {
|
|
10630
10839
|
if (strategy === "none")
|
|
10631
10840
|
return false;
|
|
10841
|
+
if (strategy === "openai-effort")
|
|
10842
|
+
return true;
|
|
10632
10843
|
try {
|
|
10633
10844
|
let hasReasoning = false;
|
|
10634
10845
|
for await (const chunk of provider.chat(PROBE_MESSAGES, undefined, signal, {
|
|
@@ -10775,8 +10986,7 @@ async function setupProviderPhase(config, logger, dir) {
|
|
|
10775
10986
|
const builtProvider = buildActiveProvider(config, logger, { getSessionId });
|
|
10776
10987
|
const providerManager = builtProvider.manager;
|
|
10777
10988
|
const llmProvider = builtProvider.provider;
|
|
10778
|
-
const
|
|
10779
|
-
const reasoningStrategy = providerSpec?.capabilities.reasoningStrategy ?? "none";
|
|
10989
|
+
const reasoningStrategy = reasoningStrategyForProvider(config.provider);
|
|
10780
10990
|
let reasoningProbePromise = Promise.resolve(false);
|
|
10781
10991
|
if (config.reasoning && config.reasoning.mode !== "none" && reasoningStrategy !== "none") {
|
|
10782
10992
|
reasoningProbePromise = (async () => {
|
|
@@ -10816,7 +11026,6 @@ var init_provider_phase = __esm(() => {
|
|
|
10816
11026
|
init_model_loader();
|
|
10817
11027
|
init_factory();
|
|
10818
11028
|
init_manager();
|
|
10819
|
-
init_presets();
|
|
10820
11029
|
init_profile();
|
|
10821
11030
|
init_i18n();
|
|
10822
11031
|
});
|
|
@@ -11703,6 +11912,7 @@ import { join as join20 } from "path";
|
|
|
11703
11912
|
class IndexCache {
|
|
11704
11913
|
cachePath;
|
|
11705
11914
|
cache = null;
|
|
11915
|
+
cachedBuiltAt = null;
|
|
11706
11916
|
root;
|
|
11707
11917
|
signature;
|
|
11708
11918
|
constructor(cacheDir, opts = {}) {
|
|
@@ -11724,17 +11934,21 @@ class IndexCache {
|
|
|
11724
11934
|
if (this.signature && parsed.signature !== this.currentSignature())
|
|
11725
11935
|
return null;
|
|
11726
11936
|
this.cache = parsed.result;
|
|
11937
|
+
this.cachedBuiltAt = typeof parsed.builtAt === "number" ? parsed.builtAt : null;
|
|
11727
11938
|
return this.cache;
|
|
11728
11939
|
} catch {
|
|
11729
11940
|
return null;
|
|
11730
11941
|
}
|
|
11731
11942
|
}
|
|
11732
11943
|
save(result) {
|
|
11944
|
+
const now = Date.now();
|
|
11733
11945
|
this.cache = result;
|
|
11946
|
+
this.cachedBuiltAt = now;
|
|
11734
11947
|
const envelope = {
|
|
11735
11948
|
version: CACHE_VERSION,
|
|
11736
11949
|
root: this.root ?? "",
|
|
11737
11950
|
signature: this.currentSignature(),
|
|
11951
|
+
builtAt: now,
|
|
11738
11952
|
result
|
|
11739
11953
|
};
|
|
11740
11954
|
const dir = join20(this.cachePath, "..");
|
|
@@ -11744,12 +11958,16 @@ class IndexCache {
|
|
|
11744
11958
|
}
|
|
11745
11959
|
invalidate() {
|
|
11746
11960
|
this.cache = null;
|
|
11961
|
+
this.cachedBuiltAt = null;
|
|
11747
11962
|
if (existsSync18(this.cachePath)) {
|
|
11748
11963
|
try {
|
|
11749
11964
|
rmSync(this.cachePath);
|
|
11750
11965
|
} catch {}
|
|
11751
11966
|
}
|
|
11752
11967
|
}
|
|
11968
|
+
getBuiltAt() {
|
|
11969
|
+
return this.cachedBuiltAt;
|
|
11970
|
+
}
|
|
11753
11971
|
currentSignature() {
|
|
11754
11972
|
if (!this.signature)
|
|
11755
11973
|
return "";
|
|
@@ -12077,7 +12295,11 @@ class IndexerModule {
|
|
|
12077
12295
|
cache;
|
|
12078
12296
|
baseDir;
|
|
12079
12297
|
index = null;
|
|
12080
|
-
|
|
12298
|
+
mapCache = null;
|
|
12299
|
+
buildPromise = null;
|
|
12300
|
+
indexing = false;
|
|
12301
|
+
builtAt = null;
|
|
12302
|
+
watcherActive = false;
|
|
12081
12303
|
rebuildTimeout = null;
|
|
12082
12304
|
constructor(opts) {
|
|
12083
12305
|
this.baseDir = opts.baseDir;
|
|
@@ -12087,26 +12309,38 @@ class IndexerModule {
|
|
|
12087
12309
|
signature: () => this.indexer.scanSignature()
|
|
12088
12310
|
});
|
|
12089
12311
|
}
|
|
12090
|
-
|
|
12312
|
+
buildIndex() {
|
|
12091
12313
|
if (this.index)
|
|
12092
|
-
return this.index;
|
|
12314
|
+
return Promise.resolve(this.index);
|
|
12315
|
+
if (this.buildPromise)
|
|
12316
|
+
return this.buildPromise;
|
|
12093
12317
|
const cached = this.cache.load();
|
|
12094
12318
|
if (cached) {
|
|
12095
12319
|
this.index = cached;
|
|
12096
|
-
|
|
12097
|
-
|
|
12098
|
-
try {
|
|
12099
|
-
const result = await this.indexer.walk();
|
|
12100
|
-
this.cache.save(result);
|
|
12101
|
-
this.index = result;
|
|
12102
|
-
return result;
|
|
12103
|
-
} catch {
|
|
12104
|
-
return null;
|
|
12320
|
+
this.builtAt = this.cache.getBuiltAt();
|
|
12321
|
+
return Promise.resolve(cached);
|
|
12105
12322
|
}
|
|
12323
|
+
this.indexing = true;
|
|
12324
|
+
this.buildPromise = (async () => {
|
|
12325
|
+
try {
|
|
12326
|
+
const result = await this.indexer.walk();
|
|
12327
|
+
this.cache.save(result);
|
|
12328
|
+
this.index = result;
|
|
12329
|
+
this.builtAt = Date.now();
|
|
12330
|
+
return result;
|
|
12331
|
+
} catch {
|
|
12332
|
+
return null;
|
|
12333
|
+
} finally {
|
|
12334
|
+
this.indexing = false;
|
|
12335
|
+
this.buildPromise = null;
|
|
12336
|
+
}
|
|
12337
|
+
})();
|
|
12338
|
+
return this.buildPromise;
|
|
12106
12339
|
}
|
|
12107
12340
|
async refresh() {
|
|
12108
12341
|
this.cache.invalidate();
|
|
12109
12342
|
this.index = null;
|
|
12343
|
+
this.builtAt = null;
|
|
12110
12344
|
return this.buildIndex();
|
|
12111
12345
|
}
|
|
12112
12346
|
find(query) {
|
|
@@ -12146,9 +12380,11 @@ class IndexerModule {
|
|
|
12146
12380
|
this.refresh().catch(() => {});
|
|
12147
12381
|
}, 2000);
|
|
12148
12382
|
});
|
|
12383
|
+
this.watcherActive = true;
|
|
12149
12384
|
} catch {}
|
|
12150
12385
|
}
|
|
12151
12386
|
unwatch() {
|
|
12387
|
+
this.watcherActive = false;
|
|
12152
12388
|
if (this.rebuildTimeout) {
|
|
12153
12389
|
clearTimeout(this.rebuildTimeout);
|
|
12154
12390
|
this.rebuildTimeout = null;
|
|
@@ -12167,19 +12403,47 @@ class IndexerModule {
|
|
|
12167
12403
|
kind: "project-map"
|
|
12168
12404
|
};
|
|
12169
12405
|
}
|
|
12170
|
-
|
|
12171
|
-
if (!this.index)
|
|
12172
|
-
return
|
|
12173
|
-
|
|
12174
|
-
|
|
12406
|
+
mapInfo() {
|
|
12407
|
+
if (!this.index) {
|
|
12408
|
+
return {
|
|
12409
|
+
indexed: false,
|
|
12410
|
+
indexing: this.indexing,
|
|
12411
|
+
files: 0,
|
|
12412
|
+
symbols: 0,
|
|
12413
|
+
tokens: 0,
|
|
12414
|
+
updatedAt: this.builtAt,
|
|
12415
|
+
languages: [],
|
|
12416
|
+
watcher: this.watcherActive
|
|
12417
|
+
};
|
|
12418
|
+
}
|
|
12419
|
+
if (this.mapCache && this.mapCache.index === this.index) {
|
|
12420
|
+
return { ...this.mapCache.value, indexing: this.indexing, watcher: this.watcherActive };
|
|
12421
|
+
}
|
|
12175
12422
|
const symbols = this.index.files.reduce((n, f) => n + f.exports.length, 0);
|
|
12423
|
+
const langMap = new Map;
|
|
12424
|
+
for (const f of this.index.files) {
|
|
12425
|
+
const lang = f.language;
|
|
12426
|
+
const cur = langMap.get(lang) ?? { files: 0, symbols: 0 };
|
|
12427
|
+
cur.files += 1;
|
|
12428
|
+
cur.symbols += f.exports.length;
|
|
12429
|
+
langMap.set(lang, cur);
|
|
12430
|
+
}
|
|
12431
|
+
const languages = [...langMap.entries()].map(([language, v]) => ({ language, ...v })).sort((a, b) => b.files - a.files || a.language.localeCompare(b.language)).slice(0, 8);
|
|
12176
12432
|
const value = {
|
|
12433
|
+
indexed: true,
|
|
12177
12434
|
files: this.index.files.length,
|
|
12178
12435
|
symbols,
|
|
12179
|
-
tokens: this.estimateTokens(this.formatMap(this.index))
|
|
12436
|
+
tokens: this.estimateTokens(this.formatMap(this.index)),
|
|
12437
|
+
updatedAt: this.builtAt,
|
|
12438
|
+
languages,
|
|
12439
|
+
watcher: this.watcherActive
|
|
12180
12440
|
};
|
|
12181
|
-
this.
|
|
12182
|
-
return value;
|
|
12441
|
+
this.mapCache = { index: this.index, value };
|
|
12442
|
+
return { ...value, indexing: this.indexing };
|
|
12443
|
+
}
|
|
12444
|
+
stats() {
|
|
12445
|
+
const info = this.mapInfo();
|
|
12446
|
+
return info.indexed ? { files: info.files, symbols: info.symbols, tokens: info.tokens } : null;
|
|
12183
12447
|
}
|
|
12184
12448
|
getToolDefinitions() {
|
|
12185
12449
|
return [this.createProjectMapTool()];
|
|
@@ -16801,6 +17065,15 @@ class SessionLogger {
|
|
|
16801
17065
|
...data
|
|
16802
17066
|
});
|
|
16803
17067
|
}
|
|
17068
|
+
logClaimRetry(data) {
|
|
17069
|
+
this.session?.appendLog({
|
|
17070
|
+
ts: new Date().toISOString(),
|
|
17071
|
+
type: "claim_retry",
|
|
17072
|
+
content: data.reason,
|
|
17073
|
+
kind: data.kind,
|
|
17074
|
+
iteration: data.iteration
|
|
17075
|
+
});
|
|
17076
|
+
}
|
|
16804
17077
|
logCritic(event, data = {}) {
|
|
16805
17078
|
this.session?.appendLog({
|
|
16806
17079
|
ts: new Date().toISOString(),
|
|
@@ -19391,8 +19664,17 @@ function isFilePathLike(s) {
|
|
|
19391
19664
|
return true;
|
|
19392
19665
|
}
|
|
19393
19666
|
function extractFileLikeTokens(text) {
|
|
19394
|
-
const
|
|
19395
|
-
|
|
19667
|
+
const out = new Set;
|
|
19668
|
+
const re = new RegExp(FILE_TOKEN_RE.source, "gi");
|
|
19669
|
+
for (const m of text.matchAll(re)) {
|
|
19670
|
+
const token = m[0];
|
|
19671
|
+
const after = text[(m.index ?? 0) + token.length];
|
|
19672
|
+
if (after === "(")
|
|
19673
|
+
continue;
|
|
19674
|
+
if (isFilePathLike(token))
|
|
19675
|
+
out.add(token);
|
|
19676
|
+
}
|
|
19677
|
+
return [...out];
|
|
19396
19678
|
}
|
|
19397
19679
|
function stripUrls(text) {
|
|
19398
19680
|
return text.replace(/\bhttps?:\/\/[^\s"'<>]+/gi, " ");
|
|
@@ -20720,6 +21002,7 @@ function createLoopState() {
|
|
|
20720
21002
|
criticCalls: 0,
|
|
20721
21003
|
criticRepairCycles: 0,
|
|
20722
21004
|
mutationsSinceCritic: 0,
|
|
21005
|
+
criticHistoryMark: 0,
|
|
20723
21006
|
seenCriticIssues: new Set,
|
|
20724
21007
|
emptyResponseRetries: 0,
|
|
20725
21008
|
emptyResponseExhausted: false,
|
|
@@ -20991,6 +21274,55 @@ class ReasoningEffortResolver {
|
|
|
20991
21274
|
}
|
|
20992
21275
|
var init_reasoning_resolver = () => {};
|
|
20993
21276
|
|
|
21277
|
+
// src/core/agent/tool-pairing.ts
|
|
21278
|
+
function repairToolCallPairing(messages) {
|
|
21279
|
+
const out = [];
|
|
21280
|
+
let pending = [];
|
|
21281
|
+
const closePending = () => {
|
|
21282
|
+
for (const call of pending) {
|
|
21283
|
+
out.push({
|
|
21284
|
+
role: "tool",
|
|
21285
|
+
name: call.name,
|
|
21286
|
+
content: UNRESOLVED_TOOL_RESULT,
|
|
21287
|
+
tool_call_id: call.id,
|
|
21288
|
+
success: false,
|
|
21289
|
+
blocked: true
|
|
21290
|
+
});
|
|
21291
|
+
}
|
|
21292
|
+
pending = [];
|
|
21293
|
+
};
|
|
21294
|
+
for (const msg of messages) {
|
|
21295
|
+
if (msg.role === "assistant" && msg.tool_calls?.length) {
|
|
21296
|
+
const last = out[out.length - 1];
|
|
21297
|
+
if (last?.role === "assistant" && last.tool_calls?.length) {
|
|
21298
|
+
const merged = {
|
|
21299
|
+
...last,
|
|
21300
|
+
tool_calls: [...last.tool_calls, ...msg.tool_calls]
|
|
21301
|
+
};
|
|
21302
|
+
out[out.length - 1] = merged;
|
|
21303
|
+
pending = merged.tool_calls.map((tc) => ({ id: tc.id, name: tc.function.name }));
|
|
21304
|
+
continue;
|
|
21305
|
+
}
|
|
21306
|
+
closePending();
|
|
21307
|
+
out.push(msg);
|
|
21308
|
+
pending = msg.tool_calls.map((tc) => ({ id: tc.id, name: tc.function.name }));
|
|
21309
|
+
continue;
|
|
21310
|
+
}
|
|
21311
|
+
if (msg.role === "tool" && msg.tool_call_id) {
|
|
21312
|
+
if (pending.some((c) => c.id === msg.tool_call_id)) {
|
|
21313
|
+
out.push(msg);
|
|
21314
|
+
pending = pending.filter((c) => c.id !== msg.tool_call_id);
|
|
21315
|
+
}
|
|
21316
|
+
continue;
|
|
21317
|
+
}
|
|
21318
|
+
closePending();
|
|
21319
|
+
out.push(msg);
|
|
21320
|
+
}
|
|
21321
|
+
closePending();
|
|
21322
|
+
return out;
|
|
21323
|
+
}
|
|
21324
|
+
var UNRESOLVED_TOOL_RESULT = "[Result unavailable]";
|
|
21325
|
+
|
|
20994
21326
|
// src/core/agent/context-renderer.ts
|
|
20995
21327
|
class ContextRenderer {
|
|
20996
21328
|
lastCompactionShown = 0;
|
|
@@ -21481,6 +21813,7 @@ class HallucinationGate {
|
|
|
21481
21813
|
return { action: "warn" };
|
|
21482
21814
|
}
|
|
21483
21815
|
if (result.status === "retry") {
|
|
21816
|
+
this.retractDraft(deps, result.kind ?? "retry", result.reason ?? "");
|
|
21484
21817
|
return this.applyRetry(deps, textContent, result);
|
|
21485
21818
|
}
|
|
21486
21819
|
const claimRetry = this.checkSuccessClaim(deps, textContent);
|
|
@@ -21529,30 +21862,35 @@ class HallucinationGate {
|
|
|
21529
21862
|
return this.retryClaim(deps, textContent, t("hall.claim_contradiction", {
|
|
21530
21863
|
tool: contradiction.tool,
|
|
21531
21864
|
snippet: contradiction.snippet
|
|
21532
|
-
}), `Success-claim contradiction: ${contradiction.tool}: ${contradiction.snippet}
|
|
21865
|
+
}), `Success-claim contradiction: ${contradiction.tool}: ${contradiction.snippet}`, "success");
|
|
21533
21866
|
}
|
|
21534
21867
|
}
|
|
21535
21868
|
if (state.artifactClaimRetries < MAX_CLAIM_CHECK_RETRIES && deps.artifacts && deps.artifacts.length > 0) {
|
|
21536
21869
|
const artifact = checkArtifactClaims(text, deps.artifacts);
|
|
21537
21870
|
if (artifact) {
|
|
21538
21871
|
state.artifactClaimRetries++;
|
|
21539
|
-
return this.retryClaim(deps, textContent, t("hall.claim_artifact", { path: artifact.path, detail: artifact.snippet }), `Artifact-claim contradiction: ${artifact.snippet}
|
|
21872
|
+
return this.retryClaim(deps, textContent, t("hall.claim_artifact", { path: artifact.path, detail: artifact.snippet }), `Artifact-claim contradiction: ${artifact.snippet}`, "artifact");
|
|
21540
21873
|
}
|
|
21541
21874
|
}
|
|
21542
21875
|
if (state.outputClaimRetries < MAX_CLAIM_CHECK_RETRIES) {
|
|
21543
21876
|
const unverified = checkUnverifiedOutput(text, evidence);
|
|
21544
21877
|
if (unverified) {
|
|
21545
21878
|
state.outputClaimRetries++;
|
|
21546
|
-
return this.retryClaim(deps, textContent, t("hall.claim_output_unverified", { detail: unverified.snippet }), `Unverified output: ${unverified.snippet}
|
|
21879
|
+
return this.retryClaim(deps, textContent, t("hall.claim_output_unverified", { detail: unverified.snippet }), `Unverified output: ${unverified.snippet}`, "output");
|
|
21547
21880
|
}
|
|
21548
21881
|
}
|
|
21549
21882
|
return null;
|
|
21550
21883
|
}
|
|
21551
|
-
|
|
21884
|
+
retractDraft(deps, kind, reason) {
|
|
21885
|
+
deps.onMeta?.(t("ui.draft_retracted"), "retract");
|
|
21886
|
+
deps.slog?.logClaimRetry({ kind, reason, iteration: deps.state.iteration });
|
|
21887
|
+
}
|
|
21888
|
+
retryClaim(deps, textContent, reason, logLine, kind) {
|
|
21552
21889
|
const { state, logger: logger3 } = deps;
|
|
21553
21890
|
state.iterHallucinationRetry = true;
|
|
21554
21891
|
state.suppressRepetitionRetry = true;
|
|
21555
21892
|
logger3.diagnostic("warn", logLine);
|
|
21893
|
+
this.retractDraft(deps, kind, reason);
|
|
21556
21894
|
if (textContent) {
|
|
21557
21895
|
deps.contextManager.addMessage({ role: "assistant", content: textContent });
|
|
21558
21896
|
}
|
|
@@ -21611,27 +21949,30 @@ function resolveArtifactStates(baseDir, response) {
|
|
|
21611
21949
|
const rel = relative6(baseDir, abs);
|
|
21612
21950
|
if (rel.startsWith("..") || isAbsolute4(rel))
|
|
21613
21951
|
continue;
|
|
21614
|
-
const state = resolveOneArtifact(token,
|
|
21952
|
+
const state = resolveOneArtifact(token, baseDir);
|
|
21615
21953
|
if (state)
|
|
21616
21954
|
out.push(state);
|
|
21617
21955
|
}
|
|
21618
21956
|
return out;
|
|
21619
21957
|
}
|
|
21620
|
-
function resolveOneArtifact(token,
|
|
21958
|
+
function resolveOneArtifact(token, baseDir) {
|
|
21959
|
+
const found = findExistingFile(baseDir, token);
|
|
21960
|
+
if (!found)
|
|
21961
|
+
return { path: token, exists: false };
|
|
21621
21962
|
let size;
|
|
21622
21963
|
try {
|
|
21623
|
-
const st = statSync8(
|
|
21964
|
+
const st = statSync8(found);
|
|
21624
21965
|
if (!st.isFile())
|
|
21625
21966
|
return { path: token, exists: false };
|
|
21626
21967
|
size = st.size;
|
|
21627
21968
|
} catch {
|
|
21628
|
-
return { path: token, exists:
|
|
21969
|
+
return { path: token, exists: true };
|
|
21629
21970
|
}
|
|
21630
21971
|
if (size > MAX_BYTES)
|
|
21631
21972
|
return { path: token, exists: true };
|
|
21632
21973
|
let content;
|
|
21633
21974
|
try {
|
|
21634
|
-
content = readFileSync25(
|
|
21975
|
+
content = readFileSync25(found, "utf-8");
|
|
21635
21976
|
} catch {
|
|
21636
21977
|
return { path: token, exists: true };
|
|
21637
21978
|
}
|
|
@@ -21641,6 +21982,7 @@ var MAX_PATHS = 10, MAX_BYTES, JSON_EXTS, XML_EXTS;
|
|
|
21641
21982
|
var init_artifact_resolve = __esm(() => {
|
|
21642
21983
|
init_js_identifiers();
|
|
21643
21984
|
init_syntax_validator();
|
|
21985
|
+
init_auditor();
|
|
21644
21986
|
MAX_BYTES = 500 * 1024;
|
|
21645
21987
|
JSON_EXTS = new Set([".json", ".jsonc"]);
|
|
21646
21988
|
XML_EXTS = new Set([".xml", ".drawio", ".svg", ".xaml", ".plist", ".iml"]);
|
|
@@ -21678,6 +22020,7 @@ class AuditGate {
|
|
|
21678
22020
|
return { action: "exhausted", summary: audit.summary };
|
|
21679
22021
|
}
|
|
21680
22022
|
state.suppressRepetitionRetry = true;
|
|
22023
|
+
deps.onMeta?.(t("ui.draft_retracted"), "retract");
|
|
21681
22024
|
return { action: "reject" };
|
|
21682
22025
|
}
|
|
21683
22026
|
}
|
|
@@ -21689,10 +22032,17 @@ var init_audit_gate = __esm(() => {
|
|
|
21689
22032
|
function issueSignature(issue) {
|
|
21690
22033
|
return `${issue.severity}:${issue.claim}`.toLowerCase().replace(/\s+/g, " ").slice(0, 120);
|
|
21691
22034
|
}
|
|
22035
|
+
function normalizedSignature(issue) {
|
|
22036
|
+
const body = `${issue.severity}:${issue.claim}`.toLowerCase().replace(/[^a-z0-9а-яё\s]/gi, " ").replace(/\s+/g, " ").trim().slice(0, 120);
|
|
22037
|
+
return `~${body}`;
|
|
22038
|
+
}
|
|
21692
22039
|
function renderIssues(issues) {
|
|
21693
22040
|
return issues.slice(0, 5).map((i) => `- [${i.severity}] ${i.problem || i.claim}${i.suggestion ? ` → ${i.suggestion}` : ""}`).join(`
|
|
21694
22041
|
`);
|
|
21695
22042
|
}
|
|
22043
|
+
function isRepeatedVerdict(state, issues) {
|
|
22044
|
+
return issues.length > 0 && issues.every((i) => state.seenCriticIssues.has(normalizedSignature(i)));
|
|
22045
|
+
}
|
|
21696
22046
|
|
|
21697
22047
|
class CriticGate {
|
|
21698
22048
|
opts;
|
|
@@ -21708,18 +22058,26 @@ class CriticGate {
|
|
|
21708
22058
|
const verdict = await this.verifySafely(deps);
|
|
21709
22059
|
if (!verdict || verdict.status === "ok")
|
|
21710
22060
|
return "pass";
|
|
22061
|
+
const isRepeat = isRepeatedVerdict(deps.state, verdict.issues);
|
|
21711
22062
|
const fresh = this.takeFreshIssues(deps.state, verdict.issues);
|
|
21712
22063
|
if (fresh.length === 0)
|
|
21713
22064
|
return "pass";
|
|
21714
22065
|
this.logVerdict(deps, verdict, fresh.length);
|
|
21715
|
-
|
|
21716
|
-
|
|
22066
|
+
if (!this.shouldRepair(deps, verdict, isRepeat)) {
|
|
22067
|
+
this.injectRepeatOrAdvice(deps, fresh, isRepeat);
|
|
22068
|
+
return "pass";
|
|
22069
|
+
}
|
|
22070
|
+
this.injectRepair(deps, verdict, fresh);
|
|
21717
22071
|
return "retry";
|
|
21718
22072
|
}
|
|
22073
|
+
shouldRepair(deps, verdict, isRepeat) {
|
|
22074
|
+
return verdict.status === "critical" && deps.beforeFinish && deps.state.criticRepairCycles < this.opts.maxRepairCycles && !isRepeat;
|
|
22075
|
+
}
|
|
21719
22076
|
async verifySafely(deps) {
|
|
21720
22077
|
try {
|
|
21721
22078
|
return await this.opts.verify(this.opts.buildPack(deps), this.opts.signal);
|
|
21722
|
-
} catch {
|
|
22079
|
+
} catch (err) {
|
|
22080
|
+
deps.logger.diagnostic("warn", `Critic verify failed (fail-open): ${String(err?.message ?? err)}`);
|
|
21723
22081
|
return null;
|
|
21724
22082
|
}
|
|
21725
22083
|
}
|
|
@@ -21728,9 +22086,8 @@ class CriticGate {
|
|
|
21728
22086
|
return false;
|
|
21729
22087
|
if (deps.state.criticCalls >= this.opts.maxCalls)
|
|
21730
22088
|
return false;
|
|
21731
|
-
if (!deps.beforeFinish
|
|
22089
|
+
if (!deps.beforeFinish)
|
|
21732
22090
|
return false;
|
|
21733
|
-
}
|
|
21734
22091
|
return deps.toolEvents.length !== 0;
|
|
21735
22092
|
}
|
|
21736
22093
|
takeFreshIssues(state, issues) {
|
|
@@ -21740,6 +22097,7 @@ class CriticGate {
|
|
|
21740
22097
|
if (state.seenCriticIssues.has(sig))
|
|
21741
22098
|
continue;
|
|
21742
22099
|
state.seenCriticIssues.add(sig);
|
|
22100
|
+
state.seenCriticIssues.add(normalizedSignature(issue));
|
|
21743
22101
|
fresh.push(issue);
|
|
21744
22102
|
}
|
|
21745
22103
|
return fresh;
|
|
@@ -21760,15 +22118,15 @@ class CriticGate {
|
|
|
21760
22118
|
});
|
|
21761
22119
|
deps.logger.diagnostic("info", `Critic ${verdict.status}: ${verdict.summary} (${count} issue(s))`);
|
|
21762
22120
|
}
|
|
21763
|
-
|
|
21764
|
-
|
|
21765
|
-
|
|
21766
|
-
|
|
21767
|
-
|
|
21768
|
-
|
|
21769
|
-
|
|
21770
|
-
}
|
|
22121
|
+
injectRepeatOrAdvice(deps, fresh, isRepeat) {
|
|
22122
|
+
deps.contextManager.addMessage({
|
|
22123
|
+
role: "user",
|
|
22124
|
+
content: `<system-summary>${isRepeat ? t("critic.repeat", { issues: renderIssues(fresh) }) : t("critic.advice", { issues: renderIssues(fresh) })}</system-summary>`
|
|
22125
|
+
});
|
|
22126
|
+
}
|
|
22127
|
+
injectRepair(deps, verdict, fresh) {
|
|
21771
22128
|
deps.state.criticRepairCycles++;
|
|
22129
|
+
deps.onMeta?.(t("ui.draft_retracted"), "retract");
|
|
21772
22130
|
deps.slog.logCritic("critic_escalation", {
|
|
21773
22131
|
summary: verdict.summary,
|
|
21774
22132
|
cycle: deps.state.criticRepairCycles
|
|
@@ -21782,9 +22140,11 @@ class CriticGate {
|
|
|
21782
22140
|
});
|
|
21783
22141
|
}
|
|
21784
22142
|
}
|
|
21785
|
-
function gatherTurnToolEvents(contextManager) {
|
|
22143
|
+
function gatherTurnToolEvents(contextManager, fromIndex = 0) {
|
|
21786
22144
|
const events = [];
|
|
21787
|
-
|
|
22145
|
+
const history = contextManager.getActiveHistory();
|
|
22146
|
+
const start = Math.max(0, Math.min(fromIndex, history.length));
|
|
22147
|
+
for (const m of history.slice(start)) {
|
|
21788
22148
|
if (m.role !== "tool" || !m.name)
|
|
21789
22149
|
continue;
|
|
21790
22150
|
const output = typeof m.content === "string" ? m.content.slice(-MAX_EVENT_OUTPUT_CHARS) : undefined;
|
|
@@ -21792,7 +22152,7 @@ function gatherTurnToolEvents(contextManager) {
|
|
|
21792
22152
|
}
|
|
21793
22153
|
return events;
|
|
21794
22154
|
}
|
|
21795
|
-
var
|
|
22155
|
+
var MAX_EVENT_OUTPUT_CHARS = 600;
|
|
21796
22156
|
var init_critic_gate = __esm(() => {
|
|
21797
22157
|
init_i18n();
|
|
21798
22158
|
});
|
|
@@ -21979,7 +22339,9 @@ ${f.excerpt}`);
|
|
|
21979
22339
|
pack.toolDigest || "(empty)",
|
|
21980
22340
|
files.length > 0 ? `FILE CONTENTS:
|
|
21981
22341
|
${files.join(`
|
|
21982
|
-
`)}` : ""
|
|
22342
|
+
`)}` : "",
|
|
22343
|
+
pack.answerExcerpt ? `ANSWER (the agent's chat delivery — may satisfy the task without files):
|
|
22344
|
+
${pack.answerExcerpt}` : ""
|
|
21983
22345
|
].filter(Boolean).join(`
|
|
21984
22346
|
`);
|
|
21985
22347
|
}
|
|
@@ -22033,6 +22395,7 @@ Rules:
|
|
|
22033
22395
|
- Flag ONLY issues that can be verified from the evidence provided. Do not speculate or invent.
|
|
22034
22396
|
- Do not nitpick style, wording, or preferences unless the user's task demanded it.
|
|
22035
22397
|
- If the evidence is insufficient to judge, return status "ok" (prefer silence over noise).
|
|
22398
|
+
- A chat-delivered answer (ANSWER section) can fully satisfy the task without any files or commands; absence of changed files is NOT itself an issue when ANSWER contains the requested result.
|
|
22036
22399
|
- "critical" = the task's stated result is demonstrably not delivered. "concern" = a concrete, checkable gap. "info" = minor.
|
|
22037
22400
|
- Every issue must reference concrete evidence (file, command, output).
|
|
22038
22401
|
Reply with JSON ONLY:
|
|
@@ -22047,8 +22410,12 @@ var init_client = __esm(() => {
|
|
|
22047
22410
|
// src/modules/critic/provider.ts
|
|
22048
22411
|
function buildCriticProvider(critic, config, defaultProvider, deps) {
|
|
22049
22412
|
const model = critic?.model?.trim();
|
|
22050
|
-
if (!model)
|
|
22413
|
+
if (!model) {
|
|
22414
|
+
if (critic?.provider && Object.keys(critic.provider).length > 0) {
|
|
22415
|
+
deps?.logger?.warn("critic.provider is set without critic.model — provider ignored, using active provider");
|
|
22416
|
+
}
|
|
22051
22417
|
return defaultProvider;
|
|
22418
|
+
}
|
|
22052
22419
|
try {
|
|
22053
22420
|
const providerCfg = critic?.provider ?? {
|
|
22054
22421
|
type: "openai-compat",
|
|
@@ -22106,7 +22473,8 @@ function buildEvidencePack(input) {
|
|
|
22106
22473
|
commands,
|
|
22107
22474
|
toolDigest: digest.slice(-MAX_DIGEST_LINES).join(`
|
|
22108
22475
|
`),
|
|
22109
|
-
fileExcerpts: input.baseDir ? readExcerpts(input.baseDir, [...changedFiles]) : undefined
|
|
22476
|
+
fileExcerpts: input.baseDir ? readExcerpts(input.baseDir, [...changedFiles]) : undefined,
|
|
22477
|
+
answerExcerpt: input.answerText ? redactContextSecrets(input.answerText).slice(0, MAX_ANSWER_CHARS) : undefined
|
|
22110
22478
|
};
|
|
22111
22479
|
}
|
|
22112
22480
|
function digestLine(ev) {
|
|
@@ -22127,7 +22495,7 @@ function commandOf(ev) {
|
|
|
22127
22495
|
return;
|
|
22128
22496
|
return {
|
|
22129
22497
|
command: ev.args.command,
|
|
22130
|
-
exitCode: ev.ok === false ? 1 :
|
|
22498
|
+
exitCode: ev.ok === false ? 1 : undefined,
|
|
22131
22499
|
output: ev.output?.slice(-MAX_DIGEST_OUTPUT_CHARS)
|
|
22132
22500
|
};
|
|
22133
22501
|
}
|
|
@@ -22145,9 +22513,10 @@ function readExcerpts(baseDir, paths) {
|
|
|
22145
22513
|
}
|
|
22146
22514
|
return out;
|
|
22147
22515
|
}
|
|
22148
|
-
var MUTATING_TOOLS, MAX_DIGEST_LINES = 40, MAX_DIGEST_OUTPUT_CHARS = 300, MAX_EXCERPT_FILES = 5, MAX_EXCERPT_CHARS = 1200;
|
|
22516
|
+
var MUTATING_TOOLS, MAX_DIGEST_LINES = 40, MAX_DIGEST_OUTPUT_CHARS = 300, MAX_EXCERPT_FILES = 5, MAX_EXCERPT_CHARS = 1200, MAX_ANSWER_CHARS = 2000;
|
|
22149
22517
|
var init_evidence = __esm(() => {
|
|
22150
22518
|
init_tool_output();
|
|
22519
|
+
init_context_log();
|
|
22151
22520
|
MUTATING_TOOLS = new Set(["write_file", "edit_file", "delete_file", "move_file", "create_dir"]);
|
|
22152
22521
|
});
|
|
22153
22522
|
|
|
@@ -22842,6 +23211,7 @@ class Agent {
|
|
|
22842
23211
|
} = this.deps;
|
|
22843
23212
|
this.abortController = new AbortController;
|
|
22844
23213
|
const state = createLoopState();
|
|
23214
|
+
state.criticHistoryMark = contextManager.getActiveHistory().length;
|
|
22845
23215
|
const compactionService = new CompactionService({
|
|
22846
23216
|
contextManager,
|
|
22847
23217
|
logger: logger3,
|
|
@@ -22899,7 +23269,8 @@ class Agent {
|
|
|
22899
23269
|
task: d.task,
|
|
22900
23270
|
planSummary: d.planSummary,
|
|
22901
23271
|
toolEvents: d.toolEvents,
|
|
22902
|
-
baseDir: this.deps.baseDir
|
|
23272
|
+
baseDir: this.deps.baseDir,
|
|
23273
|
+
answerText: d.answerText
|
|
22903
23274
|
}),
|
|
22904
23275
|
signal: this.abortController?.signal
|
|
22905
23276
|
});
|
|
@@ -22927,7 +23298,7 @@ class Agent {
|
|
|
22927
23298
|
});
|
|
22928
23299
|
compactionService.compactIfNeeded(state);
|
|
22929
23300
|
this.refreshSystemPrompt();
|
|
22930
|
-
const history = contextManager.getActiveHistory();
|
|
23301
|
+
const history = repairToolCallPairing(contextManager.getActiveHistory());
|
|
22931
23302
|
const promptSnapshot = buildPromptSnapshot(history, allToolsForBudget);
|
|
22932
23303
|
state.prefixDelta = diffPrompt(state.prevPrompt, promptSnapshot, estimateTokens);
|
|
22933
23304
|
state.prevPrompt = promptSnapshot;
|
|
@@ -23180,7 +23551,8 @@ class Agent {
|
|
|
23180
23551
|
onMeta,
|
|
23181
23552
|
onChunk,
|
|
23182
23553
|
verbose: resolveVerbosity(this.deps.config.ui) === "verbose",
|
|
23183
|
-
artifacts: resolveArtifactStates(this.deps.baseDir, textContent)
|
|
23554
|
+
artifacts: resolveArtifactStates(this.deps.baseDir, textContent),
|
|
23555
|
+
slog
|
|
23184
23556
|
});
|
|
23185
23557
|
if (verdict.action === "block") {
|
|
23186
23558
|
return {
|
|
@@ -23233,8 +23605,10 @@ class Agent {
|
|
|
23233
23605
|
slog,
|
|
23234
23606
|
task: input,
|
|
23235
23607
|
planSummary: this.deps.planSummary?.() ?? undefined,
|
|
23236
|
-
toolEvents: gatherTurnToolEvents(contextManager),
|
|
23237
|
-
beforeFinish: true
|
|
23608
|
+
toolEvents: gatherTurnToolEvents(contextManager, state.criticHistoryMark),
|
|
23609
|
+
beforeFinish: true,
|
|
23610
|
+
answerText: state.mutationsSinceCritic === 0 ? textContent : undefined,
|
|
23611
|
+
onMeta
|
|
23238
23612
|
});
|
|
23239
23613
|
if (criticAction === "retry") {
|
|
23240
23614
|
state.suppressRepetitionRetry = true;
|
|
@@ -23246,7 +23620,8 @@ class Agent {
|
|
|
23246
23620
|
maxIterations: config.maxToolIterations,
|
|
23247
23621
|
logger: logger3,
|
|
23248
23622
|
contextManager,
|
|
23249
|
-
slog
|
|
23623
|
+
slog,
|
|
23624
|
+
onMeta
|
|
23250
23625
|
});
|
|
23251
23626
|
if (auditVerdict === null || auditVerdict.action === "pass") {
|
|
23252
23627
|
state.finalAnswerAccepted = true;
|
|
@@ -23351,6 +23726,13 @@ class Agent {
|
|
|
23351
23726
|
if (this.deps.configRef)
|
|
23352
23727
|
this.deps.configRef.current = config;
|
|
23353
23728
|
this.costTracker.setModel(config.model);
|
|
23729
|
+
this.applyReasoningStrategy(config.provider);
|
|
23730
|
+
}
|
|
23731
|
+
applyReasoningStrategy(provider) {
|
|
23732
|
+
const strategy = reasoningStrategyForProvider(provider);
|
|
23733
|
+
this.deps.reasoningStrategy = strategy;
|
|
23734
|
+
if (strategy === "none")
|
|
23735
|
+
this.probePassed = false;
|
|
23354
23736
|
}
|
|
23355
23737
|
setProvider(name, model) {
|
|
23356
23738
|
const { manager, provider } = buildActiveProvider(this.deps.config, this.deps.logger, {
|
|
@@ -23359,6 +23741,7 @@ class Agent {
|
|
|
23359
23741
|
manager.switch(name, model);
|
|
23360
23742
|
const providerCfg = manager.toConfig();
|
|
23361
23743
|
this.deps.config.provider = providerCfg;
|
|
23744
|
+
this.applyReasoningStrategy(providerCfg);
|
|
23362
23745
|
this.deps.llmProvider = provider;
|
|
23363
23746
|
this.deps.getProviderName = () => manager.activeName;
|
|
23364
23747
|
this.deps.toolExecutor.updateProvider(provider);
|
|
@@ -30508,6 +30891,33 @@ class PlanStore {
|
|
|
30508
30891
|
activePath() {
|
|
30509
30892
|
return join44(this.plansDir, "active.json");
|
|
30510
30893
|
}
|
|
30894
|
+
sessionsDir() {
|
|
30895
|
+
return join44(this.plansDir, "sessions");
|
|
30896
|
+
}
|
|
30897
|
+
sessionActivePath(sessionId) {
|
|
30898
|
+
if (!/^[A-Za-z0-9_-]+$/.test(sessionId)) {
|
|
30899
|
+
throw new Error(`invalid session id: ${sessionId}`);
|
|
30900
|
+
}
|
|
30901
|
+
return join44(this.sessionsDir(), sessionId, "active.json");
|
|
30902
|
+
}
|
|
30903
|
+
saveSessionActive(sessionId, plan) {
|
|
30904
|
+
const p = this.sessionActivePath(sessionId);
|
|
30905
|
+
const dir = join44(this.sessionsDir(), sessionId);
|
|
30906
|
+
if (!existsSync50(dir))
|
|
30907
|
+
mkdirSync24(dir, { recursive: true });
|
|
30908
|
+
writePlanFile(p, plan);
|
|
30909
|
+
}
|
|
30910
|
+
loadSessionActive(sessionId) {
|
|
30911
|
+
const p = this.sessionActivePath(sessionId);
|
|
30912
|
+
if (!existsSync50(p))
|
|
30913
|
+
return null;
|
|
30914
|
+
return readPlanFile(p, this.baseDir);
|
|
30915
|
+
}
|
|
30916
|
+
clearSessionActive(sessionId) {
|
|
30917
|
+
const p = this.sessionActivePath(sessionId);
|
|
30918
|
+
if (existsSync50(p))
|
|
30919
|
+
rmSync3(p, { force: true });
|
|
30920
|
+
}
|
|
30511
30921
|
saveActive(plan) {
|
|
30512
30922
|
writePlanFile(this.activePath(), plan);
|
|
30513
30923
|
}
|
|
@@ -31033,7 +31443,7 @@ Last compile error: ${first[1]}`;
|
|
|
31033
31443
|
}
|
|
31034
31444
|
}
|
|
31035
31445
|
if (result.success && FS_MUTATING_TOOLS.has(call.name)) {
|
|
31036
|
-
deps.advancePlanIfStepComplete(ctx.
|
|
31446
|
+
deps.advancePlanIfStepComplete(ctx.sessionLog);
|
|
31037
31447
|
}
|
|
31038
31448
|
deps.maybeSearchError(ctx, call);
|
|
31039
31449
|
}
|
|
@@ -31982,6 +32392,7 @@ function planPathToken(p) {
|
|
|
31982
32392
|
class ExecutionModule {
|
|
31983
32393
|
name = "execution";
|
|
31984
32394
|
tracker = null;
|
|
32395
|
+
sessionId = null;
|
|
31985
32396
|
verifier;
|
|
31986
32397
|
stuckDetector;
|
|
31987
32398
|
auditor;
|
|
@@ -32018,9 +32429,20 @@ class ExecutionModule {
|
|
|
32018
32429
|
},
|
|
32019
32430
|
set current(v) {
|
|
32020
32431
|
self.tracker = v;
|
|
32432
|
+
self.flushSessionPlan();
|
|
32021
32433
|
}
|
|
32022
32434
|
};
|
|
32023
32435
|
})();
|
|
32436
|
+
flushSessionPlan() {
|
|
32437
|
+
if (!this.sessionId)
|
|
32438
|
+
return;
|
|
32439
|
+
try {
|
|
32440
|
+
if (this.tracker)
|
|
32441
|
+
this.store.saveSessionActive(this.sessionId, this.tracker.getPlan());
|
|
32442
|
+
else
|
|
32443
|
+
this.store.clearSessionActive(this.sessionId);
|
|
32444
|
+
} catch {}
|
|
32445
|
+
}
|
|
32024
32446
|
constructor(baseDir, stuckThreshold = 6, webSearchThreshold = 5, searchRunner = performWebSearch, errorSearchCooldownMs = EXECUTION_ERROR_SEARCH_MIN_INTERVAL_MS) {
|
|
32025
32447
|
this.baseDir = baseDir;
|
|
32026
32448
|
this.verifier = new StepVerifier(baseDir);
|
|
@@ -32034,9 +32456,69 @@ class ExecutionModule {
|
|
|
32034
32456
|
this.tracker = new PlanTracker(plan);
|
|
32035
32457
|
this.tracker.syncCurrentStep();
|
|
32036
32458
|
this.store.saveActive(plan);
|
|
32459
|
+
if (this.sessionId) {
|
|
32460
|
+
try {
|
|
32461
|
+
this.store.saveSessionActive(this.sessionId, plan);
|
|
32462
|
+
} catch {}
|
|
32463
|
+
}
|
|
32037
32464
|
this.completedPlan = null;
|
|
32038
32465
|
this._auditSkipsRemaining = 0;
|
|
32039
32466
|
}
|
|
32467
|
+
switchSession(id) {
|
|
32468
|
+
const prev = this.sessionId;
|
|
32469
|
+
if (prev === id)
|
|
32470
|
+
return;
|
|
32471
|
+
if (this.tracker) {
|
|
32472
|
+
try {
|
|
32473
|
+
this.store.saveSessionActive(prev ?? id ?? "", this.tracker.getPlan());
|
|
32474
|
+
} catch {}
|
|
32475
|
+
} else if (prev) {
|
|
32476
|
+
try {
|
|
32477
|
+
this.store.clearSessionActive(prev);
|
|
32478
|
+
} catch {}
|
|
32479
|
+
}
|
|
32480
|
+
this.sessionId = id;
|
|
32481
|
+
this.completedPlan = null;
|
|
32482
|
+
if (!id) {
|
|
32483
|
+
this.tracker = null;
|
|
32484
|
+
this._auditSkipsRemaining = 0;
|
|
32485
|
+
return;
|
|
32486
|
+
}
|
|
32487
|
+
let plan = null;
|
|
32488
|
+
try {
|
|
32489
|
+
plan = this.store.loadSessionActive(id);
|
|
32490
|
+
} catch {
|
|
32491
|
+
plan = null;
|
|
32492
|
+
}
|
|
32493
|
+
if (!plan) {
|
|
32494
|
+
this.tracker = null;
|
|
32495
|
+
this._auditSkipsRemaining = 0;
|
|
32496
|
+
return;
|
|
32497
|
+
}
|
|
32498
|
+
const restored = new PlanTracker(plan);
|
|
32499
|
+
if (restored.isComplete()) {
|
|
32500
|
+
this.store.archivePlan(plan);
|
|
32501
|
+
try {
|
|
32502
|
+
this.store.clearSessionActive(id);
|
|
32503
|
+
} catch {}
|
|
32504
|
+
this.tracker = null;
|
|
32505
|
+
return;
|
|
32506
|
+
}
|
|
32507
|
+
this.tracker = restored;
|
|
32508
|
+
this.tracker.syncCurrentStep();
|
|
32509
|
+
this._auditSkipsRemaining = 1;
|
|
32510
|
+
}
|
|
32511
|
+
forgetSession(id) {
|
|
32512
|
+
try {
|
|
32513
|
+
this.store.clearSessionActive(id);
|
|
32514
|
+
} catch {}
|
|
32515
|
+
if (this.sessionId === id) {
|
|
32516
|
+
this.sessionId = null;
|
|
32517
|
+
this.tracker = null;
|
|
32518
|
+
this.completedPlan = null;
|
|
32519
|
+
this._auditSkipsRemaining = 0;
|
|
32520
|
+
}
|
|
32521
|
+
}
|
|
32040
32522
|
setHallucinationDetector(detector) {
|
|
32041
32523
|
this.hallucinationDetector = detector;
|
|
32042
32524
|
}
|
|
@@ -32167,6 +32649,7 @@ class ExecutionModule {
|
|
|
32167
32649
|
const done2 = plan2.steps.filter((s) => s.status === "done").length;
|
|
32168
32650
|
if (autoClosed2 > 0) {
|
|
32169
32651
|
this.store.saveActive(plan2);
|
|
32652
|
+
this.flushSessionPlan();
|
|
32170
32653
|
}
|
|
32171
32654
|
return {
|
|
32172
32655
|
passed: audit2.passed && pendingSteps2.length === 0,
|
|
@@ -32185,6 +32668,7 @@ class ExecutionModule {
|
|
|
32185
32668
|
const autoClosed = this.autoCloseEvidenceSteps(plan);
|
|
32186
32669
|
if (autoClosed > 0) {
|
|
32187
32670
|
this.store.saveActive(plan);
|
|
32671
|
+
this.flushSessionPlan();
|
|
32188
32672
|
}
|
|
32189
32673
|
const audit = await this.auditor.audit(plan);
|
|
32190
32674
|
const pendingSteps = plan.steps.flatMap((s) => s.status !== "done" && s.status !== "skipped" ? [`${s.id}. ${s.description}`] : []);
|
|
@@ -32261,7 +32745,7 @@ class ExecutionModule {
|
|
|
32261
32745
|
state: this.state,
|
|
32262
32746
|
store: this.store,
|
|
32263
32747
|
checkPlanAlignment: (call) => this.checkPlanAlignment(call),
|
|
32264
|
-
advancePlanIfStepComplete: (
|
|
32748
|
+
advancePlanIfStepComplete: (sl) => this.advancePlanIfStepComplete(sl),
|
|
32265
32749
|
maybeSearchError: (ctx, call) => this.maybeSearchError(ctx, call)
|
|
32266
32750
|
});
|
|
32267
32751
|
}
|
|
@@ -32330,7 +32814,7 @@ class ExecutionModule {
|
|
|
32330
32814
|
}
|
|
32331
32815
|
return out;
|
|
32332
32816
|
}
|
|
32333
|
-
advancePlanIfStepComplete(
|
|
32817
|
+
advancePlanIfStepComplete(sessionLog) {
|
|
32334
32818
|
const step = this.tracker?.getCurrentStep();
|
|
32335
32819
|
if (!step)
|
|
32336
32820
|
return;
|
|
@@ -32352,19 +32836,17 @@ class ExecutionModule {
|
|
|
32352
32836
|
];
|
|
32353
32837
|
const hasLockFile = lockFiles.some((f) => existsSync51(resolve22(this.baseDir, f)));
|
|
32354
32838
|
if (!hasLockFile) {
|
|
32355
|
-
|
|
32356
|
-
|
|
32357
|
-
|
|
32358
|
-
|
|
32359
|
-
|
|
32360
|
-
|
|
32361
|
-
|
|
32362
|
-
|
|
32363
|
-
|
|
32364
|
-
|
|
32365
|
-
|
|
32366
|
-
});
|
|
32367
|
-
}
|
|
32839
|
+
const hints = this.state.depsGateHints.get(step.id) || 0;
|
|
32840
|
+
this.state.depsGateHints.set(step.id, hints + 1);
|
|
32841
|
+
const force = hints >= 1;
|
|
32842
|
+
const content = force ? t("exec.step_gate_deps_force", { step: String(step.id) }) : t("exec.step_gate_deps", {
|
|
32843
|
+
step: String(step.id),
|
|
32844
|
+
description: step.description
|
|
32845
|
+
});
|
|
32846
|
+
this.pendingMessages.push({
|
|
32847
|
+
role: "user",
|
|
32848
|
+
content: `<system-summary>${content}</system-summary>`
|
|
32849
|
+
});
|
|
32368
32850
|
return;
|
|
32369
32851
|
}
|
|
32370
32852
|
}
|
|
@@ -32388,8 +32870,8 @@ class ExecutionModule {
|
|
|
32388
32870
|
}
|
|
32389
32871
|
} catch {}
|
|
32390
32872
|
}
|
|
32391
|
-
if (emptyFiles.length > 0
|
|
32392
|
-
|
|
32873
|
+
if (emptyFiles.length > 0) {
|
|
32874
|
+
this.pendingMessages.push({
|
|
32393
32875
|
role: "user",
|
|
32394
32876
|
content: `<system-summary>${t("exec.step_gate_empty", { step: String(step.id), files: emptyFiles.join(", ") })}</system-summary>`
|
|
32395
32877
|
});
|
|
@@ -32400,25 +32882,25 @@ class ExecutionModule {
|
|
|
32400
32882
|
const hadNext = this.tracker?.advance() ?? false;
|
|
32401
32883
|
if (this.tracker) {
|
|
32402
32884
|
this.store.saveActive(this.tracker.getPlan());
|
|
32885
|
+
this.flushSessionPlan();
|
|
32403
32886
|
sessionLog?.plan("auto-advance", `Step ${step.id} auto-completed | ${this.tracker.getProgressString()} | current: step ${this.tracker.getCurrentStepIndex() + 1}`);
|
|
32404
32887
|
}
|
|
32405
|
-
|
|
32406
|
-
|
|
32407
|
-
|
|
32408
|
-
|
|
32409
|
-
|
|
32410
|
-
|
|
32411
|
-
|
|
32412
|
-
|
|
32413
|
-
|
|
32414
|
-
|
|
32415
|
-
});
|
|
32416
|
-
}
|
|
32888
|
+
const nextStep = hadNext ? this.tracker?.getCurrentStep() : null;
|
|
32889
|
+
const nextMsg = nextStep ? t("exec.step_gate_ok", {
|
|
32890
|
+
step: String(step.id),
|
|
32891
|
+
nextStep: String(nextStep.id),
|
|
32892
|
+
nextDesc: nextStep.description
|
|
32893
|
+
}) : t("exec.step_gate_last", { step: String(step.id) });
|
|
32894
|
+
this.pendingMessages.push({
|
|
32895
|
+
role: "user",
|
|
32896
|
+
content: `<system-summary>${nextMsg}</system-summary>`
|
|
32897
|
+
});
|
|
32417
32898
|
if (this.tracker?.isComplete()) {
|
|
32418
32899
|
const completed = this.tracker.getPlan();
|
|
32419
32900
|
this.store.archivePlan(completed);
|
|
32420
32901
|
this.recordCompleted(completed);
|
|
32421
32902
|
this.tracker = null;
|
|
32903
|
+
this.flushSessionPlan();
|
|
32422
32904
|
sessionLog?.plan("auto-archive", `Plan ${completed.id} complete — archived`);
|
|
32423
32905
|
}
|
|
32424
32906
|
}
|
|
@@ -33777,6 +34259,9 @@ async function registerCoreModules(input, moduleRegistry) {
|
|
|
33777
34259
|
const { config, logger: logger5, dir, baseDir, hallucinationDetector } = input;
|
|
33778
34260
|
const execModule = new ExecutionModule(baseDir, config.stuckThreshold, config.errorWebSearch?.threshold ?? 5);
|
|
33779
34261
|
execModule.restorePlan();
|
|
34262
|
+
try {
|
|
34263
|
+
execModule.switchSession(input.sessionManager.getActive());
|
|
34264
|
+
} catch {}
|
|
33780
34265
|
moduleRegistry.register(execModule);
|
|
33781
34266
|
execModule.setHallucinationDetector(hallucinationDetector);
|
|
33782
34267
|
const sessionModule = new SessionModule(input.sessionManager);
|
|
@@ -34746,6 +35231,40 @@ var init_box = __esm(() => {
|
|
|
34746
35231
|
});
|
|
34747
35232
|
|
|
34748
35233
|
// src/modules/setup/answers.ts
|
|
35234
|
+
function securityDetailFromConfig(s) {
|
|
35235
|
+
return {
|
|
35236
|
+
bash: {
|
|
35237
|
+
blacklist: [...s.bash.blacklist],
|
|
35238
|
+
whitelist: [...s.bash.whitelist],
|
|
35239
|
+
logCommands: s.bash.logCommands
|
|
35240
|
+
},
|
|
35241
|
+
paths: { denied: [...s.paths.denied], allowed: [...s.paths.allowed] },
|
|
35242
|
+
flags: {
|
|
35243
|
+
dangerousFlags: [...s.bash.dangerousFlags],
|
|
35244
|
+
dangerousOperators: [...s.bash.dangerousOperators]
|
|
35245
|
+
},
|
|
35246
|
+
network: {
|
|
35247
|
+
enabled: s.network.enabled,
|
|
35248
|
+
deniedDomains: [...s.network.deniedDomains],
|
|
35249
|
+
allowedDomains: [...s.network.allowedDomains],
|
|
35250
|
+
requestTimeout: s.network.requestTimeout,
|
|
35251
|
+
maxResponseSize: s.network.maxResponseSize
|
|
35252
|
+
},
|
|
35253
|
+
advanced: {
|
|
35254
|
+
maxRecursionDepth: s.maxRecursionDepth,
|
|
35255
|
+
maxFileOperations: s.maxFileOperations,
|
|
35256
|
+
maxRequestsPerMinute: s.rateLimits.maxRequestsPerMinute,
|
|
35257
|
+
maxParallelTasks: s.rateLimits.maxParallelTasks,
|
|
35258
|
+
contentScanEnabled: s.contentScan.enabled,
|
|
35259
|
+
sessionEncryptionEnabled: s.sessionEncryption.enabled,
|
|
35260
|
+
auditNotifierEnabled: s.auditNotifier.enabled,
|
|
35261
|
+
auditNotifierMinSeverity: s.auditNotifier.minSeverity ?? "medium",
|
|
35262
|
+
auditNotifierEventTypes: [...s.auditNotifier.eventTypes ?? []],
|
|
35263
|
+
auditNotifierMaxRetries: s.auditNotifier.maxRetries ?? 3,
|
|
35264
|
+
auditNotifierWebhookTimeout: s.auditNotifier.webhookTimeout ?? 5000
|
|
35265
|
+
}
|
|
35266
|
+
};
|
|
35267
|
+
}
|
|
34749
35268
|
function buildSetupDisplay() {
|
|
34750
35269
|
const providers = BUILTIN_PROVIDERS.map((spec) => {
|
|
34751
35270
|
const option = { type: spec.type, label: spec.label };
|
|
@@ -35135,20 +35654,62 @@ function applyAnswersToConfig(config, a) {
|
|
|
35135
35654
|
config.provider.entries = next;
|
|
35136
35655
|
config.provider.active = updated.label || updated.type;
|
|
35137
35656
|
}
|
|
35138
|
-
|
|
35139
|
-
config.security.enabled = true;
|
|
35140
|
-
config.security.bash.enabled = true;
|
|
35141
|
-
config.security.bash.blockDangerousFlags = a.securityFlagsBlock || config.security.bash.blockDangerousFlags;
|
|
35142
|
-
if (a.securityBashBlock) {
|
|
35143
|
-
config.security.bash.blacklist = [
|
|
35144
|
-
...new Set([...config.security.bash.blacklist, ...SECURITY_BASH_BLOCKLIST])
|
|
35145
|
-
];
|
|
35146
|
-
}
|
|
35147
|
-
config.security.paths.enabled = a.securityPathsRestrict;
|
|
35148
|
-
}
|
|
35657
|
+
applySecurityAnswers(config, a);
|
|
35149
35658
|
return config;
|
|
35150
35659
|
}
|
|
35151
|
-
|
|
35660
|
+
function applySecurityAnswers(config, a) {
|
|
35661
|
+
if (!config.security)
|
|
35662
|
+
return;
|
|
35663
|
+
config.security.enabled = true;
|
|
35664
|
+
config.security.bash.enabled = true;
|
|
35665
|
+
config.security.bash.blockDangerousFlags = a.securityFlagsBlock || config.security.bash.blockDangerousFlags;
|
|
35666
|
+
if (a.securityBashBlock) {
|
|
35667
|
+
config.security.bash.blacklist = [
|
|
35668
|
+
...new Set([...config.security.bash.blacklist, ...SECURITY_BASH_BLOCKLIST])
|
|
35669
|
+
];
|
|
35670
|
+
}
|
|
35671
|
+
config.security.paths.enabled = a.securityPathsRestrict;
|
|
35672
|
+
if (a.securityDetail)
|
|
35673
|
+
applySecurityDetail(config.security, a.securityDetail);
|
|
35674
|
+
}
|
|
35675
|
+
function readPath(obj, path) {
|
|
35676
|
+
let cur = obj;
|
|
35677
|
+
for (const key of path.split(".")) {
|
|
35678
|
+
if (cur === null || typeof cur !== "object")
|
|
35679
|
+
return;
|
|
35680
|
+
cur = cur[key];
|
|
35681
|
+
}
|
|
35682
|
+
return cur;
|
|
35683
|
+
}
|
|
35684
|
+
function writePath(obj, path, value) {
|
|
35685
|
+
const keys = path.split(".");
|
|
35686
|
+
let cur = obj;
|
|
35687
|
+
for (let i = 0;i < keys.length - 1; i++) {
|
|
35688
|
+
if (cur[keys[i]] === null || typeof cur[keys[i]] !== "object")
|
|
35689
|
+
cur[keys[i]] = {};
|
|
35690
|
+
cur = cur[keys[i]];
|
|
35691
|
+
}
|
|
35692
|
+
cur[keys[keys.length - 1]] = value;
|
|
35693
|
+
}
|
|
35694
|
+
function isFieldValue(v, kind) {
|
|
35695
|
+
if (kind === "list")
|
|
35696
|
+
return Array.isArray(v) && v.every((x) => typeof x === "string");
|
|
35697
|
+
if (kind === "bool")
|
|
35698
|
+
return typeof v === "boolean";
|
|
35699
|
+
if (kind === "int")
|
|
35700
|
+
return typeof v === "number" && Number.isInteger(v) && v > 0;
|
|
35701
|
+
return typeof v === "string" && SEVERITIES2.includes(v);
|
|
35702
|
+
}
|
|
35703
|
+
function applySecurityDetail(security, detail) {
|
|
35704
|
+
const target = security;
|
|
35705
|
+
for (const field of DETAIL_FIELDS) {
|
|
35706
|
+
const value = readPath(detail, field.from);
|
|
35707
|
+
if (!isFieldValue(value, field.kind))
|
|
35708
|
+
continue;
|
|
35709
|
+
writePath(target, field.to, Array.isArray(value) ? [...value] : value);
|
|
35710
|
+
}
|
|
35711
|
+
}
|
|
35712
|
+
var SECURITY_BASH_BLOCKLIST, SEVERITIES2, DETAIL_FIELDS;
|
|
35152
35713
|
var init_apply = __esm(() => {
|
|
35153
35714
|
SECURITY_BASH_BLOCKLIST = [
|
|
35154
35715
|
"rm",
|
|
@@ -35168,6 +35729,32 @@ var init_apply = __esm(() => {
|
|
|
35168
35729
|
"shutdown",
|
|
35169
35730
|
"reboot"
|
|
35170
35731
|
];
|
|
35732
|
+
SEVERITIES2 = ["low", "medium", "high", "critical"];
|
|
35733
|
+
DETAIL_FIELDS = [
|
|
35734
|
+
{ from: "bash.blacklist", to: "bash.blacklist", kind: "list" },
|
|
35735
|
+
{ from: "bash.whitelist", to: "bash.whitelist", kind: "list" },
|
|
35736
|
+
{ from: "bash.logCommands", to: "bash.logCommands", kind: "bool" },
|
|
35737
|
+
{ from: "paths.denied", to: "paths.denied", kind: "list" },
|
|
35738
|
+
{ from: "paths.allowed", to: "paths.allowed", kind: "list" },
|
|
35739
|
+
{ from: "flags.dangerousFlags", to: "bash.dangerousFlags", kind: "list" },
|
|
35740
|
+
{ from: "flags.dangerousOperators", to: "bash.dangerousOperators", kind: "list" },
|
|
35741
|
+
{ from: "network.enabled", to: "network.enabled", kind: "bool" },
|
|
35742
|
+
{ from: "network.deniedDomains", to: "network.deniedDomains", kind: "list" },
|
|
35743
|
+
{ from: "network.allowedDomains", to: "network.allowedDomains", kind: "list" },
|
|
35744
|
+
{ from: "network.requestTimeout", to: "network.requestTimeout", kind: "int" },
|
|
35745
|
+
{ from: "network.maxResponseSize", to: "network.maxResponseSize", kind: "int" },
|
|
35746
|
+
{ from: "advanced.maxRecursionDepth", to: "maxRecursionDepth", kind: "int" },
|
|
35747
|
+
{ from: "advanced.maxFileOperations", to: "maxFileOperations", kind: "int" },
|
|
35748
|
+
{ from: "advanced.maxRequestsPerMinute", to: "rateLimits.maxRequestsPerMinute", kind: "int" },
|
|
35749
|
+
{ from: "advanced.maxParallelTasks", to: "rateLimits.maxParallelTasks", kind: "int" },
|
|
35750
|
+
{ from: "advanced.contentScanEnabled", to: "contentScan.enabled", kind: "bool" },
|
|
35751
|
+
{ from: "advanced.sessionEncryptionEnabled", to: "sessionEncryption.enabled", kind: "bool" },
|
|
35752
|
+
{ from: "advanced.auditNotifierEnabled", to: "auditNotifier.enabled", kind: "bool" },
|
|
35753
|
+
{ from: "advanced.auditNotifierMinSeverity", to: "auditNotifier.minSeverity", kind: "severity" },
|
|
35754
|
+
{ from: "advanced.auditNotifierEventTypes", to: "auditNotifier.eventTypes", kind: "list" },
|
|
35755
|
+
{ from: "advanced.auditNotifierMaxRetries", to: "auditNotifier.maxRetries", kind: "int" },
|
|
35756
|
+
{ from: "advanced.auditNotifierWebhookTimeout", to: "auditNotifier.webhookTimeout", kind: "int" }
|
|
35757
|
+
];
|
|
35171
35758
|
});
|
|
35172
35759
|
|
|
35173
35760
|
// src/cli/setup-order.ts
|
|
@@ -35914,6 +36501,14 @@ function getConfigValue(config, name) {
|
|
|
35914
36501
|
const value = def.get(config);
|
|
35915
36502
|
return { ok: true, key: def.key, def, value, display: formatConfigValue(value) };
|
|
35916
36503
|
}
|
|
36504
|
+
function mirrorActiveEntryFields(provider, activeName) {
|
|
36505
|
+
const entry = (provider.entries ?? []).find((e) => e.label === activeName || e.type === activeName);
|
|
36506
|
+
if (!entry)
|
|
36507
|
+
return;
|
|
36508
|
+
provider.type = entry.type;
|
|
36509
|
+
provider.baseUrl = entry.baseUrl;
|
|
36510
|
+
provider.apiKey = entry.apiKey;
|
|
36511
|
+
}
|
|
35917
36512
|
function applyProviderModelMemory(config, key, value) {
|
|
35918
36513
|
const provider = config.provider;
|
|
35919
36514
|
const activeName = provider.active ?? provider.type;
|
|
@@ -35927,6 +36522,7 @@ function applyProviderModelMemory(config, key, value) {
|
|
|
35927
36522
|
const remembered = provider.models?.[String(value)];
|
|
35928
36523
|
if (remembered)
|
|
35929
36524
|
config.model = remembered;
|
|
36525
|
+
mirrorActiveEntryFields(provider, String(value));
|
|
35930
36526
|
}
|
|
35931
36527
|
}
|
|
35932
36528
|
function setConfigValue(config, name, raw) {
|
|
@@ -45457,8 +46053,9 @@ function registerProviderCommands(ctx) {
|
|
|
45457
46053
|
const list2 = () => {
|
|
45458
46054
|
const providers = ctx.agent.listProviders();
|
|
45459
46055
|
if (providers.length === 0) {
|
|
45460
|
-
|
|
45461
|
-
ctx.output.writeLine(
|
|
46056
|
+
const endpoint = activeProviderEndpoint(ctx.config.provider);
|
|
46057
|
+
ctx.output.writeLine(`${t("repl.provider_current")} ${endpoint.type}`);
|
|
46058
|
+
ctx.output.writeLine(` ${endpoint.baseUrl}`);
|
|
45462
46059
|
return;
|
|
45463
46060
|
}
|
|
45464
46061
|
ctx.output.writeLine(t("repl.provider_current"));
|
|
@@ -45720,7 +46317,8 @@ function registerAgentCommands(ctx) {
|
|
|
45720
46317
|
ctx.output.writeLine(pc.green(t("repl.reloaded")));
|
|
45721
46318
|
ctx.output.writeLine(`${t("repl.model")} ${ctx.config.model}`);
|
|
45722
46319
|
ctx.output.writeLine(`${t("repl.context")} ${ctx.config.contextWindow}`);
|
|
45723
|
-
|
|
46320
|
+
const endpoint = activeProviderEndpoint(ctx.config.provider);
|
|
46321
|
+
ctx.output.writeLine(`${t("repl.provider")} ${endpoint.type} @ ${endpoint.baseUrl}`);
|
|
45724
46322
|
}
|
|
45725
46323
|
});
|
|
45726
46324
|
ctx.registerCommand({
|
|
@@ -45826,6 +46424,10 @@ function registerSessionCommands(ctx) {
|
|
|
45826
46424
|
const name = args.join(" ") || undefined;
|
|
45827
46425
|
const meta = ctx.sessionManager.create(name);
|
|
45828
46426
|
ctx.agent.clearContext();
|
|
46427
|
+
const exec = ctx.agent.getModule("execution");
|
|
46428
|
+
try {
|
|
46429
|
+
exec?.switchSession(meta.id);
|
|
46430
|
+
} catch {}
|
|
45829
46431
|
ctx.output.clearScreen();
|
|
45830
46432
|
ctx.output.writeLine(`${t("session.created", { name: meta.name })} (${pc.dim(meta.id.slice(0, 12))})`);
|
|
45831
46433
|
ctx.output.writeLine(pc.dim(` ${t("session.chat_cleared")}
|
|
@@ -45860,6 +46462,12 @@ function registerSessionCommands(ctx) {
|
|
|
45860
46462
|
ctx.sessionManager.setActive(match.id);
|
|
45861
46463
|
const history = ctx.sessionManager.loadHistory();
|
|
45862
46464
|
ctx.agent.setContext(history);
|
|
46465
|
+
const exec = ctx.agent.getModule("execution");
|
|
46466
|
+
let planLine = null;
|
|
46467
|
+
try {
|
|
46468
|
+
exec?.switchSession(match.id);
|
|
46469
|
+
planLine = exec?.getPlanSummary() ?? null;
|
|
46470
|
+
} catch {}
|
|
45863
46471
|
ctx.output.clearScreen();
|
|
45864
46472
|
ctx.output.writeLine(pc.bold(pc.green(t("session.resumed", { name: match.name }))) + " " + pc.dim(`(${match.id.slice(0, 12)})`) + " — " + match.messageCount + " " + t("repl.msgs"));
|
|
45865
46473
|
ctx.output.writeLine(pc.dim("─".repeat(50)));
|
|
@@ -45882,6 +46490,7 @@ function registerSessionCommands(ctx) {
|
|
|
45882
46490
|
}
|
|
45883
46491
|
ctx.output.writeLine(pc.dim("─".repeat(50)));
|
|
45884
46492
|
ctx.output.writeLine(pc.dim(` ${t("session.chat_loaded")}`));
|
|
46493
|
+
ctx.output.writeLine(pc.dim(` ◇ ${planLine ?? t("plan.no_active")}`));
|
|
45885
46494
|
}
|
|
45886
46495
|
});
|
|
45887
46496
|
ctx.registerCommand({
|
|
@@ -45921,6 +46530,9 @@ function registerSessionCommands(ctx) {
|
|
|
45921
46530
|
return;
|
|
45922
46531
|
}
|
|
45923
46532
|
ctx.sessionManager.delete(match.id);
|
|
46533
|
+
try {
|
|
46534
|
+
ctx.agent.getModule("execution")?.forgetSession(match.id);
|
|
46535
|
+
} catch {}
|
|
45924
46536
|
ctx.output.writeLine(`${t("session.deleted", { id: match.id })}: ${match.name}`);
|
|
45925
46537
|
}
|
|
45926
46538
|
});
|
|
@@ -46031,6 +46643,7 @@ var init_repl_commands = __esm(() => {
|
|
|
46031
46643
|
init_setup_order();
|
|
46032
46644
|
init_config2();
|
|
46033
46645
|
init_presets();
|
|
46646
|
+
init_manager();
|
|
46034
46647
|
init_budget();
|
|
46035
46648
|
init_registry2();
|
|
46036
46649
|
init_export();
|
|
@@ -47083,10 +47696,12 @@ function buildModelCommands(program2) {
|
|
|
47083
47696
|
const { config } = await bootstrap();
|
|
47084
47697
|
getDefaultChannel().writeLine(`${t("cli.current_model")} ${config.model}`);
|
|
47085
47698
|
const { createProvider: createProvider2 } = await Promise.resolve().then(() => (init_create(), exports_create));
|
|
47086
|
-
const
|
|
47699
|
+
const { activeProviderEndpoint: activeProviderEndpoint2 } = await Promise.resolve().then(() => (init_manager(), exports_manager));
|
|
47700
|
+
const endpoint = activeProviderEndpoint2(config.provider);
|
|
47701
|
+
const provider = createProvider2(endpoint.type, {
|
|
47087
47702
|
model: config.model,
|
|
47088
|
-
baseUrl:
|
|
47089
|
-
apiKey:
|
|
47703
|
+
baseUrl: endpoint.baseUrl,
|
|
47704
|
+
apiKey: endpoint.apiKey,
|
|
47090
47705
|
contextWindow: config.contextWindow
|
|
47091
47706
|
});
|
|
47092
47707
|
const spinner = (await Promise.resolve().then(() => (init_spinner(), exports_spinner))).Spinner;
|
|
@@ -49692,6 +50307,7 @@ function adaptActivePlan(plan) {
|
|
|
49692
50307
|
// src/cli/repl.ts
|
|
49693
50308
|
init_repl_commands();
|
|
49694
50309
|
init_registry2();
|
|
50310
|
+
init_manager();
|
|
49695
50311
|
|
|
49696
50312
|
// src/modules/lsp/probe.ts
|
|
49697
50313
|
init_client3();
|
|
@@ -50692,7 +51308,8 @@ ${divider()}`);
|
|
|
50692
51308
|
const resBudget = Math.floor(ctx * this.config.contextBudget.responseReserve);
|
|
50693
51309
|
const histBudget = ctx - sysBudget - resBudget;
|
|
50694
51310
|
row(t("repl.model"), pc.white(this.config.model));
|
|
50695
|
-
|
|
51311
|
+
const endpoint = activeProviderEndpoint(this.config.provider);
|
|
51312
|
+
row(t("repl.provider"), `${endpoint.type} → ${pc.dim(endpoint.baseUrl)}`);
|
|
50696
51313
|
row(t("repl.context"), `${pc.white(String(ctx))} ${pc.dim(`(sys:${sysBudget} res:${resBudget} hist:${histBudget})`)}`);
|
|
50697
51314
|
const si = this.agent.getSystemPromptInfo();
|
|
50698
51315
|
row(t("repl.sysprompt_label"), pc.dim(t("repl.sysprompt_size", { used: si.tokenCount, budget: sysBudget })));
|
|
@@ -51607,6 +52224,11 @@ function makeForwarder(s, sink = (ev) => broadcast(ev, s), opts = {}) {
|
|
|
51607
52224
|
schedule();
|
|
51608
52225
|
},
|
|
51609
52226
|
onMeta(chunk, kind) {
|
|
52227
|
+
if (kind === "retract") {
|
|
52228
|
+
flush();
|
|
52229
|
+
sink({ type: "retract", ts: Date.now(), reason: stripAnsi2(chunk) });
|
|
52230
|
+
return;
|
|
52231
|
+
}
|
|
51610
52232
|
const next = kind ?? "status";
|
|
51611
52233
|
if (buf.meta && (buf.metaKind ?? "status") !== next)
|
|
51612
52234
|
flush();
|
|
@@ -52290,6 +52912,9 @@ function handleSessionCreate(req, res, s) {
|
|
|
52290
52912
|
}
|
|
52291
52913
|
try {
|
|
52292
52914
|
const meta = create(name);
|
|
52915
|
+
try {
|
|
52916
|
+
s.execModule?.switchSession(meta.id);
|
|
52917
|
+
} catch {}
|
|
52293
52918
|
sendJson(res, 201, {
|
|
52294
52919
|
ok: true,
|
|
52295
52920
|
session: {
|
|
@@ -52330,6 +52955,9 @@ function handleSessionActivate(req, res, s) {
|
|
|
52330
52955
|
sendJson(res, 404, { error: "not_found" });
|
|
52331
52956
|
return;
|
|
52332
52957
|
}
|
|
52958
|
+
try {
|
|
52959
|
+
s.execModule?.switchSession(id);
|
|
52960
|
+
} catch {}
|
|
52333
52961
|
sendJson(res, 200, { ok: true });
|
|
52334
52962
|
}).catch((err) => {
|
|
52335
52963
|
readBodyError(req, res, err);
|
|
@@ -52354,6 +52982,9 @@ function handleSessionDelete(res, id, s) {
|
|
|
52354
52982
|
sendJson(res, 404, { error: "not_found" });
|
|
52355
52983
|
return;
|
|
52356
52984
|
}
|
|
52985
|
+
try {
|
|
52986
|
+
s.execModule?.forgetSession(id);
|
|
52987
|
+
} catch {}
|
|
52357
52988
|
sendJson(res, 200, { ok: true });
|
|
52358
52989
|
}
|
|
52359
52990
|
function handleSessionsApi(req, res, reqUrl, s) {
|
|
@@ -53408,9 +54039,11 @@ function servePreview(res, absReal, buf) {
|
|
|
53408
54039
|
|
|
53409
54040
|
// src/modules/webui/setup-api.ts
|
|
53410
54041
|
init_i18n();
|
|
54042
|
+
init_registry_extra();
|
|
53411
54043
|
init_apply();
|
|
53412
54044
|
init_answers();
|
|
53413
54045
|
init_discovery();
|
|
54046
|
+
init_provider_context();
|
|
53414
54047
|
function str3(rec, key) {
|
|
53415
54048
|
const v = rec[key];
|
|
53416
54049
|
return typeof v === "string" ? v.trim() : "";
|
|
@@ -53420,6 +54053,76 @@ function positiveInt(rec, key) {
|
|
|
53420
54053
|
const n = typeof v === "number" ? v : typeof v === "string" ? Number(v) : NaN;
|
|
53421
54054
|
return Number.isInteger(n) && n > 0 ? n : null;
|
|
53422
54055
|
}
|
|
54056
|
+
var SEVERITIES3 = ["low", "medium", "high", "critical"];
|
|
54057
|
+
var MAX_DETAIL_LIST = 200;
|
|
54058
|
+
var MAX_DETAIL_ITEM = 200;
|
|
54059
|
+
function strList(v) {
|
|
54060
|
+
if (!Array.isArray(v))
|
|
54061
|
+
return;
|
|
54062
|
+
const out = v.filter((x) => typeof x === "string").map((x) => x.trim()).filter((x) => x !== "" && x.length <= MAX_DETAIL_ITEM).slice(0, MAX_DETAIL_LIST);
|
|
54063
|
+
return out;
|
|
54064
|
+
}
|
|
54065
|
+
function optBool(v) {
|
|
54066
|
+
return typeof v === "boolean" ? v : undefined;
|
|
54067
|
+
}
|
|
54068
|
+
function optInt(v) {
|
|
54069
|
+
const n = typeof v === "number" ? v : typeof v === "string" ? Number(v) : NaN;
|
|
54070
|
+
return Number.isInteger(n) && n > 0 ? n : undefined;
|
|
54071
|
+
}
|
|
54072
|
+
function parseSecurityDetail(v) {
|
|
54073
|
+
if (!v || typeof v !== "object")
|
|
54074
|
+
return;
|
|
54075
|
+
const rec = v;
|
|
54076
|
+
const detail = {};
|
|
54077
|
+
const bash = rec.bash;
|
|
54078
|
+
if (bash && typeof bash === "object") {
|
|
54079
|
+
detail.bash = {
|
|
54080
|
+
blacklist: strList(bash.blacklist),
|
|
54081
|
+
whitelist: strList(bash.whitelist),
|
|
54082
|
+
logCommands: optBool(bash.logCommands)
|
|
54083
|
+
};
|
|
54084
|
+
}
|
|
54085
|
+
const paths = rec.paths;
|
|
54086
|
+
if (paths && typeof paths === "object") {
|
|
54087
|
+
detail.paths = { denied: strList(paths.denied), allowed: strList(paths.allowed) };
|
|
54088
|
+
}
|
|
54089
|
+
const flags = rec.flags;
|
|
54090
|
+
if (flags && typeof flags === "object") {
|
|
54091
|
+
detail.flags = {
|
|
54092
|
+
dangerousFlags: strList(flags.dangerousFlags),
|
|
54093
|
+
dangerousOperators: strList(flags.dangerousOperators)
|
|
54094
|
+
};
|
|
54095
|
+
}
|
|
54096
|
+
const network = rec.network;
|
|
54097
|
+
if (network && typeof network === "object") {
|
|
54098
|
+
detail.network = {
|
|
54099
|
+
enabled: optBool(network.enabled),
|
|
54100
|
+
deniedDomains: strList(network.deniedDomains),
|
|
54101
|
+
allowedDomains: strList(network.allowedDomains),
|
|
54102
|
+
requestTimeout: optInt(network.requestTimeout),
|
|
54103
|
+
maxResponseSize: optInt(network.maxResponseSize)
|
|
54104
|
+
};
|
|
54105
|
+
}
|
|
54106
|
+
const adv = rec.advanced;
|
|
54107
|
+
if (adv && typeof adv === "object") {
|
|
54108
|
+
const rawSev = adv.auditNotifierMinSeverity;
|
|
54109
|
+
const sev = typeof rawSev === "string" && SEVERITIES3.includes(rawSev) ? rawSev : undefined;
|
|
54110
|
+
detail.advanced = {
|
|
54111
|
+
maxRecursionDepth: optInt(adv.maxRecursionDepth),
|
|
54112
|
+
maxFileOperations: optInt(adv.maxFileOperations),
|
|
54113
|
+
maxRequestsPerMinute: optInt(adv.maxRequestsPerMinute),
|
|
54114
|
+
maxParallelTasks: optInt(adv.maxParallelTasks),
|
|
54115
|
+
contentScanEnabled: optBool(adv.contentScanEnabled),
|
|
54116
|
+
sessionEncryptionEnabled: optBool(adv.sessionEncryptionEnabled),
|
|
54117
|
+
auditNotifierEnabled: optBool(adv.auditNotifierEnabled),
|
|
54118
|
+
auditNotifierMinSeverity: sev,
|
|
54119
|
+
auditNotifierEventTypes: strList(adv.auditNotifierEventTypes)?.filter((e) => AUDIT_EVENT_TYPES.includes(e)),
|
|
54120
|
+
auditNotifierMaxRetries: optInt(adv.auditNotifierMaxRetries),
|
|
54121
|
+
auditNotifierWebhookTimeout: optInt(adv.auditNotifierWebhookTimeout)
|
|
54122
|
+
};
|
|
54123
|
+
}
|
|
54124
|
+
return detail;
|
|
54125
|
+
}
|
|
53423
54126
|
function parseSetupAnswers(rec) {
|
|
53424
54127
|
const provider = str3(rec, "provider");
|
|
53425
54128
|
const apiBase = str3(rec, "apiBase");
|
|
@@ -53449,15 +54152,17 @@ function parseSetupAnswers(rec) {
|
|
|
53449
54152
|
locale,
|
|
53450
54153
|
securityBashBlock: rec.securityBashBlock,
|
|
53451
54154
|
securityFlagsBlock: rec.securityFlagsBlock,
|
|
53452
|
-
securityPathsRestrict: rec.securityPathsRestrict
|
|
54155
|
+
securityPathsRestrict: rec.securityPathsRestrict,
|
|
54156
|
+
securityDetail: parseSecurityDetail(rec.securityDetail)
|
|
53453
54157
|
};
|
|
53454
54158
|
}
|
|
53455
54159
|
function handleSetupGet(res, s) {
|
|
54160
|
+
const defaults = s.setup?.defaults ?? { contextWindow: 0, maxToolIterations: 0 };
|
|
53456
54161
|
sendJson(res, 200, {
|
|
53457
54162
|
required: s.setupRequired,
|
|
53458
54163
|
languages: s.setup?.languages ?? [],
|
|
53459
54164
|
providers: s.setup?.providers ?? [],
|
|
53460
|
-
defaults: s.
|
|
54165
|
+
defaults: s.config?.security ? { ...defaults, security: securityDetailFromConfig(s.config.security) } : defaults
|
|
53461
54166
|
});
|
|
53462
54167
|
}
|
|
53463
54168
|
function handleSetupScan(req, res, s) {
|
|
@@ -53503,6 +54208,31 @@ function handleSetupTest(req, res, s) {
|
|
|
53503
54208
|
readBodyError(req, res, err);
|
|
53504
54209
|
});
|
|
53505
54210
|
}
|
|
54211
|
+
function handleSetupContext(req, res, s) {
|
|
54212
|
+
readJsonBody(req, s.maxBodyBytes).then(async (rec) => {
|
|
54213
|
+
if (!rec) {
|
|
54214
|
+
sendJson(res, 400, { ok: false, error: "invalid JSON" });
|
|
54215
|
+
return;
|
|
54216
|
+
}
|
|
54217
|
+
const baseUrl = str3(rec, "baseUrl");
|
|
54218
|
+
const model = str3(rec, "model");
|
|
54219
|
+
if (!baseUrl || !model) {
|
|
54220
|
+
sendJson(res, 400, { ok: false, error: "invalid-context-request" });
|
|
54221
|
+
return;
|
|
54222
|
+
}
|
|
54223
|
+
const probe = await probeProviderContext(baseUrl, model, {
|
|
54224
|
+
apiKey: str3(rec, "apiKey") || undefined,
|
|
54225
|
+
providerType: str3(rec, "providerType") || undefined
|
|
54226
|
+
});
|
|
54227
|
+
if (!probe) {
|
|
54228
|
+
sendJson(res, 200, { ok: false });
|
|
54229
|
+
return;
|
|
54230
|
+
}
|
|
54231
|
+
sendJson(res, 200, { ok: true, contextWindow: probe.actual, model: probe.model });
|
|
54232
|
+
}).catch((err) => {
|
|
54233
|
+
readBodyError(req, res, err);
|
|
54234
|
+
});
|
|
54235
|
+
}
|
|
53506
54236
|
function handleSetupLocale(req, res, s) {
|
|
53507
54237
|
readJsonBody(req, s.maxBodyBytes).then((rec) => {
|
|
53508
54238
|
if (!rec) {
|
|
@@ -53575,6 +54305,10 @@ function handleSetupApi(req, res, reqUrl, s) {
|
|
|
53575
54305
|
handleSetupTest(req, res, s);
|
|
53576
54306
|
return true;
|
|
53577
54307
|
}
|
|
54308
|
+
if (p === "/api/setup/context" && req.method === "POST") {
|
|
54309
|
+
handleSetupContext(req, res, s);
|
|
54310
|
+
return true;
|
|
54311
|
+
}
|
|
53578
54312
|
if (p === "/api/setup/locale" && req.method === "POST") {
|
|
53579
54313
|
handleSetupLocale(req, res, s);
|
|
53580
54314
|
return true;
|
|
@@ -53652,6 +54386,7 @@ var API_ROUTES = {
|
|
|
53652
54386
|
"GET /api/models": (_req, res, s) => handleModelsGet(res, s),
|
|
53653
54387
|
"POST /api/command": (req, res, s) => handleCommandPost(req, res, s),
|
|
53654
54388
|
"POST /api/interrupt": (_req, res, s) => handleInterruptPost(res, s),
|
|
54389
|
+
"POST /api/index": (_req, res, s) => handleIndexPost(res, s),
|
|
53655
54390
|
"POST /api/mcp": (req, res, s) => handleMcpCreate(req, res, s),
|
|
53656
54391
|
"GET /api/lsp": (_req, res, s) => handleLspGet(res, s)
|
|
53657
54392
|
};
|
|
@@ -53693,6 +54428,14 @@ function handleInterruptPost(res, s) {
|
|
|
53693
54428
|
s.bridge?.interrupt();
|
|
53694
54429
|
sendJson(res, 200, { ok: true });
|
|
53695
54430
|
}
|
|
54431
|
+
function handleIndexPost(res, s) {
|
|
54432
|
+
if (!s.refreshIndex) {
|
|
54433
|
+
sendJson(res, 503, { error: "unavailable" });
|
|
54434
|
+
return;
|
|
54435
|
+
}
|
|
54436
|
+
Promise.resolve(s.refreshIndex()).catch(() => {});
|
|
54437
|
+
sendJson(res, 202, { ok: true });
|
|
54438
|
+
}
|
|
53696
54439
|
function handleRequest(req, res, assets, s) {
|
|
53697
54440
|
let reqUrl;
|
|
53698
54441
|
try {
|
|
@@ -53947,13 +54690,22 @@ async function startWebUi(deps) {
|
|
|
53947
54690
|
state.setup = buildSetupDisplay();
|
|
53948
54691
|
state.config = deps.config;
|
|
53949
54692
|
state.sessionManager = deps.sessionManager;
|
|
54693
|
+
state.execModule = deps.execModule;
|
|
53950
54694
|
state.memory = deps.memory;
|
|
53951
54695
|
state.skills = deps.skills;
|
|
53952
54696
|
state.plugins = deps.plugins;
|
|
53953
54697
|
state.workspace = deps.baseDir;
|
|
53954
54698
|
state.agentsMd = deps.agentsMd;
|
|
53955
|
-
if (deps.indexer)
|
|
54699
|
+
if (deps.indexer) {
|
|
53956
54700
|
state.projectMapStats = () => deps.indexer?.stats() ?? null;
|
|
54701
|
+
if (deps.indexer.refresh) {
|
|
54702
|
+
const refresh = deps.indexer.refresh.bind(deps.indexer);
|
|
54703
|
+
state.refreshIndex = async () => {
|
|
54704
|
+
await refresh();
|
|
54705
|
+
broadcast({ type: "state", ts: Date.now(), busy: state.busy, usage: state.usage }, state);
|
|
54706
|
+
};
|
|
54707
|
+
}
|
|
54708
|
+
}
|
|
53957
54709
|
state.saveConfig = (config) => saveConfig(config, CONFIG_FILE, deps.configDir);
|
|
53958
54710
|
installWebPromptIO({
|
|
53959
54711
|
state,
|
|
@@ -53997,10 +54749,7 @@ async function startWebUi(deps) {
|
|
|
53997
54749
|
contextProbe: probe,
|
|
53998
54750
|
workspace: deps.baseDir,
|
|
53999
54751
|
instructions: deps.agentsMd,
|
|
54000
|
-
projectMap: (
|
|
54001
|
-
const s = deps.indexer?.stats();
|
|
54002
|
-
return s ? { indexed: true, ...s } : { indexed: false, files: 0, symbols: 0, tokens: 0 };
|
|
54003
|
-
})()
|
|
54752
|
+
projectMap: deps.indexer?.mapInfo?.()
|
|
54004
54753
|
}, state.busy),
|
|
54005
54754
|
addPendingImage: (url2) => {
|
|
54006
54755
|
deps.agent.contextManager?.addPendingImage?.({
|