Skip to content

fix(ui): Remove leaked think and final tags#3

Open
iclem wants to merge 12 commits intofeat/nextcloud-talkfrom
fix/think-tags
Open

fix(ui): Remove leaked think and final tags#3
iclem wants to merge 12 commits intofeat/nextcloud-talkfrom
fix/think-tags

Conversation

@iclem
Copy link
Copy Markdown
Owner

@iclem iclem commented Apr 23, 2026

Summary

Describe the problem and fix in 2–5 bullets:

If this PR fixes a plugin beta-release blocker, title it fix(<plugin-id>): beta blocker - <summary> and link the matching Beta blocker: <plugin-name> - <summary> issue labeled beta-blocker. Contributors cannot label PRs, so the title is the PR-side signal for maintainers and automation.

  • Problem:
  • Why it matters:
  • What changed:
  • What did NOT change (scope boundary):

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #
  • Related #
  • This PR fixes a bug or regression

Root Cause (if applicable)

For bug fixes or regressions, explain why this happened, not just what changed. Otherwise write N/A. If the cause is unclear, write Unknown.

  • Root cause:
  • Missing detection / guardrail:
  • Contributing context (if known):

Regression Test Plan (if applicable)

For bug fixes or regressions, name the smallest reliable test coverage that should catch this. Otherwise write N/A.

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file:
  • Scenario the test should lock in:
  • Why this is the smallest reliable guardrail:
  • Existing test that already covers this (if any):
  • If no new test is added, why not:

User-visible / Behavior Changes

List user-visible changes (including defaults/config).
If none, write None.

Diagram (if applicable)

For UI changes or non-trivial logic flows, include a small ASCII diagram reviewers can scan quickly. Otherwise write N/A.

Before:
[user action] -> [old state]

After:
[user action] -> [new state] -> [result]

Security Impact (required)

  • New permissions/capabilities? (Yes/No)
  • Secrets/tokens handling changed? (Yes/No)
  • New/changed network calls? (Yes/No)
  • Command/tool execution surface changed? (Yes/No)
  • Data access scope changed? (Yes/No)
  • If any Yes, explain risk + mitigation:

Repro + Verification

Environment

  • OS:
  • Runtime/container:
  • Model/provider:
  • Integration/channel (if any):
  • Relevant config (redacted):

Steps

Expected

Actual

Evidence

Attach at least one:

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios:
  • Edge cases checked:
  • What you did not verify:

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

If a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.

Compatibility / Migration

  • Backward compatible? (Yes/No)
  • Config/env changes? (Yes/No)
  • Migration needed? (Yes/No)
  • If yes, exact upgrade steps:

Risks and Mitigations

List only real risks for this PR. Add/remove entries as needed. If none, write None.

  • Risk:
    • Mitigation:

iclem and others added 12 commits April 22, 2026 23:45
- Export parseStructuredNextcloudTalkBody and resolveExplicitNextcloudTalkMention
- Rename mentionDebug -> mentionEntries and drop unused explicitMention field from
  the parsed body struct
- Remove verbose per-message debug log line from the hot path
- Add inbound.mentions.test.ts with 16 unit tests covering plain text pass-through,
  structured JSON extraction, malformed JSON fallback, and mention matching (id,
  mentionId, name, email local-part, case-insensitive, type guard)
…ge body

Nextcloud Talk's structured payload puts mention tokens like {mention0} or
{mention-user1} directly in the message string. Leaving them in effectiveBody
caused two problems:
- Command parsing (hasControlCommand, directives) would not see commands that
  follow an @-mention, e.g. "{mention0} /reset" -> "/reset" was never reached.
- A mention-only message ("{mention0}") produced a non-empty prompt dispatched
  to the agent, causing spurious replies.

Fix: strip all {key} placeholder tokens whose keys appear in parameters[], then
treat a structured body that is empty after stripping as a mention-only ping and
return early without dispatching.

Also add ParsedNextcloudTalkBody.structured flag to distinguish plain-text
fall-through from a successfully parsed JSON body.

Tests: 2 new cases (mention-only drop, command after mention), updated existing
assertions to reflect stripped text. 18 unit tests, 68 total, all passing.
- Outbound: wire sendReactionNextcloudTalk into a ChannelMessageActionAdapter
  (nextcloudTalkMessageActions) exposing the 'react' action on the message tool
- Inbound: extend webhook decoder to parse Like/Dislike events (Talk 21+) into
  NextcloudTalkInboundReaction; route through onReaction callback in
  monitorNextcloudTalkProvider; add handleNextcloudTalkInboundReaction stub
  (TODO: full dispatch on a future pass)
- Types: extend NextcloudTalkWebhookPayload with Like/Dislike types and
  optional content field; add NextcloudTalkInboundReaction type
- SDK: export jsonResult, readReactionParams, readStringParam from
  plugin-sdk/nextcloud-talk surface
- Tests: channel-actions.test.ts (2 tests), monitor.reaction.test.ts (3 tests)
  — all 73 nextcloud-talk tests pass
Adds an optional `ackReaction` config field (account- and room-level).
When set, the bot sends a reaction emoji to every received message that
passes all gate checks (best-effort; errors are logged, not thrown).
Room-level `ackReaction` takes precedence over account-level.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements typing indicator signaling so the bot shows a 'composing'
status while processing a message.

- Add NextcloudTalkTypingIndicator type and typingIndicator config option
  to NextcloudTalkRoomConfig and NextcloudTalkAccountConfig
- Add send-typing.ts: sendTypingNextcloudTalk() using the proposed bot
  typing endpoint POST /ocs/v2.php/apps/spreed/api/v1/bot/{token}/typing
  with HMAC-SHA256 auth (same pattern as sendMessageNextcloudTalk)
- Gracefully handles 404 (endpoint not yet available on server) with a
  one-time console.warn and continues without throwing
- Add resolveTypingIndicatorEnabled() for room-level override of
  account-level setting (room config takes precedence)
- Integrate into inbound.ts: typing=true before dispatch, typing=false
  after delivery or on dispatch error (fire-and-forget, non-blocking)
- Add config-schema.ts entries for typingIndicator on both room and
  account schemas
- Add 16 unit tests covering valid/error paths and config resolution

Feature is opt-in: typingIndicator defaults to false. Enable per-account
or override per-room with typingIndicator: true/false.
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cb22ceb729

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

}
if (item.type === "text" && typeof item.text === "string" && isAssistantMessage) {
const expanded = expandTextContent(item.text);
const expanded = expandAssistantTextContent(item.text);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Sanitize assistant tags after combining text blocks

normalizeMessage now runs sanitizeAssistantVisibleText on each assistant text block independently, so malformed reasoning tags that span blocks are not handled correctly. If block A opens <think> and block B contains continuation text (or a visible answer) without a closing tag, block A is dropped but block B is still rendered, which leaks content that the new strict behavior is supposed to suppress until thinking closes. This affects assistant messages delivered as multi-block arrays, not just single-string payloads covered by the new tests.

Useful? React with 👍 / 👎.

@iclem iclem force-pushed the feat/nextcloud-talk branch from b8a08c3 to aa2a646 Compare April 23, 2026 20:33
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.

1 participant