fix: Slack MAX_MESSAGE_LENGTH + typing indicator via assistant.threads.setStatus

- Increase MAX_MESSAGE_LENGTH from 3,900 to 39,000 (Slack API allows 40k)
- Implement real typing indicator using assistant.threads.setStatus API
  - Shows 'BotName is thinking...' next to the bot name in threads
  - Auto-clears when the bot sends a reply
  - Requires assistant:write or chat:write scope
  - Falls back silently if scope unavailable (reactions still work)
- 4 new tests for typing indicator
This commit is contained in:
teknium1 2026-03-12 17:32:06 -07:00
parent df07baedfe
commit 319e6615c3
2 changed files with 69 additions and 6 deletions

View file

@ -532,6 +532,49 @@ class TestMessageRouting:
adapter.handle_message.assert_not_called()
# ---------------------------------------------------------------------------
# TestSendTyping — assistant.threads.setStatus
# ---------------------------------------------------------------------------
class TestSendTyping:
"""Test typing indicator via assistant.threads.setStatus."""
@pytest.mark.asyncio
async def test_sets_status_in_thread(self, adapter):
adapter._app.client.assistant_threads_setStatus = AsyncMock()
await adapter.send_typing("C123", metadata={"thread_id": "parent_ts"})
adapter._app.client.assistant_threads_setStatus.assert_called_once_with(
channel_id="C123",
thread_ts="parent_ts",
status="is thinking...",
)
@pytest.mark.asyncio
async def test_noop_without_thread(self, adapter):
adapter._app.client.assistant_threads_setStatus = AsyncMock()
await adapter.send_typing("C123")
adapter._app.client.assistant_threads_setStatus.assert_not_called()
@pytest.mark.asyncio
async def test_handles_missing_scope_gracefully(self, adapter):
adapter._app.client.assistant_threads_setStatus = AsyncMock(
side_effect=Exception("missing_scope")
)
# Should not raise
await adapter.send_typing("C123", metadata={"thread_id": "ts1"})
@pytest.mark.asyncio
async def test_uses_thread_ts_fallback(self, adapter):
adapter._app.client.assistant_threads_setStatus = AsyncMock()
await adapter.send_typing("C123", metadata={"thread_ts": "fallback_ts"})
adapter._app.client.assistant_threads_setStatus.assert_called_once_with(
channel_id="C123",
thread_ts="fallback_ts",
status="is thinking...",
)
# ---------------------------------------------------------------------------
# TestFormatMessage — Markdown → mrkdwn conversion
# ---------------------------------------------------------------------------
@ -760,7 +803,7 @@ class TestMessageSplitting:
@pytest.mark.asyncio
async def test_long_message_split_into_chunks(self, adapter):
"""Messages over MAX_MESSAGE_LENGTH should be split."""
long_text = "x" * 5000
long_text = "x" * 45000 # Over Slack's 40k API limit
adapter._app.client.chat_postMessage = AsyncMock(
return_value={"ts": "ts1"}
)