Skip to content

feat: manual context compression - #9795

Open
C10H14N2O5 wants to merge 13 commits into
AstrBotDevs:masterfrom
C10H14N2O5:feat/manual-context-compression
Open

feat: manual context compression#9795
C10H14N2O5 wants to merge 13 commits into
AstrBotDevs:masterfrom
C10H14N2O5:feat/manual-context-compression

Conversation

@C10H14N2O5

@C10H14N2O5 C10H14N2O5 commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

TL;DR

  • Add a /compact command for the local Agent Runner so users can explicitly request LLM-based context compression before the automatic threshold is reached.
  • Add an opt-in Manual Context Compression (Experimental) setting, disabled by default and shown only for local + llm_compress configurations.
  • Reuse the existing context compressor, token estimator, provider resolution, and persisted history format without adding a ChatUI button, backend API, database migration, or remote-runner compatibility layer.
  • Keep the original history when manual compression fails, returns an empty or unchanged result, or does not reduce the estimated token count; manual compression never invokes the automatic half-truncation fallback.
  • Acquire the same per-session lock as normal local Agent requests and revalidate the conversation ID, history, and stop state before persistence.
  • Keep WebChat progress transient while updating the context ring immediately after a successful compression: connected clients see concise progress and completion states, durable history stores only the terminal result, and the generated summary is never exposed.
  • Add focused regression coverage for forced compression, command gates, permissions, checkpoints, concurrency conflicts, database verification, log privacy, and provider resolution, together with real WebUI and provider-backed manual verification.

Background

Fixes #9281

Related to #8348 and #9252, but intentionally does not implement configurable automatic compression thresholds.

AstrBot already supports automatic context management through maximum-turn enforcement and a token-threshold safeguard. When a request approaches the model context-window limit, ContextManager can summarize the history with an LLM or truncate it by conversation turns. However, token-triggered compression does not run until its threshold is reached. With models offering 512K, 1M, or larger context windows, users may encounter practical degradation far below the current 82% threshold:

  • Agent tool calls can accumulate large intermediate outputs with little long-term value.
  • Important task goals can become diluted by details in a long-running conversation.
  • A completed project phase may be worth summarizing before the next phase begins.
  • Re-sending a large history on every request increases latency, token consumption, and API cost.
  • Users should not need to misrepresent a model's context-window size merely to trigger compression earlier.

This PR adds the manual /compact workflow available in other agent harnesses. It lets users request compression at an appropriate point without changing AstrBot's automatic threshold or existing automatic behavior.

The first version uses a command instead of a dedicated ChatUI button. AstrBot's command system already provides registration, autocomplete, enable/disable controls, renaming, and permission management. Reusing it keeps the patch reviewable while supporting WebChat and other messaging platforms without a new API or UI component.

Because an LLM-generated summary may omit role state, narrative facts, or task details, this capability is marked experimental and remains disabled by default. Users must explicitly opt in before the command can run.


Modifications / 改动点

1. /compact user command

Register /compact in the built-in command plugin and reuse the existing command-management behavior:

  • The command can be disabled, renamed, or permission-restricted under Plugins → Manage Behaviors.
  • Regular members may use it in direct messages and group chats with per-member sessions enabled.
  • Shared group conversations require administrator permission, preventing regular members from changing context shared by the entire group.
  • The command rejects execution when AI features are disabled.
  • The command rejects execution when manual context compression is disabled.
  • The command rejects non-local Agent Runners.
  • The command requires the llm_compress context strategy.
  • Missing conversations or unavailable compression providers produce explicit errors.

The live user-visible flow remains intentionally concise:

⏳ Compressing context...
✅ Context compressed.

The generated summary is never printed into the chat. WebChat additionally receives an agent_stats event so the context ring immediately reflects the estimated size of the compressed history.

WebChat marks the progress status as ephemeral. The live client replaces it with the terminal result, while persisted history after a successful run contains only:

user: /compact
astrbot: ✅ Context compressed.

2. Opt-in experimental setting

Add the following configuration value:

{
  "agent_runner": {
    "runner_type": "local",
    "config": {
      "compression": {
        "enable_manual_context_compression": false
      }
    }
  }
}

Configuration behavior:

  • The default is false, so upgrading does not silently enable the feature for existing users.
  • The setting is part of the normalized local Agent Runner compression config and survives save, reload, and profile round trips.
  • The setting is visible only when agent_runner.runner_type=local and agent_runner.config.compression.overflow_strategy=llm_compress.
  • Selecting another compression strategy hides the setting without changing its value.
  • Switching to another runner replaces the local runner config; switching back loads local defaults and resets the setting to false, matching the embedded-runner semantics introduced by refactor: embed agent runner configuration in profiles #9821.
  • Legacy provider_settings.enable_manual_context_compression values are migrated into the embedded local compression config during the existing v2-to-v3 migration.
  • Chinese, English, and Russian configuration metadata include localized labels and risk guidance.
  • No database field, configuration-version bump, frontend component, or generated API client change is introduced.

3. Reuse the existing compression flow

Add an optional force_compress argument to ContextManager.process(). Its default remains false, preserving all existing automatic callers.

With force_compress=True, the manual command:

  • bypasses the 82% automatic token threshold;
  • bypasses the maximum-turn gate;
  • does not depend on model-metadata context-window values;
  • ignores provider-reported token usage that is relevant only to the automatic request path;
  • reuses _run_compression(), the existing TokenCounter, and the LLM summary compressor; and
  • explicitly disables the post-summary half-truncation fallback.

Automatic compression retains its existing half-truncation protection. Only the manual path disables that fallback so a failed /compact operation cannot destructively truncate the original history.

4. Preserve the latest complete turn

Add an optional preserve_latest_round behavior to the LLM summary compressor. It defaults to disabled and therefore does not alter automatic compression output.

When enabled by manual compression:

  • the latest complete user-assistant turn is always preserved verbatim;
  • any incomplete user request or other content following that turn is preserved;
  • a zero-token estimate cannot move the protected latest turn into the summary input;
  • a conversation with only one complete user-assistant turn does not call the provider and reports insufficient history; and
  • additional recent complete turns are retained according to agent_runner.config.compression.keep_recent_ratio, without splitting logical turns.

This reduces the risk of changing the user's most recent requirements, tool state, or editable response.

5. Checkpoint-aware history persistence

The manual command reads the persisted database history and uses the existing checkpoint utilities during conversion:

  • bind_checkpoint_messages() associates persisted checkpoints with their messages.
  • dump_messages_with_checkpoints() serializes the compressed result.
  • Checkpoints belonging to summarized historical turns are removed with those messages.
  • Checkpoints on the preserved latest turn remain available, keeping WebChat edit and regenerate behavior functional.
  • Runtime-only persona, tool, and safety prompts are not persisted and are injected again through the normal request path.

6. Token-benefit validation and non-destructive failure

Estimate tokens both before and after compression:

  • Persistence occurs only when the estimated token count is strictly lower after compression.
  • Provider failures preserve the original history.
  • Empty summaries preserve the original history.
  • Unchanged compressor output preserves the original history.
  • Compressed histories that do not reduce the total estimated token count preserve the original history.
  • Manual compression never invokes half-truncation merely because the result still exceeds the automatic threshold.

On success, the compressed history and token_usage=0 are saved in the same database update. The next normal model response refreshes token state using the provider's actual usage information.

7. Session locking, concurrency revalidation, and stop handling

/compact acquires the same unified-message-origin (UMO) session lock used by normal local Agent requests:

  • It does not stop a running Agent request.
  • If the same session already has an active Agent request, compression waits until that request has persisted its complete result.
  • Different sessions can compact concurrently because their locks are independent.
  • After acquiring the lock, the command reloads the current conversation ID and database history.
  • After the summary request, it reloads the active conversation ID and persisted history again.
  • If the user switches conversations, runs /new, or modifies the same history through the Dashboard/API, the result is discarded.
  • The stop state is checked again immediately before persistence.
  • A WebChat /stop request prevents the compressed result from being written and explicitly reports that the original history was preserved.

Dashboard and API history updates do not acquire this session lock. The additional conversation-ID and history comparisons therefore protect against external changes that occur while the LLM summary is being generated.

8. Safe verification after database exceptions

If update_conversation() raises an exception, the command does not immediately assume that persistence failed. It safely reloads the database state once:

  • If the stored history already equals the target history, the write actually completed and the command continues as successful.
  • If the stored history remains equal to the original history, the command reports failure and confirms preservation.
  • If the stored history is a third state, the command reports an unknown context state and asks the user to inspect it before retrying.
  • If verification itself fails, the command reports the same unknown state.

