Skip to content

refactor: extract dual-bot support (Clawd + Gremlin)#8

Merged
enspyr-admin merged 5 commits intomainfrom
refactor/dual-bot-support
Mar 17, 2026
Merged

refactor: extract dual-bot support (Clawd + Gremlin)#8
enspyr-admin merged 5 commits intomainfrom
refactor/dual-bot-support

Conversation

@maxwell-merge-slam
Copy link
Copy Markdown
Contributor

Summary

  • Extract bot configuration into bot-config.ts with per-bot identity, prompts, and wandering settings
  • Add Gremlin as a second bot with name-addressed chat routing (responds only when mentioned)
  • Thread BotConfig through all handlers to replace hardcoded Clawd values
  • Update ecosystem.config.cjs for dual-bot PM2 management
  • Add CI workflow (build + lint)

Test plan

  • Both Clawd and Gremlin register as separate LiveKit workers
  • Clawd responds to all messages; Gremlin only when addressed by name
  • Wandering, help requests, and proactive nudges use per-bot config
  • npm run build passes

Stack: 1/3 — base PR

Generated with Claude Code

nickmeinhold and others added 2 commits March 17, 2026 23:25
Extract bot configuration into bot-config.ts with per-bot prompts,
wandering behavior, and identity settings. Add Gremlin as a second bot
with name-addressed chat routing (only responds when mentioned).
Thread BotConfig through all handlers to replace hardcoded Clawd values.
Update ecosystem.config.cjs for dual-bot PM2 management.

Co-Authored-By: Claude <noreply@anthropic.com>
Add GitHub Actions CI (build + lint on PR/push to main) and /ship
initialization config with 80% coverage threshold target.

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link
Copy Markdown

@kelvin-bit-brawler kelvin-bit-brawler 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 - PR #8

Summary: Cleanly extracts bot identity, prompts, and wandering config into a per-bot configuration system, enabling Clawd and Gremlin to run as separate processes from a single codebase.

Changes reviewed:

  • New BotConfig interface and config registry (src/bot-config.ts)
  • Clawd and Gremlin prompt modules (src/prompts/clawd.ts, src/prompts/gremlin.ts)
  • Threading BotConfig through all handlers in src/index.ts and src/agent-loop.ts
  • Name-addressed chat routing via shouldRespondToChat()
  • Dual-bot PM2 config (ecosystem.config.cjs)
  • CI workflow (.github/workflows/ci.yml)

Quality Assessment:

Aspect Status Notes
Code Quality pass Clean extraction — config threaded consistently, good doc comments, nullable prompts handled well
Tests warning No tests exist yet (test-command: none in ship-config). Acceptable for this refactor scope
Security pass No new secrets, env vars, or external inputs introduced
Performance pass No performance implications — same runtime behavior, just parameterized

Issues found:

  1. CI lint step fails (blocking) — The CI workflow runs npm run lint but no eslint.config.js exists in the repo. ESLint 9.x requires a flat config file. CI is currently red: https://github.com/enspyrco/tech_world_bot/actions/runs/23194165834. Either add an eslint.config.js or remove the lint step until one is configured.

  2. shouldRespondToChat hardcodes Clawd as the "responds to everything" bot (src/index.ts line 545) — This embeds routing policy in a function that should ideally be config-driven. Consider adding a respondsToAll: boolean field to BotConfig instead of checking agentName === "clawd". Low priority since it works correctly today, but it would make adding a third bot cleaner.

  3. Shared messageHistory between bots — Both bots share the same chat room, but each process has its own messageHistory array. This means Clawd's conversation context won't include Gremlin's responses and vice versa. This is probably fine (even desirable) for now, but worth noting as a conscious design choice.

  4. Gremlin's fallback hint message references Clawd by name (src/index.ts line 344: "try asking Clawd!") — This works for the current two-bot setup but would need updating if the tutor bot is ever renamed. Minor.

Suggestions:

  • Deployment note needed: The CLAUDE.md still references a single tech-world-bot PM2 process. The deployment section should be updated to reflect dual-bot management (e.g., pm2 restart clawd-bot gremlin-bot). This PR description says "Stack: 1/3" so maybe a later PR handles docs.

  • Imports before interface declaration in bot-config.ts (lines 26-27): The import statements come after the BotConfig interface. While TypeScript is fine with this, conventionally imports go at the top of the file. Nitpick.

  • Agent dispatch coordination: The existing Firebase Cloud Function dispatches agentName: "clawd". For Gremlin to also be dispatched, the Cloud Function will need a second RoomAgentDispatch. Presumably handled in a later PR in this stack, but flagging for awareness.

Verdict: REQUEST_CHANGES

The code quality of the refactor itself is solid — config extraction is clean, nullable prompts are handled consistently, and the name-addressed routing is a nice touch. However, CI is red due to the missing ESLint config, which needs to be fixed before merge. Once that's resolved, this is ready to go.

nickmeinhold and others added 2 commits March 17, 2026 23:34
Add eslint.config.js with typescript-eslint, install required deps,
remove unused MapInfo interface that triggered lint error.

Co-Authored-By: Claude <noreply@anthropic.com>
- Add respondsToAll config flag to replace hardcoded agentName check
- Include bot name in proactive nudge IDs to prevent deduplication
- Remove hardcoded "Clawd" reference from Gremlin hint fallback
- Update CLAUDE.md for dual-bot architecture and Cloud Run deployment

Co-Authored-By: Claude <noreply@anthropic.com>
Copy link
Copy Markdown

@kelvin-bit-brawler kelvin-bit-brawler 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 - PR #8 (Re-review)

Summary: Extracts dual-bot support into a clean config-driven architecture, enabling Clawd and Gremlin to run as separate processes from a single codebase.

Previous feedback status:

  • ESLint flat config: Fixedeslint.config.js added, CI is green
  • respondsToAll config flag: Fixed — routing is now config-driven instead of hardcoding agentName === "clawd"
  • Gremlin fallback referencing Clawd: Fixed — now says "try asking the other bot!"
  • CLAUDE.md deployment docs: Fixed — updated for Cloud Run dual-bot setup

Quality Assessment:

Aspect Status Notes
Code Quality pass Clean config threading, good doc comments, nullable prompts handled consistently
Tests warning No tests (acceptable for refactor scope, test-command: none in ship config)
Security pass No new secrets or external inputs
Performance pass Same runtime behavior, just parameterized
CI pass Build + lint green

Issue found:

  1. Chat response IDs missing bot name (non-blocking)src/index.ts line 178 uses `${messageId}-response` but the CLAUDE.md documents the format as message-id-botname-response and states "Response IDs include the bot's agentName to prevent deduplication when both bots respond to the same message." The proactive nudge ID was correctly updated to include botConfig.agentName (line 501), but the regular chat response ID (line 178) and error ID (line 205) were not. Today this only matters when a user mentions "gremlin" (triggering both bots to respond to the same message), but it's a latent dedup bug.

    Suggested fix:

    // line 178
    id: `${messageId}-${botConfig.agentName}-response`,
    // line 205
    id: `${messageId}-${botConfig.agentName}-error`,
    

Verdict: APPROVE

All blocking feedback from the previous review has been addressed. The response ID inconsistency is real but non-blocking — it only manifests when both bots respond to the same message, and the fix is a one-liner. The overall refactor is clean: config extraction is thorough, prompts are well-separated, and the BotConfig interface is a solid foundation for adding more bots later.

- Add extractText() helper that safely handles empty content arrays
  from the Anthropic API (prevents crash on undefined access)
- Guard help-request handler with isBusy check to prevent concurrent
  help requests from racing and corrupting walk/state

Co-Authored-By: Claude <noreply@anthropic.com>
@enspyr-admin enspyr-admin merged commit 569129c into main Mar 17, 2026
1 check passed
@nickmeinhold nickmeinhold deleted the refactor/dual-bot-support branch March 17, 2026 13: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