Skip to content

feat: Phase 4+6 — patterns pagination, confidence fix, HEARTBEAT filter#29

Merged
thebtf merged 3 commits into
mainfrom
feat/v1.1-phase4-graph-patterns
Mar 20, 2026
Merged

feat: Phase 4+6 — patterns pagination, confidence fix, HEARTBEAT filter#29
thebtf merged 3 commits into
mainfrom
feat/v1.1-phase4-graph-patterns

Conversation

@thebtf
Copy link
Copy Markdown
Owner

@thebtf thebtf commented Mar 20, 2026

Summary

  • T018: Patterns page server-side pagination + confidence formula ceiling fix (0.9→1.0)
  • T039: HEARTBEAT prompt filter in openclaw-engram before-prompt-build hook

Changes

Backend (Go)

  • pattern_store.go: GetActivePatterns(ctx, limit, offset, sort) — DB-level pagination+sorting
  • pattern_store.go: New CountActivePatterns(ctx) for total count
  • handlers_patterns.go: Returns {patterns, total}, accepts limit/offset/sort params, DefaultPatternsLimit 100→500
  • pattern.go: Confidence formula weight 0.4→0.5, ceiling 0.9→1.0
  • All callers updated (server.go ×2, decay.go, handlers_maintenance.go, pattern_store_test.go)

Frontend (Vue/TS)

  • PatternsView.vue: Server-side pagination replaces client-side slicing
  • usePatterns.ts: Passes limit/offset/sort params, exposes total ref
  • api.ts: fetchPatterns returns PatternsResponse {patterns, total}

Plugin (TypeScript)

  • before-prompt-build.ts: Skip HEARTBEAT prompts (workspace health checks)

Test plan

  • Patterns page loads with total count in header
  • Sort by frequency/confidence/last_seen triggers server fetch
  • Pagination works with >100 patterns
  • Confidence values now reach above 90% for top patterns
  • HEARTBEAT prompts don't appear in activity timeline

Summary by CodeRabbit

Примечания к выпуску

  • Новые возможности
    • Серверная пагинация и сортировка списка шаблонов; API возвращает общее количество результатов.
  • Улучшения
    • Поддержка сортировки по частоте, уверенности или дате последнего обнаружения.
    • Увеличен лимит выдачи по умолчанию с 100 до 500; клиенты обновлены для работы с новым ответом.
  • Изменения
    • Скорректирована формула расчёта уверенности шаблонов.
  • Исправления
    • Пропуск служебных «heartbeat» запросов в плагине, чтобы избежать лишней обработки.

thebtf added 2 commits March 20, 2026 15:14
T039: HEARTBEAT prompts (workspace health checks) now exit early before
triggering context search, tier classification, or tracking. Prevents
unnecessary noise in activity timeline and search analytics.
… fix

T018: Patterns page overhaul:
- Backend: GetActivePatterns now accepts limit, offset, sort params
- Backend: Added CountActivePatterns for total count
- Backend: DefaultPatternsLimit raised to 500
- Backend: handleGetPatterns returns {patterns, total} with DB-level sorting
- Frontend: Server-side pagination replaces client-side slicing
- Frontend: Sort triggers server fetch instead of local sort
- Confidence formula: ceiling raised from 0.9 to 1.0 (freqConfidence weight 0.4→0.5)
- All callers of GetActivePatterns updated to new signature
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 20, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c61c0de8-b825-4ebe-9caf-7a2fe7b7f642

📥 Commits

Reviewing files that changed from the base of the PR and between 4dc4e21 and 3544475.

📒 Files selected for processing (2)
  • internal/db/gorm/pattern_store.go
  • internal/worker/handlers_patterns.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • internal/db/gorm/pattern_store.go

Walkthrough

Внедрена серверная пагинация и сортировка для списка шаблонов: GetActivePatterns расширен (limit, offset, sort) и добавлен CountActivePatterns. Серверные обработчики и UI-компоненты обновлены для использования нового API; скорректирована формула confidence и добавлена пропускная логика для heartbeat в плагине.

Changes

Cohort / File(s) Summary
Сигнатуры хранилища шаблонов
internal/db/gorm/pattern_store.go
GetActivePatterns(ctx, limit, offset, sort) — добавлены offset и sort с динамической сортировкой; добавлен CountActivePatterns(ctx) для получения общего числа активных шаблонов.
Вызовы хранилища шаблонов
internal/db/gorm/pattern_store_test.go, internal/mcp/server.go, internal/pattern/decay.go, internal/worker/handlers_maintenance.go
Обновлены вызовы GetActivePatterns — добавлены параметры offset и sort. Тесты и внутренние сервисы адаптированы к новой сигнатуре.
Обработчик API шаблонов (сервер)
internal/worker/handlers_patterns.go
Увеличен DefaultPatternsLimit 100→500; добавлен PatternsListResponse{patterns,total}; реализована серверная пагинация и сортировка: используется CountActivePatterns и GetActivePatterns(limit,offset,sort); добавлен путь ошибки при сбое подсчёта.
Клиентский API
ui/src/utils/api.ts
Добавлен экспорт PatternsResponse { patterns, total }; fetchPatterns принимает {limit,offset,sort} и возвращает PatternsResponse.
Composable UI
ui/src/composables/usePatterns.ts
Добавлено реактивное total; loadPatterns(params?) принимает limit/offset/sort; обновлены удаления/деактивация для корректного обновления total.
Представление шаблонов (UI)
ui/src/views/PatternsView.vue
Переработана логика: серверная пагинация/сортировка, убрана клиентская пост-фильтрация/пагинация; добавлены fetchCurrentPage и handleRefresh; наблюдатели перезагружают страницу при смене сортировки/пагинации.
Модель и плагин
pkg/models/pattern.go, plugin/openclaw-engram/src/hooks/before-prompt-build.ts
Коэффициент частоты в updateConfidence() увеличен (0.4→0.5). В hook добавлен ранний выход для heartbeat-промптов (heartbeat.md / heartbeat_ok).

Sequence Diagram(s)

sequenceDiagram
    participant UI as Browser/UI
    participant API as Server (handlers_patterns)
    participant Store as PatternStore
    participant DB as Database

    UI->>API: GET /patterns?limit=..&offset=..&sort=..
    activate API
    API->>Store: CountActivePatterns(ctx)      note right of Store: unfiltered path
    Store->>DB: SELECT COUNT(*) FROM patterns WHERE status='active'
    DB-->>Store: total
    Store-->>API: total
    API->>Store: GetActivePatterns(ctx, limit, offset, sort)
    Store->>DB: SELECT ... ORDER BY <sort> LIMIT <limit> OFFSET <offset>
    DB-->>Store: patterns[]
    Store-->>API: patterns[]
    API-->>UI: { patterns: [...], total: N }
    deactivate API
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Стих

🐇 В коде норка, в мозгу — маршрут,

Offset ведёт, а сорт — как салют.
Сервер считает, UI ждёт,
Пагинация ввысь идёт,
Хватаю морковку — и спринт пройден, ура!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.22% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the three main changes: server-side pagination implementation, confidence formula adjustment, and HEARTBEAT filter addition.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/v1.1-phase4-graph-patterns
📝 Coding Plan
  • Generate coding plan for human review comments

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.11.3)

Error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions
The command is terminated due to an error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions


Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the "Patterns" feature by migrating its data retrieval to a server-side pagination and sorting model, improving performance and scalability for larger datasets. It also refines the pattern confidence calculation to allow for higher accuracy scores and introduces a filter to exclude internal system health checks (HEARTBEAT prompts) from user-facing pattern processing, ensuring a cleaner and more relevant user experience.

Highlights

  • Server-side Pagination & Sorting: Implemented server-side pagination and sorting for the Patterns page, replacing client-side slicing for improved performance and scalability.
  • Confidence Formula Adjustment: Adjusted the pattern confidence formula to allow values to reach 1.0, providing more accurate scoring for top patterns.
  • HEARTBEAT Prompt Filtering: Added a filter to skip internal HEARTBEAT prompts from being processed, preventing workspace health checks from appearing in the activity timeline.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@thebtf
Copy link
Copy Markdown
Owner Author

thebtf commented Mar 20, 2026

@coderabbitai review

@thebtf
Copy link
Copy Markdown
Owner Author

thebtf commented Mar 20, 2026

@gemini-code-assist review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 20, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@thebtf
Copy link
Copy Markdown
Owner Author

thebtf commented Mar 20, 2026

@codex review

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces server-side pagination for the Patterns page, which is a great improvement for performance. The backend is updated to handle limit, offset, and sorting at the database level, and the frontend is refactored to use this new API. The changes are well-implemented, but I've found a bug in the backend where the total count for filtered pattern lists is calculated incorrectly, which will break pagination for those views. I've also identified a potential UI inconsistency on the frontend where deleting or deprecating a pattern updates the local state instead of refetching from the server, which can lead to a stale view with server-side pagination.

Comment thread internal/worker/handlers_patterns.go
Comment thread ui/src/composables/usePatterns.ts
Comment thread ui/src/composables/usePatterns.ts
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces server-side pagination for the Patterns page, which is a great improvement for performance and scalability. The backend changes in Go correctly add limit, offset, and sorting capabilities to the GetActivePatterns function. The frontend is also updated accordingly to use these new parameters.

My review has identified a few issues:

  • A high-severity bug in the backend handler where the total pattern count is calculated incorrectly for filtered views, which will break pagination for those cases.
  • A medium-severity issue on the frontend where local state for the total count is manipulated, which could lead to inconsistencies.
  • A medium-severity bug in the Vue component that can cause redundant API calls when changing sort or page size options.

I've provided detailed comments and suggestions for fixing these issues. Overall, this is a solid implementation of a key feature, and with these fixes, it will be much more robust.

Comment thread internal/worker/handlers_patterns.go Outdated
Comment thread ui/src/composables/usePatterns.ts
Comment thread ui/src/views/PatternsView.vue
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (1)
internal/db/gorm/pattern_store_test.go (1)

202-202: Стоит добавить тесты для новых веток пагинации и сортировки.

Сейчас проверяется только дефолтный путь. Рекомендую дополнить кейсами для sort=confidence, sort=last_seen, offset>0 и отдельным тестом для CountActivePatterns, чтобы зафиксировать новое поведение API.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/db/gorm/pattern_store_test.go` at line 202, Add test cases in
pattern_store_test.go exercising the alternative pagination and sorting
branches: call patternStore.GetActivePatterns(ctx, limit, offset, "confidence")
and with "last_seen" to assert ordering, and call with offset>0 to verify
pagination skips correctly; also add a separate test for
patternStore.CountActivePatterns(ctx) to assert total counts match expected
after inserts. Locate tests around existing GetActivePatterns usage to mirror
setup/teardown, create deterministic sample patterns with varying confidence and
last_seen values, and assert both the returned slice order/length and
CountActivePatterns results to lock in the new API behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@internal/db/gorm/pattern_store.go`:
- Around line 151-157: The current ORDER BY built in pattern_store.go (the
orderClause variable and the switch on sort) is not deterministic when
frequency/confidence/last_seen_at_epoch tie, causing pagination
duplicates/misses; update the orderClause construction inside the switch (and
the default) to append a stable tiebreaker such as the primary key column (e.g.,
"id" or "pattern_id") or created_at to ensure deterministic ordering across
pages (e.g., "... , frequency DESC, confidence DESC, id DESC"); modify the
branches for "confidence" and "last_seen" similarly so every ordering path
includes the same unique deterministic tie-breaker.

In `@internal/worker/handlers_patterns.go`:
- Around line 70-77: Ветка фильтрации по type/project нарушает контракт
пагинации: offset и sort игнорируются и total берётся как len(patterns). Fix:
when patternType != "" call a CountPatternsByType(ctx,
models.PatternType(patternType)) to set total and then call
GetPatternsByType(ctx, models.PatternType(patternType), limit, offset, sort) (or
the store equivalents that accept offset/sort); similarly for project use
CountPatternsByProject and GetPatternsByProject with limit/offset/sort.
Альтернативно, если бекенд не поддерживает комбинацию фильтра+пагинации — явно
возвращать 400 error when offset/sort provided with patternType/project and
document that limitation.

In `@plugin/openclaw-engram/src/hooks/before-prompt-build.ts`:
- Around line 45-47: The early-return check in the before-prompt-build hook uses
promptLower.includes(...) which erroneously matches any prompt containing those
substrings; change it to exact-match logic (e.g., normalize promptLower with
trim() and test equality against 'heartbeat.md' and 'heartbeat_ok' or use a
strict regex like /^(heartbeat\.md|heartbeat_ok)$/i) so only exact health-check
signatures in the prompt variable (promptLower) trigger the return; update the
conditional around promptLower in the before-prompt-build handler accordingly.

In `@ui/src/composables/usePatterns.ts`:
- Around line 54-55: The code always decrements total.value after filtering
patterns.value, which can desynchronize the counter when the id wasn't present;
update the remove logic in the function that filters by id (references:
patterns.value, total.value, id) to only decrement total.value when an actual
removal occurred — e.g., capture the previous length or check if the item
existed (findIndex/includes) before filtering and decrement total.value (with
Math.max(0, ...)) only if an item was removed; apply the same fix to the
analogous block around the references at the other location (lines 65-66).

In `@ui/src/views/PatternsView.vue`:
- Around line 49-54: The client-side filter in visiblePatterns (which filters
patterns.value by searchQuery) only affects the current page while the
Pagination and total counter still reflect the full dataset, causing
inconsistent UX; fix by either (preferred) moving the search into loadPatterns
so the server accepts a search query parameter and returns paginated results
plus a totalCount used by Pagination, or (alternative) make the UI explicit that
the name filter is page-scoped by removing the global counter and updating
Pagination/labels and the computed visiblePatterns to clearly state "filtering
current page only"; update references to visiblePatterns, patterns, searchQuery,
loadPatterns, and Pagination accordingly so the total shown and pages reflect
server-filtered results (or the UI text/counter reflects a page-limited filter).
- Around line 62-69: When watching [sortBy, itemsPerPage] (the watcher using
sortBy, itemsPerPage, currentOffset, fetchCurrentPage), avoid forcing a
duplicate fetch by only resetting currentOffset.value to 0 when it actually
differs from 0; implement: if currentOffset.value !== 0 then set
currentOffset.value = 0 (do not call fetchCurrentPage there because the
currentOffset watcher will run), otherwise call fetchCurrentPage() directly—this
ensures fetchCurrentPage() is invoked exactly once when sort or page size
changes.

---

Nitpick comments:
In `@internal/db/gorm/pattern_store_test.go`:
- Line 202: Add test cases in pattern_store_test.go exercising the alternative
pagination and sorting branches: call patternStore.GetActivePatterns(ctx, limit,
offset, "confidence") and with "last_seen" to assert ordering, and call with
offset>0 to verify pagination skips correctly; also add a separate test for
patternStore.CountActivePatterns(ctx) to assert total counts match expected
after inserts. Locate tests around existing GetActivePatterns usage to mirror
setup/teardown, create deterministic sample patterns with varying confidence and
last_seen values, and assert both the returned slice order/length and
CountActivePatterns results to lock in the new API behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: faa8329d-f364-4474-b501-b4cb0fec6366

📥 Commits

Reviewing files that changed from the base of the PR and between 6c9ab25 and 4dc4e21.

📒 Files selected for processing (11)
  • internal/db/gorm/pattern_store.go
  • internal/db/gorm/pattern_store_test.go
  • internal/mcp/server.go
  • internal/pattern/decay.go
  • internal/worker/handlers_maintenance.go
  • internal/worker/handlers_patterns.go
  • pkg/models/pattern.go
  • plugin/openclaw-engram/src/hooks/before-prompt-build.ts
  • ui/src/composables/usePatterns.ts
  • ui/src/utils/api.ts
  • ui/src/views/PatternsView.vue

Comment thread internal/db/gorm/pattern_store.go Outdated
Comment thread internal/worker/handlers_patterns.go Outdated
Comment thread plugin/openclaw-engram/src/hooks/before-prompt-build.ts
Comment thread ui/src/composables/usePatterns.ts
Comment thread ui/src/views/PatternsView.vue
Comment thread ui/src/views/PatternsView.vue
- Add id DESC tiebreaker to all ORDER BY clauses in GetActivePatterns
- Guard type/project filter total count against err before assignment
- Document that type/project filters don't support offset pagination
@thebtf
Copy link
Copy Markdown
Owner Author

thebtf commented Mar 20, 2026

🤖 PR Review MCP State (auto-managed, do not edit)
{
  "version": 2,
  "parentChildren": {},
  "resolvedNitpicks": {
    "coderabbit-nitpick-117c249c-202": {
      "resolvedAt": "2026-03-20T12:58:26.095Z",
      "resolvedBy": "agent"
    }
  },
  "updatedAt": "2026-03-20T12:58:26.653Z"
}

@thebtf thebtf merged commit 35002b5 into main Mar 20, 2026
2 checks passed
@thebtf thebtf deleted the feat/v1.1-phase4-graph-patterns branch March 20, 2026 13:00
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.

1 participant