Skip to content

feat: add gap logging functionality and improve bot thread management#6

Open
kpj2006 wants to merge 4 commits into
AOSSIE-Org:mainfrom
kpj2006:main
Open

feat: add gap logging functionality and improve bot thread management#6
kpj2006 wants to merge 4 commits into
AOSSIE-Org:mainfrom
kpj2006:main

Conversation

@kpj2006

@kpj2006 kpj2006 commented Jun 11, 2026

Copy link
Copy Markdown
Member

Addressed Issues:

Fixes #(issue number)

Screenshots/Recordings:

Additional Notes:

Checklist

  • My code follows the project's code style and conventions
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings or errors
  • I have joined the Discord server and I will share a link to this PR with the project maintainers there
  • I have read the Contributing Guidelines

⚠️ AI Notice - Important!

We encourage contributors to use AI tools responsibly when creating Pull Requests. While AI can be a valuable aid, it is essential to ensure that your contributions meet the task requirements, build successfully, include relevant tests, and pass all linters. Submissions that do not meet these standards may be closed without warning to maintain the quality and integrity of the project. Please take the time to understand the changes you are proposing and their impact.

Summary by CodeRabbit

  • New Features

    • Bot now builds conversation context from recent thread history for more coherent responses
    • Retry logic improves reliability during temporary unavailability
  • Bug Fixes

    • Enhanced error handling with standardized fallback messages when responses fail
    • Improved thread creation and management with better validation
  • Chores

    • Added persistent logging for unavailability events
    • Updated configuration to ignore additional development artifacts

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@kpj2006, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 40 minutes and 53 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more credits in the billing tab to continue.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: eec6d3a2-b418-406a-aa1d-c6237349db60

📥 Commits

Reviewing files that changed from the base of the PR and between 00d27ff and 6ef33d7.

📒 Files selected for processing (2)
  • bot.py
  • start_bot_hidden.vbs

Walkthrough

The bot now persists failure logs, retries Ollama requests up to 3 times, builds conversation context from recent thread history, creates dedicated Discord threads for responses with auto-archival, serializes Ollama calls with a lock, and surfaces gap reasons when operations fail.

Changes

Enhanced Discord Bot with Resilience and Thread-based Conversation

Layer / File(s) Summary
Infrastructure: Imports, Constants, and Gap Logging
bot.py (lines 2–8, 24–25, 35–67)
Module dependencies reorganized for timezone and Path support. Gap logging configured with GAP_LOG_PATH, MAX_RETRIES = 3, and THREAD_HISTORY_LIMIT = 10. Persistence helpers load/save gap_log.json with corruption handling and record per-query reason entries with optional thread_id.
Ollama Service: Retry Logic with Fallback
bot.py (lines 78–80, 93–113)
Function signature updated to return tuple[str, bool]. HTTP request loop retries up to MAX_RETRIES times; on success returns response with fallback=False, or after exhaustion returns standardized unavailability message with fallback=True.
Thread and Conversation Context
bot.py (lines 115–160)
Conversation context assembled from recent thread history with author labels and message length caps. Thread acquisition/creation reuses active threads or creates new Q&A threads with auto-archive, returning None on archived/locked failure and logging specific error reasons.
Message Processing with Thread Integration
bot.py (lines 163–234)
Refactored process_message routes all responses through threads: determines thread context, creates threads when needed, serializes Ollama calls with lock, builds optional conversation context, logs gap reasons on fallback/context absence, truncates long replies, and handles Discord send/reply and API errors.
Event Handlers and Startup
bot.py (lines 251–295, 314)
on_ready waits for Ollama readiness and processes backlog of missed non-bot messages. on_message delegates to process_message. Main entry point runs Discord client via client.run(DISCORD_TOKEN).
Development Configuration
.gitignore (lines 329–331), start_bot_hidden.vbs (lines 1–4), gap_log.json
.gitignore adds ignore patterns for __pycache__/ and .commandcode/. New VBScript launches bot in hidden window using local virtualenv Python. gap_log.json example shows five logged gap entries with timestamps and reasons.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant Discord
  participant bot
  participant Ollama
  participant gap_log

  User->>Discord: post message in main channel
  Discord->>bot: on_message event
  bot->>bot: determine thread context
  bot->>Discord: create or reuse thread
  Discord-->>bot: thread
  bot->>bot: build conversation context from thread history
  bot->>bot: acquire ollama_lock
  loop Retry up to MAX_RETRIES
    bot->>Ollama: POST prompt with context
    Ollama-->>bot: response or timeout
  end
  bot->>bot: truncate if long reply
  bot->>Discord: send/reply in thread
  Discord-->>User: response in thread
  alt gap occurred
    bot->>gap_log: _log_gap(query, reason, thread_id)
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • AOSSIE-Org/SkillBot#4: Both PRs touch the same Discord bot implementation in bot.py—specifically the Ollama request/response path (generate_ollama_response) and message-handling/event flow (on_message/processing)—with this PR extending and refactoring the initial logic from PR #4.

Suggested labels

Python Lang

Poem

🐰 A rabbit hops through Discord threads with glee,
Retrying Ollama—thrice the spree!
Gap logs persist, conversations flow,
From history's roots, fresh answers grow.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures both main changes: adding gap logging functionality and improving bot thread management, matching the core modifications in bot.py and gap_log.json.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions github-actions Bot added no-issue-linked PR is not linked to any issue backend Changes to backend code configuration Configuration file changes javascript JavaScript/TypeScript code changes python Python code changes size/L Large PR (201-500 lines changed) repeat-contributor PR from an external contributor who already had PRs merged needs-review labels Jun 11, 2026
@github-actions

github-actions Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor
Messages
📖

⚠️ PR Template Check

These are non-blocking, but please fix:

  • Please replace the placeholder Fixes #(issue number) with the actual issue number (e.g. Fixes #42).

  • Some required checklist items are not completed:

  • My PR addresses a single issue

  • My code follows the project's code style

  • My changes generate no new warnings or errors

Generated by 🚫 dangerJS against 6ef33d7

@coderabbitai coderabbitai 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.

Actionable comments posted: 10

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.gitignore:
- Line 331: Update the .gitignore to include gap_log.json so runtime bot logs
are not committed (add a line "gap_log.json"); if gap_log.json is already
tracked remove it from the index with git rm --cached gap_log.json and commit
the .gitignore change; reference .gitignore and the filename gap_log.json when
making the change to ensure future runtime artifacts are excluded.

In `@bot.py`:
- Around line 214-219: The current code treats both Ollama fallback and missing
skill context as operational "gaps" via _log_gap, which is misleading when
Ollama responded successfully but no skill file exists; change the logging so
only used_fallback triggers _log_gap(message.content, "ollama_unavailable",
thread_id=thread.id), and when skill_context is missing but a response was
produced call a configuration/validation logger (e.g., _log_warning or a new
_log_config_warning) with a distinct tag like "missing_skill_context" (still
include message.content and thread.id) instead of logging it as a gap; update
the conditional around used_fallback and skill_context to implement this
distinction and reference the symbols used_fallback, skill_context, _log_gap,
message.content, and thread.id.
- Around line 169-173: The current guard lets any Thread through because
is_in_thread bypasses the channel ID check; update the condition so when
message.channel is a discord.Thread you compare its parent channel ID (use
message.channel.parent_id or message.channel.parent.id) against
DISCORD_CHANNEL_ID_INT instead of the thread's own id; specifically change the
is_in_configured_channel logic to detect Thread vs TextChannel and, for Threads,
check parent_id == DISCORD_CHANNEL_ID_INT, and only allow when either a
non-thread channel id matches or a thread's parent matches.
- Around line 137-161: The _get_or_create_thread function currently tries to
call message.create_thread even when the message is already inside an
archived/locked discord.Thread; to fix, detect if isinstance(message.channel,
discord.Thread) and if thread.archived or thread.locked then immediately return
None (instead of falling through), so you don't attempt to create a nested
thread via message.create_thread; update the early branch that checks
thread.archived and thread.locked to return None and log a warning, leaving the
rest of the try/except creating thread logic unchanged.
- Around line 54-65: The _log_gap function does an unsynchronized
read-modify-write using _load_gap_log and _save_gap_log causing race conditions;
convert _log_gap into an async function that uses a module-level asyncio.Lock
(e.g., _gap_log_lock) to guard the load/append/save sequence, or alternatively
implement atomic file writes (write to a temp file then os.replace) inside the
critical section; then update all call sites (the async callers mentioned at
lines around where it's invoked) to await _log_gap so the lock is respected and
concurrent invocations won't clobber gap_log.json.
- Around line 115-134: The _build_conversation_context function can duplicate
the user's current message because thread.history(...) may include it; modify
_build_conversation_context to skip the current message when building
history—e.g., inside the async for loop over thread.history in
_build_conversation_context, compare each msg to the current message (use
current_author and current_query or preferably msg.id if the caller can pass the
current message id) and continue (skip) when they match so you don't include the
same content twice before you append the "Current question..." line.
- Around line 187-192: The bare except in the message.reply fallback should not
silently swallow errors; update the try/except around the message.reply call to
catch Exception as e and log the exception (e.g., using an existing logger or
logger.exception) with context like "Failed to send thread-creation failure
reply" so you retain the fallback behavior but capture the stack/exception for
debugging; keep the reply attempt logic intact and do not re-raise.
- Around line 196-201: The typing indicator currently enters and immediately
exits because async with thread.typing(): contains only pass; move the Ollama
response generation call(s) (the coroutine that generates the reply) inside the
async with thread.typing() block so the context is held for the duration of
generation; update the try/except around thread.typing() to cover the await that
performs generation (refer to thread.typing and the coroutine/function used to
call Ollama response generation) so logger.warning still captures exceptions
from both typing and generation.

In `@gap_log.json`:
- Around line 1-32: Remove the runtime log file gap_log.json from version
control and prevent future commits: run git rm gap_log.json to remove it from
the repo and add gap_log.json to .gitignore so the file created by the bot's
_save_gap_log() in bot.py is ignored; ensure you commit the .gitignore update
and the removal together and verify no other runtime artifacts from
_save_gap_log() are tracked.

In `@start_bot_hidden.vbs`:
- Around line 3-4: Replace the hard-coded botDir with a dynamic path derived
from the script's location: use WScript.ScriptFullName and the
Scripting.FileSystemObject's GetParentFolderName to compute the directory
containing the VBS file (then append "\SkillBot" if the bot folder is a child),
and keep the existing WshShell.Run call (WshShell.Run "cmd /c cd /d """ & botDir
& """ && venv\Scripts\python.exe bot.py", 0, False) unchanged except to
reference the new botDir variable; update any variable named botDir and ensure
you create the FileSystemObject (CreateObject("Scripting.FileSystemObject")) and
use GetParentFolderName(WScript.ScriptFullName) to make the script portable.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 423e24a9-7eb8-49b7-bcef-c38fa906f2ef

📥 Commits

Reviewing files that changed from the base of the PR and between ba49d03 and 00d27ff.

📒 Files selected for processing (4)
  • .gitignore
  • bot.py
  • gap_log.json
  • start_bot_hidden.vbs

Comment thread .gitignore
Comment thread bot.py Outdated
Comment thread bot.py
Comment thread bot.py
Comment thread bot.py
Comment thread bot.py
Comment thread bot.py
Comment thread bot.py
Comment thread gap_log.json
Comment thread start_bot_hidden.vbs Outdated
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Comment thread gap_log.json
@@ -0,0 +1,32 @@
[

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.

Do we need this log in the repo? Should we perhaps gitignore it?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

this is intentionally left for skill-updater, will make it more polished in my future pr.

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

Labels

backend Changes to backend code configuration Configuration file changes gsoc javascript JavaScript/TypeScript code changes needs-review no-issue-linked PR is not linked to any issue python Python code changes repeat-contributor PR from an external contributor who already had PRs merged size/L Large PR (201-500 lines changed)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants