Skip to content

[Feature]: add context editing trigger mechanism#209

Open
riturajFi wants to merge 13 commits intomemodb-io:devfrom
riturajFi:feat/context_editing
Open

[Feature]: add context editing trigger mechanism#209
riturajFi wants to merge 13 commits intomemodb-io:devfrom
riturajFi:feat/context_editing

Conversation

@riturajFi
Copy link
Contributor

Why we need this PR?

This should close Issue (#137 )

Describe your solution

Adds optional auto-trim to GET /session/{session_id}/messages using a token threshold and the remove_tool_result strategy. The API validates query params, the service trims messages when the threshold is met and returns auto-trim metadata, and the Python SDK exposes both the new request params and response fields.

Implementation Tasks

Please ensure your pull request meets the following requirements:

  • Confirm API schema for auto-trim query params and response metadata
  • Verify Python SDK sync + async methods accept new params and return new fields
  • Add or update tests for auto-trim behavior and error cases

Impact Areas

Which part of Acontext would this feature affect?

  • Client SDK (Python)
  • Client SDK (TypeScript)
  • Core Service
  • API Server
  • Dashboard
  • CLI Tool
  • Documentation
  • Other: ...

Checklist

  • Open your pull request against the dev branch.
  • All tests pass in available continuous integration systems (e.g., GitHub Actions).
  • Tests are added or modified as needed to cover code changes.

@riturajFi riturajFi changed the base branch from main to dev January 23, 2026 19:46
@riturajFi riturajFi marked this pull request as draft January 23, 2026 19:54
@riturajFi riturajFi marked this pull request as ready for review January 24, 2026 20:33
Copy link
Contributor

@slyt3 slyt3 left a comment

Choose a reason for hiding this comment

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

lgtm, just minor optimization would be nice, but it doesnt block functionality, but yeah it could improve performence and maintability. You can ignor this issues if @gusye1234

Comment on lines 494 to 498
originalTokens, err = tokenizer.CountMessagePartsTokens(ctx, out.Items)
// Return error if token counting fails.
if err != nil {
return nil, fmt.Errorf("failed to count tokens for auto-trim: %w", err)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

token counting run on EVERY get_message call when auto_trim config exsists, wont it will be expensive for a large message sets?

Comment on lines 532 to 536
// Count tokens after auto-trim to estimate removed tokens.
editedTokens, err := tokenizer.CountMessagePartsTokens(ctx, out.Items)
if err != nil {
return nil, fmt.Errorf("failed to count tokens after auto-trim: %w", err)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

second token counting operation, should be consider caching or optimization?

Comment on lines 508 to 513
// Skip auto-trim when strategy is not supported in v0.
if in.AutoTrim.Strategy != "remove_tool_result" {
// Record skip reason for unsupported strategy.
reason := "unsupported_strategy"
out.AutoTrimSkipped = true
out.AutoTrimSkipReason = &reason
Copy link
Contributor

Choose a reason for hiding this comment

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

use registry pattern for extensibility

Comment on lines 589 to 593
// Return 400 when strategy is not the only allowed value.
if strat != "remove_tool_result" {
c.JSON(http.StatusBadRequest, serializer.ParamErr("invalid auto_trim_strategy", errors.New("strategy must be remove_tool_result")))
return
}
Copy link
Contributor

Choose a reason for hiding this comment

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

same hardcoded validation in handle layer.

originalTokens, err = tokenizer.CountMessagePartsTokens(ctx, out.Items)
// Return error if token counting fails.
if err != nil {
return nil, fmt.Errorf("failed to count tokens for auto-trim: %w", err)
Copy link
Contributor

Choose a reason for hiding this comment

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

add error message it lacks session context for debugging.

same in line 535, not gonna comment same issuse just include in error message session ID for better debugging

Copy link
Contributor

@gusye1234 gusye1234 left a comment

Choose a reason for hiding this comment

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

I would discuss about the design, which may be two direction:

  1. trigger one editing strategy at a time.
  2. trigger the whole editing strategies.

trigger one editing strategy at a time

like https://platform.claude.com/docs/en/build-with-claude/context-editing#advanced-configuration. The trigger field should be in the strategy itself, like:

edit_strategies=[
        {"type": "token_limit", "params": {"limit_tokens": 20000}, "trigger": {"token_gt": 30000}},
        {"type": "remove_tool_use")
        ...
    ]

so that each editing method can be triggered independently, and that gives Acontext combinability. In this design, you don't need to add the new parameter in the same level with edit_strategies. you just need to add a general field to every strategy's parameter, and trigger them accordingly

trigger the whole editing strategies

or we can just use trigger to trigger the whole editing_strategies (which I prefer), like

edit_strategies=[
        {"type": "token_limit", "params": {"limit_tokens": 20000},},
        {"type": "remove_tool_use")
        ...
    ]
editing_trigger = {"token_gt": 30000}

I think this is more reasonable, after all, when everyone designs editing, they definitely hope it takes effect together.

Overall, I think the current sdk design a bit stuck in the middle, making it very inconvenient to use: I can only choose one trigger and one editing strategy at a time.

description="Estimated token reduction from auto-trim",
)
# auto_trim_skipped shows whether auto-trim was skipped.
auto_trim_skipped: bool | None = Field(
Copy link
Contributor

Choose a reason for hiding this comment

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

what's the difference bettwen auto_trim_applied and auto_trim_skipped?

Aren't these two always opposite booleans?

@riturajFi riturajFi force-pushed the feat/context_editing branch 3 times, most recently from 670b772 to dd285a4 Compare January 28, 2026 12:28
@GenerQAQ GenerQAQ force-pushed the dev branch 2 times, most recently from 0ca4326 to 64e00b9 Compare January 29, 2026 13:37
@riturajFi riturajFi force-pushed the feat/context_editing branch 2 times, most recently from 185b2cc to 06a47e1 Compare February 5, 2026 21:53
@slyt3
Copy link
Contributor

slyt3 commented Feb 6, 2026

I would love to see to be added tests for editing_trigger validation, gating behavior, and confirm pin+trigger semantics

@riturajFi riturajFi force-pushed the feat/context_editing branch from 06a47e1 to 03b6e85 Compare February 7, 2026 22:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants