Skip to content

feat(gateway): add context provider abstraction with LINE buffered context#1165

Open
iamninihuang wants to merge 2 commits into
openabdev:mainfrom
iamninihuang:feat/line-group-context-buffer
Open

feat(gateway): add context provider abstraction with LINE buffered context#1165
iamninihuang wants to merge 2 commits into
openabdev:mainfrom
iamninihuang:feat/line-group-context-buffer

Conversation

@iamninihuang

@iamninihuang iamninihuang commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR refactors the original LINE-only group context buffer into a gateway-level ContextProvider foundation, with LINE using the first buffered implementation.

Problem: mention-gated chatrooms can lose the conversation that happened before someone finally mentions the bot. LINE cannot fetch historical group messages from the platform API, so the only practical way to recover that context is to observe recent non-triggering messages locally and inject them when the bot is mentioned.

What changed:

  • Add gateway/src/context/ with ContextProvider, ContextScope, ContextMessage, config, and shared context injection formatting.
  • Add BufferedContextProvider for webhook-observed platforms such as LINE, Telegram, WeChat/WeCom, and fallback cases.
  • Add an ApiFetchContextProvider skeleton for platforms that can fetch history from native APIs such as Discord, Slack, Teams, or Google Chat spaces.
  • Wire LINE group/room text messages through the provider registry.
  • Keep mention gating behavior: non-mentioned LINE group messages are observed only; they are not dispatched to the bot.
  • Document the gateway context provider model and LINE-specific configuration.

Prior Art And Design Input

Community discussion: https://discord.com/channels/1491295327620169908/1517816542610460825

This design follows the direction suggested by Pahud: make the feature cross-platform instead of LINE-only.

Observed prior art:

  • OpenClaw uses a local pending-message buffer and injects recent non-triggering group messages before the current trigger.
  • Hermes uses platform API history backfill for Discord, which works well where the platform exposes channel history.
  • LINE does not expose equivalent group history fetch APIs, so a bounded local buffer is required there.
  • Google Chat likely needs a hybrid model: native API where available, buffer fallback for 1:1/private/admin-limited cases.

Scope

Included:

  • Gateway ContextProvider trait and shared data types.
  • In-memory bounded buffered provider.
  • Shared context injection format.
  • LINE group/room integration as the first concrete provider user.
  • Configurable enable flag, TTL, max messages, max chars, and bot id scoping.
  • Docs and unit tests.

Not included:

  • Persistent storage.
  • Agent memory/GBrain integration.
  • Manual /history100 command syntax.
  • Full API-backed implementations for Discord/Slack/Teams/Google Chat.
  • Changing existing mention admission behavior.

Configuration

Defaults are intentionally conservative:

  • enabled = false
  • ttl = 24h
  • max_messages = 50
  • max_chars = 8000

LINE-specific env vars can override gateway defaults:

  • LINE_GROUP_CONTEXT_ENABLED
  • LINE_GROUP_CONTEXT_TTL_HOURS
  • LINE_GROUP_CONTEXT_MAX_MESSAGES
  • LINE_GROUP_CONTEXT_MAX_CHARS
  • LINE_CONTEXT_BOT_ID

Before / After

Before:

  • In a LINE group, messages without a bot mention were dropped before dispatch.
  • When someone later mentioned the bot, the bot only saw the triggering message.

After:

  • Non-mentioned LINE group messages are observed into a bounded per-scope buffer.
  • When the bot is mentioned, recent buffered context is injected before the current message.
  • The buffer is drained after injection to avoid repeatedly re-injecting the same context.

Testing

Ran locally in gateway:

  • cargo test - 272 passed
  • cargo clippy -- -D warnings - passed

Covered by tests:

  • Context injection formatting.
  • Buffered provider observe/fetch/drain behavior.
  • Disabled provider no-op behavior.
  • Max messages and max chars trimming.
  • Scope isolation across chats/bots.
  • LINE group buffering when not mentioned.
  • LINE context injection on later mention.
  • Existing LINE image/audio attachment tests still pass.

@openab-app openab-app Bot added closing-soon PR missing Discord Discussion URL — will auto-close in 24 hours. and removed closing-soon PR missing Discord Discussion URL — will auto-close in 24 hours. labels Jun 20, 2026
@iamninihuang iamninihuang marked this pull request as ready for review June 20, 2026 09:11
@iamninihuang iamninihuang requested a review from thepagent as a code owner June 20, 2026 09:11
@chaodu-agent

This comment has been minimized.

@chaodu-agent

This comment was marked as outdated.

@thepagent

thepagent commented Jun 20, 2026

Copy link
Copy Markdown
Collaborator

per discussion here https://discord.com/channels/1491295327620169908/1517915941269147850/1517919091363545169 let's consider to build an all-platform context provider feature instead of LINE only.

@iamninihuang iamninihuang force-pushed the feat/line-group-context-buffer branch from 35125ce to 51af031 Compare June 20, 2026 16:25
@iamninihuang iamninihuang changed the title feat(line): add opt-in group context buffering feat(gateway): add context provider abstraction with LINE buffered context Jun 20, 2026
@iamninihuang

Copy link
Copy Markdown
Contributor Author

Updated this PR based on the cross-platform direction discussed in Discord.

Main changes:

  • Refactored the LINE-only buffer into a gateway-level ContextProvider abstraction.
  • Added BufferedContextProvider as the first implementation.
  • Kept LINE as the first concrete integration.
  • Added docs for the shared gateway context model and LINE config.
  • Added tests for provider behavior, scope isolation, bounded context, and LINE injection.

Local validation:

  • cargo test: 272 passed
  • cargo clippy -- -D warnings: passed
  • Local LINE group test passed:
    • non-mentioned message was buffered
    • later @bot injected buffered_messages=1
    • response used Reply API when replyToken was still valid

This keeps the current PR useful for LINE while leaving Discord/Slack/Teams/Google Chat API-backed providers as follow-up work.

@chaodu-agent

Copy link
Copy Markdown
Collaborator

LGTM ✅ — Well-structured context provider abstraction with solid test coverage and conservative defaults.

What This PR Does

Solves the "lost context" problem in mention-gated group chats (especially LINE) by adding a gateway-level ContextProvider trait with a bounded in-memory buffer implementation. When the bot is finally @-mentioned, recent unmentioned text is injected as conversational context.

How It Works

  • New gateway/src/context/ module with ContextProvider trait, BufferedContextProvider, config, and shared injection formatting.
  • LINE adapter observes unmentioned group text into a per-scope buffer; drains and prepends on the next direct mention.
  • Scoped by platform + channel + bot_id. TTL expiry, message count, and char limits prevent unbounded growth.
  • Feature is opt-in (enabled = false by default) with platform-specific env var overrides.

Findings

# Severity Finding Location
1 🟢 Clean trait-based abstraction enables future API-fetch and hybrid providers without changing the injection format context/mod.rs
2 🟢 Comprehensive test suite covers observe/fetch/drain, scope isolation, ordering, max bounds, and cross-chat leakage prevention adapters/line.rs tests
3 🟢 Conservative defaults (disabled, 50 msgs, 8K chars, 24h TTL) and env-var layering (platform-specific falls back to gateway-wide) context/config.rs
4 🟢 std::sync::Mutex is correct here — lock is never held across .await points, short critical sections only context/buffered.rs
What's Good (🟢)
  • The trait boundary between buffered and API-fetch providers is well-thought-out — new platforms can slot in without touching the injection logic.
  • Drain-after-injection prevents stale re-injection and keeps memory bounded for active chats.
  • Individual message text is bounded on insert (chars().take(max_chars)) as defense-in-depth.
  • Tests exercise the full lifecycle including multi-message ordering, cross-chat isolation, and post-drain emptiness.
  • Documentation updates in both docs/line.md and new docs/gateway-context.md are clear and complete.
  • Existing tests (image/audio attachments) updated cleanly to pass the new parameters.
Baseline Check
  • PR opened: 2026-06-20
  • Main already has: LINE mention-gating (drop unmentioned group messages), no context buffering
  • Net-new value: Gateway-level ContextProvider trait + BufferedContextProvider + LINE integration + docs + comprehensive tests

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants