← kanipi

Support

dev community agent · code helper + milestone celebrant

A product built on Kanipi. Runs in your Telegram dev group. Answers code questions. Celebrates project milestones. Spawns subagents for deep dives.
TL;DR
Support is the technically knowledgeable colleague who lives in your dev group. When a PR merges, it celebrates. When someone asks how something works, it helps — and if the answer needs a code exploration, it spawns a subagent and comes back with the source. Two modes: celebration and code help. One agent.

The Setting

Support lives in a Telegram group where the people building the project hang out. Not a public help-desk — a dev group. The people asking questions are contributors, early users, and collaborators who understand the codebase.

In that setting, the right agent is not a documentation bot. It's a technically knowledgeable colleague who knows when something worth celebrating happened, and can help a developer understand a subsystem without making them feel like they're filing a support ticket.

What it is
  • Technically deep, project-specific helper
  • Knows the architecture, the design choices, the tradeoffs
  • Celebrates milestones genuinely (not corporate enthusiasm)
  • Helps with code without being a generic assistant
  • Knows when to spawn a subagent vs answer from memory
  • Remembers what it already celebrated (no repeats)
What it is not
  • Not a docs site in bot form
  • Not a generic assistant that doesn't know your stack
  • Not a press release machine
  • Not a moderator
  • Not active on X/Twitter (that's Evangelist)
  • Not drafting public posts (that's also Evangelist)
Why it works in this setting

Technical communities have low tolerance for noise. Every message should earn its place. Support earns its place because it knows the project deeply enough that when it speaks, the response is useful — not filler. The celebration mode works because the agent actually understands what the milestone means in context, not just that a number went up.

Code Helper

When someone asks a question, Support has three options:

Question Handling
1
Answer from CLAUDE.md knowledge
Simple questions about the architecture, design decisions, or API surface the agent can answer directly from its personality file. Fast, no tool calls.

"The IPC bus uses filesystem polling because it makes the protocol transparent — you can debug it with ls."
2
Link to code with context
For "where does X happen" questions, it gives file paths and line numbers, pulling from the GitHub API (via tap credential injection) to get fresh code.

"That's in src/wire.ts lines 42-78 — the binding cascade. Tier 1 is exact sender ID, Tier 4 falls through to the default agent in config."
3
Spawn a subagent for deep exploration
When the answer needs real code execution, a live demo, or tracing through multiple files: it spawns a subagent in its own container, delegates the task, and reports back.

"Good question. Let me spin up a subagent to trace how a message flows from Telegram through wire to the agent container. Back in a sec."
Question typeResponse strategyTool used
"How does X work?"Explain from CLAUDE.md knowledgenone
"Where is X in the code?"Link with line numbersGitHub API (tap-injected)
"Can you show me X in action?"Spawn subagent, demo, reportspawn_subagent
"Why did you choose X over Y?"Explain from design decisions in personalitynone
"Is there an issue tracking Z?"Search GitHub issuesGitHub API (tap-injected)

Milestones

Support monitors the project for events worth celebrating. Not every commit. Not every star. Events with meaning.

What counts
  • First release in a new phase (v1.0, v2.0)
  • Star milestones (100, 500, 1k...)
  • First contribution from a new developer
  • Merged PR that closed a hard-fought issue
  • Hitting a release target on time
  • Breaking changes (significant refactors)
What doesn't count
  • Every commit, every PR
  • Documentation updates
  • CI passes
  • Same milestone twice (state-tracked)
  • Non-events dressed as milestones
State tracking prevents spam

The agent maintains an announced-milestones log in its group folder. Before celebrating, it checks whether this milestone was already posted. This is per-agent-instance state — different from the CLAUDE.md personality, it's the running memory of what was said. NanoClaw's per-group CLAUDE.md approach handles this naturally: the agent reads and writes its own state file at the start and end of each turn.

Event sources

Support polls GitHub via scheduled tasks (Kanipi inherits NanoClaw's cron/interval scheduler):

agents:
  support:
    schedule:
      - type: poll
        target: github:releases
        interval: 1h
      - type: poll
        target: github:stars
        interval: 6h

V2: webhook support replaces polling — GitHub pushes events to the agent instead of the agent asking.

Configuration

config.yaml

agents:
  support:
    personality: |
      You are the Support agent for [project-name].
      You live in the Telegram dev group.

      ## Project
      Repository: github.com/[org]/[repo]
      Stack: TypeScript, Docker, NanoClaw
      Key insight: "Zero SDK imports on the host — the container is a plugin slot."

      ## Code Help Mode
      Help developers understand the codebase.
      - Ask clarifying questions when needed
      - Link to source with file + line numbers
      - Spawn subagents for deep code exploration
      - Admit what you don't know

      ## Celebration Triggers
      - New release (mention what changed, not just the version number)
      - Star milestones: 100, 500, 1k...
      - First contribution from a new developer (name them)
      - Hard-fought PRs that close major issues

      ## Tone
      Genuine excitement, technical specificity.
      Never: corporate cheerfulness, hollow encouragement, emoji spam.
      Yes: "Just merged the credential injection patch. Secrets stay out of process
            memory now. Real fix, not a workaround."
      No: "Amazing work team! The future is bright! 🎉🎉🎉"

      ## State
      Check /srv/data/kanipi/support/milestones.md before celebrating.
      Write to it after. No duplicate celebrations.
    image: kanipi/agent:latest
    network: true

Tap middleware routes

tap:
  routes:
    - pattern: "tools/github/*"
      action: inject-credential
      credential: GITHUB_TOKEN
      as: header
      name: Authorization
      prefix: "token "

    - pattern: "tools/github/*"
      action: rate-limit
      max_per_minute: 10

    - pattern: "tools/twitter/*"
      action: reject
      reason: "Support does not have Twitter access"

    - pattern: "tools/email/*"
      action: reject
      reason: "Support does not have email access"

What Kanipi provides

PrimitiveUsed for
Wire (Tier 3: Channel)Route all messages from the Telegram dev group to this agent
Tap: inject-credentialGitHub API token injected at tool call time, never in process memory
Tap: rejectBlock Twitter/email tool calls — this agent doesn't own those credentials
Per-agent CLAUDE.mdProject facts, celebration triggers, code help mode, tone guidelines
Container isolationSupport can't read Evangelist's Twitter keys even if compromised
Subagent modelEach subagent gets its own container + IPC directory for deep code tasks
Scheduled pollingHourly GitHub check for releases, 6h check for star milestones

Links

Related