This covers cases where a database update commits successfully but the client still receives an exception.

9. WebChat statistics, transient progress, and log privacy

  • WebChat progress uses the internal webchat_ephemeral chain type and remains visible to connected clients.
  • Dashboard SSE keeps the progress state in its active-run display snapshot but excludes it from the persistence accumulator.
  • Dashboard WebSocket and OpenAPI WebSocket forward the progress state without adding it to their persistence accumulators.
  • Success, failure, cancellation, and unknown-state terminal messages remain durable; page refreshes and service restarts retain the user command and one terminal bot message.
  • The agent_stats event is sent on a best-effort basis after persistence and after leaving the session lock.
  • A statistics-delivery failure does not roll back history or misreport the completed compression as a failure.
  • Platforms other than WebChat do not receive this event.
  • New exception logs contain only fixed messages and exception types.
  • Exception text, tracebacks, conversation history, and UMO identifiers are not logged, preventing provider or database errors from exposing sensitive context.

10. Reuse provider resolution

Refactor the existing context-compression provider resolver so both normal Agent construction and /compact can call it without changing its selection semantics:

  1. Prefer the explicitly configured compression provider.
  2. If that provider is unavailable, retain the existing fallback to the current session's chat provider.
  3. If no compression provider ID is configured, use the current session's chat provider.
  4. Reject compression when no provider is available.

Existing automatic compression provider selection remains unchanged.


Scope and Compatibility

This PR intentionally keeps the following boundaries:

  • The implementation is aligned with the embedded Agent Runner configuration introduced by refactor: embed agent runner configuration in profiles #9821.

  • Only AstrBot's built-in local Agent Runner is supported.

  • Dify, Coze, Alibaba Cloud Bailian, DeerFlow, and other remote runners own their context remotely; this PR does not attempt to rewrite remote history.

  • No dedicated Compress now ChatUI button is added.

  • No backend API or OpenAPI schema is added.

  • The automatic 82% compression threshold is unchanged.

  • The configurable automatic token thresholds proposed in [Feature]Token-Threshold Context Compression #8348 and [Feature] 上下文压缩阈值可配置化 #9252 are out of scope.

  • The generated summary is not exposed in chat.

  • No dependency or lockfile is changed.

  • No database schema is changed.

  • Existing legacy manual-compression values are migrated into the embedded local runner config; missing values remain disabled.

  • Default behavior for all existing automatic compression callers remains unchanged.

  • This is NOT a breaking change. / 这不是一个破坏性变更。


Changed Files and Size

This PR changes 26 tracked files relative to fe3d77568b88ea3be83b2190d515da0a039da399:

Area File Purpose
Command astrbot/builtin_stars/builtin_commands/commands/conversation.py /compact gates, locking, compression, persistence, and feedback
Registration astrbot/builtin_stars/builtin_commands/main.py Register /compact
Compression core astrbot/core/agent/context/compressor.py Preserve the latest complete turn and sanitize error logging
Context configuration astrbot/core/agent/context/config.py Add the optional latest-turn preservation setting
Context manager astrbot/core/agent/context/manager.py Forced compression and manual-mode half-truncation control
Token counting astrbot/core/agent/context/token_counter.py Preserve the upstream trusted-usage entry point while isolating the internal reported-usage threshold input from estimated compression metrics
Provider resolution astrbot/core/astr_main_agent.py Share the existing compression-provider resolver
Agent Runner configuration astrbot/core/config/agent_runner.py Normalize the opt-in flag in local compression config
Legacy migration astrbot/core/utils/migra_helper.py Preserve and migrate the old manual-compression value
Configuration metadata astrbot/core/config/default.py Conditional metadata for the embedded compression config
WebChat transport Three Dashboard service files Forward transient progress without persisting it across SSE and WebSocket consumers
Dashboard i18n Three config-metadata.json files Chinese, English, and Russian labels and risk guidance
Tests Ten test files Compression, token counting, command, provider, config migration/profile, SSE, and WebSocket regressions

Patch size:

26 files changed, 1609 insertions(+), 64 deletions(-)

Production Python (13 files): +407 / -45, net +362 lines
Dashboard locale metadata (3 files): +12 / -0, net +12 lines
Tests (10 files): +1190 / -19, net +1171 lines

Most added lines are regression tests. The implementation adds no remote-runner compatibility layer, UI component, or dependency.


Screenshots or Test Results / 运行截图或测试结果

Test Environment

  • Windows 11 Home 64-bit
  • DisplayVersion: 25H2
  • Build: 26200.9168
  • Python: 3.12
  • Node.js: 24.16.0
  • pnpm: 11.19.0
  • PowerShell: 7.6.4
  • Upstream baseline: fe3d77568b88ea3be83b2190d515da0a039da399 (#9821)
  • Tested state: 6e2bf2b559f75afa665e5d71346b2062c84bca85

Verification Steps

  1. Select the local Agent Runner, choose llm_compress under its embedded compression config, and enable Manual Context Compression (Experimental).
  2. Build the Dashboard and run the related Python regression suites listed below.
  3. Create a conversation with multiple complete turns and run /compact while the context is below the automatic 82% threshold.
  4. Verify the progress/completion messages, the reduced context ring, preserved visible WebChat history, and continued recall on the next turn.
  5. Exercise failure, concurrency, stop, permission, migration, normalization, profile, and runner-switch gates and confirm that unsuccessful operations preserve the original history.

Feature Regression

The final feature-related run covers context management, token counting, /compact, the Tool Loop runner, provider resolution, session locking, checkpoints, Dashboard SSE, Dashboard WebSocket, and OpenAPI WebSocket:

uv run pytest -p no:cacheprovider -q tests/agent/test_context_manager.py tests/agent/test_token_counter.py tests/test_conversation_commands.py tests/test_tool_loop_agent_runner.py tests/unit/test_astr_main_agent.py tests/unit/test_session_lock.py tests/test_conversation_checkpoint.py tests/test_chat_route.py tests/unit/test_live_chat_service.py tests/unit/test_open_api_service_ws.py

Result:

305 passed, 1 warning in 8.21s

This includes automatic compression behavior, forced compression without half truncation, latest-round and checkpoint preservation, all command gates, provider failures, token-benefit checks, stop handling, concurrent history changes, database verification states, log privacy, transient progress, durable terminal results, context statistics, and the streaming-disconnect persistence regression.

Embedded Agent Runner Configuration Regression

The #9821 configuration and lifecycle suites were run against the adapted implementation:

uv run pytest -p no:cacheprovider -q tests/unit/test_agent_runner_config.py tests/unit/test_config_profile_service.py tests/unit/test_config.py tests/unit/test_astr_agent_tool_exec.py tests/unit/test_core_lifecycle.py tests/unit/test_cron_manager.py tests/unit/test_third_party_agent_sub_stage.py

Result:

165 passed, 2 warnings in 9.85s

These tests cover normalization, local defaults, legacy migration, config save/load, profile round trips, runner switching, metadata conversion, and all three locale resources. A dedicated regression fixture represents a pre-feature v2 default local-runner root without the new boolean field, preventing legacy Agent Runner settings from being discarded during migration.

Token Metrics Regression

Focused compatibility coverage for the current token-usage boundary:

Context manager, token counter, and Local Tool Loop Agent Runner: 108 passed
Agent Runner normalization and migration: 24 passed

The Tool Loop and ContextManager.process() retain the upstream trusted_token_usage interface. ContextManager passes that value to TokenCounter only as reported_token_usage for the automatic compression threshold calculation. Once compression is triggered, the logged before/after metrics use independent estimates from the actual message lists and do not inherit provider-reported usage. The forced manual path uses local estimates throughout.

Full Repository Regression

uv run pytest -p no:cacheprovider -q tests

Result on Windows:

2240 passed, 1 skipped, 32 failed, 27 warnings in 197.63s

The 32 failures are in Windows-specific path separator, CRLF, symlink, local shell, file URI, and sandbox skill tests. None of the 15 failing test files is changed by this PR, their intersection with the 26-file PR diff is zero, and no related production path appears in the diff. All suites covering files changed by this PR pass as listed above.

Formatting and Static Checks

uv run ruff format --check .
502 files already formatted

uv run ruff check .
All checks passed!

git diff --check upstream/master...HEAD
No whitespace errors

All three Chinese, English, and Russian config-metadata.json files were also validated as parseable JSON.

GitHub CI

All current checks passed on 6e2bf2b559f75afa665e5d71346b2062c84bca85, including the Python CodeQL analysis and final CodeQL gate, the full unit-test job, Dashboard build, formatting, and the 15-job Python 3.10–3.14 smoke-test matrix across Ubuntu, macOS, and Windows.

Dashboard Production Build

The three commands in the Dashboard build script were run directly against the installed dependencies so pnpm 11 would not rewrite the repository's existing lockfile:

node scripts/subset-mdi-font.mjs
node_modules/.bin/vue-tsc --noEmit
node_modules/.bin/vite build

Result:

3804 modules transformed
✓ built in 40.47s
Exit code: 0

Manual WebUI and Runtime Verification

The final rebased checkout was launched with main.py --webui-dir dashboard/dist and the manual WebUI/E2E flow passed. The embedded local compression setting saved and reloaded correctly, localized labels rendered without raw i18n keys, /compact completed successfully, transient progress was not persisted, the context ring updated, and page refresh preserved only the command plus one terminal result.

One successful run recorded:

Compress completed. 7418 -> 3813 tokens.
✅ Context compressed.

Both automatic and forced compression paths retain their token-change logs:

Compress completed. 100 -> 6 tokens, compression rate: 6.00%.
Compress completed. 10 -> 10 tokens.

Observed behavior:

WebChat compression and Context Ring change

压缩示例-1 压缩ring估算

QQ Official Bot

手机运行 00_00_00-00_00_30
Failure preserves the original history

The compression prompt was temporarily changed to request expansion, verifying that output without a token reduction is never persisted:

Compress completed. 11454 -> 11473 tokens.
❌ Context compression failed; the original context was preserved.

The following failure paths were also verified:

  • invalid API key or unreachable provider;
  • both the current chat provider and dedicated compression provider unavailable;
  • only one complete user-assistant turn;
  • manual compression disabled;
  • global AI setting disabled; and
  • strategy changed to turn-based truncation.

None of these tested paths reduced the context ring, half-truncated history, or damaged subsequent recall.

Original history and Context Ring remain unchanged after failure

image
Session isolation and concurrency
  • Compacting session A left session B's context ring and history unchanged.
  • Sessions A and B could compact concurrently without blocking each other.
  • Repeating /compact twice in the same session did not restore stale history or drop the latest turn.
  • When the same session had a slow Agent response, /compact waited for it and then compressed history containing the completed response.
  • Running /new or modifying history through another entry point during compression prevented persistence:
⚠️ Context changed during compression; no changes were saved.
Stop behavior

A WebChat stop request cannot immediately cancel every in-flight provider request, but it prevents the result from being persisted. After the provider returned, the command reported:

⚠️ Compression cancelled; original context was preserved.

History and the context ring remained unchanged. This protects persisted state, although a slow provider request may still run to completion and incur cost, as noted under Known Limitations.

Configuration and i18n
  • The setting is disabled by default.
  • Its value persists after saving and refreshing.
  • Switching to turn-based truncation hides the setting; switching back restores the saved value.
  • Switching to a remote runner replaces the local runner config; switching back to local restores local defaults with manual compression disabled.
  • Disabling the global AI setting hides the section.
  • The saved configuration JSON contains agent_runner.config.compression.enable_manual_context_compression.
  • The current dashboard/dist was used to verify the Chinese, English, and Russian labels and risk guidance, with no raw i18n keys shown.
  • The displayed titles were 手动上下文压缩(实验性), Manual Context Compression (Experimental), and Ручное сжатие контекста (экспериментальная функция), with complete localized risk guidance in each language.

Observed configuration:

Simplified Chinese (zh-CN)

配置1

English (en-US)

配置2

Russian (ru-RU)

配置3

Known Limitations

  • Only the local Agent Runner is supported; remote runners manage their context externally.
  • A WebChat stop request prevents persistence but cannot guarantee immediate cancellation of every provider HTTP request.
  • The context ring uses an estimate from the compressed history until the next normal model response updates it with actual provider usage.
  • Like other callers of ConversationManager.update_conversation(), the final update is not a database-level compare-and-swap. This path mitigates concurrent changes by re-reading and comparing the active conversation and persisted history immediately before the update.

Checklist / 检查清单

  • 😊 If there are new features added in the PR, I have discussed it with the authors through issues/emails, etc.
    / 如果 PR 中有新加入的功能,已经通过 Issue / 邮件等方式和作者讨论过。

  • 👀 My changes have been well-tested, and "Verification Steps" and "Screenshots" have been provided above.
    / 我的更改经过了良好的测试,并已在上方提供了“验证步骤”和“运行截图”

  • 🤓 I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations in requirements.txt and pyproject.toml.
    / 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到 requirements.txtpyproject.toml 文件相应位置。

  • 😮 My changes do not introduce malicious code.
    / 我的更改没有引入恶意代码。


Summary by Sourcery

Enable users to safely request experimental manual LLM-based context compression for local conversations through the /compact command.

New Features:

  • Add an opt-in /compact command for manually compressing local Agent Runner conversation context with an LLM.
  • Add conditional, localized configuration for experimental manual context compression.
  • Preserve recent conversation state, checkpoints, and user-visible history while reporting updated WebChat context statistics.

Bug Fixes:

  • Prevent failed, ineffective, cancelled, or conflicting manual compression attempts from overwriting the original conversation history.
  • Avoid exposing sensitive provider, database, or conversation details in compression error logs.
  • Verify conversation state after storage exceptions to distinguish successful writes from preserved or unknown states.

Enhancements:

  • Extend context processing and provider resolution to support forced compression while preserving existing automatic compression behavior.
  • Add session locking and concurrency revalidation for manual compression requests.

Tests:

  • Add regression coverage for compression behavior, command permissions and gates, provider resolution, configuration migration, checkpoints, concurrency, persistence verification, logging privacy, and transient WebChat progress.

Comment thread astrbot/core/agent/context/manager.py Fixed
Comment thread astrbot/core/agent/context/manager.py Fixed
@C10H14N2O5
C10H14N2O5 marked this pull request as ready for review August 24, 2026 11:35
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. area:core The bug / feature is about astrbot's core, backend area:provider The bug / feature is about AI Provider, Models, LLM Agent, LLM Agent Runner. labels Aug 24, 2026

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="astrbot/builtin_stars/builtin_commands/commands/conversation.py" line_range="311" />
<code_context>
+                "❌ Context compression requires admin permission in a shared "
+                "group conversation."
+            )
+            return
+
+        if not provider_settings.get("enable", True):
</code_context>
<issue_to_address>
**issue (bug_risk):** When the compact event is stopped before or after the provider call, the command returns immediately after sending the transient progress message and never sets a terminal result. WebChat therefore retains or clears the progress state without receiving the documented cancellation message, leaving the user without an explicit outcome.

**Triggers:** When `/stop` marks the compact event itself as stopped.

**Suggested fix:** Call `reply(cancelled)` before returning from both `message.is_stopped()` branches, unless the surrounding transport explicitly guarantees a terminal response for stopped events.
</issue_to_address>

Sourcery assessment

Needs a human reviewer. 1 finding to address first, and /compact replaces persisted conversation history with an LLM-generated summary, permanently discarding older exact messages; reverting the code would not restore histories already compressed. The impact is limited to opted-in conversations and requires an explicit command, but an incorrect summary or authorization check could still cause unrecoverable context loss.

Blocking findings: astrbot/builtin_stars/builtin_commands/commands/conversation.py:311


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread astrbot/builtin_stars/builtin_commands/commands/conversation.py
@C10H14N2O5

Copy link
Copy Markdown
Contributor Author

Hi @Soulter, when you have time, could you please take a quick look at whether the feature direction of this PR fits AstrBot’s current roadmap? I’m mainly looking for direction-level feedback before further iteration; no rush on the detailed review. Thanks!

@C10H14N2O5
C10H14N2O5 marked this pull request as draft August 30, 2026 08:02
@C10H14N2O5

Copy link
Copy Markdown
Contributor Author

I'll resolve the existing merge conflicts and adapt this PR to the latest Agent Runner configuration changes in #9821, then mark it ready for review again.

@C10H14N2O5
C10H14N2O5 force-pushed the feat/manual-context-compression branch from 78915fc to 77cdaa1 Compare August 30, 2026 12:06
@C10H14N2O5
C10H14N2O5 marked this pull request as ready for review August 30, 2026 13:56

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!

Sourcery assessment

Needs a human reviewer. The command permanently overwrites a conversation's persisted history with an LLM summary, so omitted details cannot be recovered by reverting the code and may require manual reconstruction. The impact is bounded to conversations where an administrator or user explicitly enables and invokes the feature, rather than affecting all conversations by default.


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:core The bug / feature is about astrbot's core, backend area:provider The bug / feature is about AI Provider, Models, LLM Agent, LLM Agent Runner. size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] 增加手动触发上下文压缩的 /compact 指令或 ChatUI 按钮

2 participants