Skip to content

Refactor canned triggers into native tool calls #25

@scarolan

Description

@scarolan

The regex matchers in lib/responses.js (isImageRequest, isDanceParty, isPodBayDoor, isLoveYou, isRickroll, isTikTok, dad-joke trigger) are 2018-vintage and increasingly out of place now that Data runs on native Ollama/Gemini SDKs with proper tool support.

Idea

Define a small set of tools and let the model decide when to call them:

  • generate_image(prompt) — calls Gemini Nano Banana
  • tell_dad_joke() — fetches from icanhazdadjoke.com
  • start_dance_party() — emits the emoji rain
  • show_help() — returns the help text
  • state_asimovs_laws() — Asimov rule recitation
  • play_rickroll() / play_tiktok() — the button blocks

Both Ollama (tools: [...]message.tool_calls) and Gemini (config.tools with function declarations) have native tool calling. Translation happens inside lib/chat-backends.js so handleMessage only deals with the canonical shape.

Biggest immediate win

The IMAGE_REQUEST_GUIDANCE shim where Data has to say "please use the /image command" instead of just generating the image. That whole interaction goes away — user says "Data, picture of a sehlat", Data calls the tool, image appears in the channel.

Plan

  1. New lib/tools.js — tool definitions (JSON schemas + implementations).
  2. Extend the chat-backend adapter interface: chat({ messages, tools }) → { text, toolCalls? }. Adapters translate to/from each provider's native shape.
  3. handleMessage becomes a small loop: call the model → if toolCalls, execute them and feed the results back as a tool-role message → repeat until plain text. Cap iterations to prevent runaways.
  4. Delete isImageRequest/IMAGE_REQUEST_GUIDANCE, the love-you/pod-bay/danceparty/rickroll/tiktok matchers and their call sites in app.js. Keep the rules, help, dad joke matchers as fallbacks for now (or convert them too).
  5. Tests: adapter translation of tool calls for both Ollama + Gemini, and a fake-tool-calling chat that exercises the multi-turn dispatch loop in handleMessage.

What this unlocks downstream

Future tools (web search, weather, Slack user lookups, etc.) just slot into lib/tools.js — no new dispatch code, no new regex.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions