Skip to content

Conversation

@bokelley
Copy link
Contributor

Summary

  • Strip all Slack user mentions (<@U12345678>) from thread context before passing to Claude
  • Replace mentions with [someone] to preserve context without exposing raw IDs
  • Add instruction in thread context header telling Claude not to use @ mentions

This fixes an issue where Claude would output raw Slack user IDs in responses, causing them to render as blank/broken mentions in Slack (showing "Private user info" tooltip).

Test plan

  • Mention Addie in a thread where someone else was @mentioned
  • Verify the response doesn't contain blank user mentions
  • Verify Claude refers to other users as "someone" instead of trying to @ mention them

🤖 Generated with Claude Code

When processing thread context for Claude:
- Add getSlackUserWithAddieToken() to look up users using Addie's bot token
- Collect all unique user IDs mentioned in thread messages
- Look up display names in parallel for efficiency
- Replace <@u12345678> with @DisplayName in thread context
- Fall back to [someone] only if user lookup fails

This allows Claude to see who was mentioned and respond appropriately,
while preventing it from outputting raw Slack user IDs.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@bokelley bokelley force-pushed the bokelley/fix-readme-links branch from 789bb7e to 11f61e4 Compare December 31, 2025 13:44
bokelley and others added 12 commits December 31, 2025 09:49
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When Addie is in a channel, it now listens to all messages (not just @mentions).
For each message, it:
1. Evaluates if the message warrants a response (quick yes/no check)
2. If yes, generates a proposed response
3. Queues the response for admin approval instead of sending directly

When an admin approves a queued item:
- The message is sent to Slack automatically
- Execution result is recorded (success/failure, message timestamp)

This enables human-in-the-loop oversight for proactive channel responses.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add quickEvaluate() method to claude-client using Haiku for fast yes/no/react decisions
- Add 'engagement' rule type for configuring when Addie should respond in channels
- Load engagement rules from database (with sensible defaults if none exist)
- Support 'react' response for greetings - adds 👋 emoji instead of full response
- Update admin UI to show and manage engagement rules

Engagement rules control:
- When to respond with a full message (questions about AdCP, help requests)
- When to react with emoji (greetings, welcomes, new members)
- When to ignore (casual chat, internal discussions)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Rules can now have a context that determines when they're applied:
- NULL (default): Always included in main system prompt
- 'engagement': Only for "should I respond?" channel evaluation
- 'admin': Only when talking to admin users
- 'member': Only when talking to organization members
- 'anonymous': Only when talking to anonymous/unlinked users

Changes:
- Add migration 066_rule_contexts.sql to add context column
- Remove 'engagement' from RuleType (it's a context, not a type)
- Add RuleContext type and getRulesByContext() method
- Update buildSystemPrompt() to only use rules with null context
- Update admin UI with separate context filter and selector
- Add context badges with distinct colors

This separates WHAT a rule does (type) from WHEN it applies (context).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add two seed rules to the migration:

1. Areas of Expertise (default context - main prompt)
   - Knowledge rule listing topics Addie is expert in
   - AdCP, agentic advertising, AgenticAdvertising.org, MCP, ad tech

2. Channel Engagement (engagement context)
   - Behavior rule for should-respond evaluation
   - Short, focused on YES/REACT/NO decisions
   - References the areas of expertise indirectly

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Address review comments:
- Change "Areas of Expertise" to "What Addie Can Help With"
- Ground capabilities in actual tools (search_docs, search_repos, validate_adagents, etc.)
- Be honest about MCP/A2A: can web search but no authoritative docs indexed
- Update engagement rules to reference actual capabilities

This makes the rules more accurate - Addie's expertise comes from its tools,
not from claiming knowledge about topics.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Introduces a proper router architecture that classifies incoming messages
using Claude Haiku before determining the execution path:

- Router generates execution plans: ignore, react (emoji), clarify, or respond
- Routing rules are code-managed (not user-editable) for tool alignment
- Rules synced to database on startup for admin visibility
- Replaces ad-hoc quickEvaluate with structured routing

Execution plans include:
- Which tools to use for the response
- Whether to ask clarifying questions
- Conditional logic based on user context (admin, member, etc.)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove routing rules database table and sync logic (unnecessary complexity)
- Remove rule context field (router handles engagement logic in code)
- Rename migration 066 to just seed the capabilities rule
- Router is now purely code-based with no database interaction

The router still provides:
- Haiku-based message classification (ignore/react/clarify/respond)
- Expertise areas mapped to tools
- Quick pattern matching for obvious cases
- Conditional logic based on user context (admin/member)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…tate

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove rule context filter from admin UI (context feature removed)
- Remove duplicated AVAILABLE_TOOLS from router (tools come from ROUTING_RULES)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Resolved conflict in server/src/addie/bolt-app.ts:
- Kept both getSlackUserWithAddieToken (for user mention resolution)
  and getChannelInfo (from main branch)
- Kept AddieRouter import for the new routing architecture

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Creates a comprehensive test script for the new Haiku-based router:
- Tests quickMatch for simple patterns (no API calls)
- Tests full router with live Haiku API for complex scenarios
- 26 test cases covering ignore, react, and respond actions
- Validates tool selection for different topic areas

Run with: npx tsx scripts/test-router.ts --live

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@bokelley bokelley merged commit eefed40 into main Dec 31, 2025
6 checks passed
@bokelley bokelley deleted the bokelley/fix-readme-links branch December 31, 2025 16:19
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.

2 participants