Skip to content

slack-bridge: expose current Pinet persona to other extensions (event + env vars) #759

@tmustier

Description

@tmustier

Problem

Third-party Pi extensions that want to act on the current Pinet persona identity (agent name, emoji, traits) have no first-class way to discover it at runtime. The identity is generated by slack-bridge (generateAgentName / resolveAgentPersonality in slack-bridge/helpers.ts) and woven into the system prompt and Slack messages, but it is not exposed to other extensions via any documented surface.

Concrete example: I just built a voice extension (ElevenLabs TTS, plays every assistant reply through afplay) and want to give every Pinet persona a unique voice — Bear gets a warm/narrative voice, Fox gets a bright/punchy one, etc. Today the only way for that extension to learn its own persona is to regex the system prompt for the identity prefix line (`<name>` reporting from `<host>`). That works but is fragile to any future change in the prefix format.

Proposed solution

Have slack-bridge publish the current persona via two complementary mechanisms:

  1. Pi event — emit a persona_changed (or pinet_persona) event on pi.events whenever the identity is resolved, refreshed, or restored from persisted state. Payload shape:

    interface PinetPersonaEvent {
      name: string;          // "Radiant Rose Bear"
      emoji: string;          // "🐻"
      role: "broker" | "worker";
      descriptor?: string;    // "Radiant"
      color?: string;         // "Rose"
      animal?: string;        // "Bear"
      traits: string[];       // ["energetic","steady","expressive","resilient"]
      stableId?: string;      // for cache keys across restarts
    }

    Fire it once after session_start resolution completes, and again on any setAgentName(...) call.

  2. Env var — export PINET_AGENT_NAME, PINET_AGENT_EMOJI, PINET_AGENT_ROLE, PINET_AGENT_TRAITS (comma-separated) in the child pi process environment, so non-extension consumers (skills, shell helpers) can see them too.

Both should be safe to add without breaking existing behaviour — they are additive.

Workaround in use today

In a voice extension I just shipped locally, I parse ctx.getSystemPrompt() in before_agent_start for the identity prefix line. Code sketch:

const m = systemPrompt.match(/'([^\s]+)\s+`([^`]+)`\s+reporting from\s+`([^`]+)`/);
if (m) {
  const emoji = m[1];
  const name = m[2];
  // …pick voice from traits derived from name…
}

This is the same parsing the system prompt itself describes for the agent — fragile but functional. Happy to migrate the extension to a first-class event/env var the moment one exists.

Notes / open questions

  • Should the event also include the personalityGuidelines array, or just the raw traits? My instinct: raw traits + descriptor/animal, and let consumers re-derive any text they want.
  • Worth caching the last fired payload so a late-loaded extension can subscribe and immediately receive a replay via a method like pi.events.getLast("persona_changed").
  • Is the stableId safe to publish? It would help downstream caches like ~/.pi/agent/voice-personas.yaml key on something better than the display name.

Happy to send a PR if the direction is right — let me know which of (1)/(2)/both you want.

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