Skip to content

Comments

feat: add plugin system with events and hooks#127

Open
steven1522 wants to merge 3 commits intoTinyAGI:mainfrom
steven1522:feature/plugin-system
Open

feat: add plugin system with events and hooks#127
steven1522 wants to merge 3 commits intoTinyAGI:mainfrom
steven1522:feature/plugin-system

Conversation

@steven1522
Copy link

Summary

Add a lightweight plugin system to TinyClaw that enables:

  • Events: Broadcast state changes so plugins can visualize (e.g., 3D avatar watching Claude work)
  • Hooks: Transform messages between LLM and channels (e.g., convert **bold** to channel-specific formatting)

Plugins auto-discover from .tinyclaw/plugins/ folder.

Changes

Plugin System (new)

  • src/lib/plugins.ts - Core plugin loader, event broadcasting, and hook runner
  • Plugins export activate(ctx) function and/or hooks object from index.ts
  • Events broadcast to registered handlers when emitEvent() is called
  • Hooks can return metadata (e.g., parseMode: 'MarkdownV2' for Telegram)

Integration

  • src/lib/logging.ts - Broadcasts events to plugin handlers
  • src/queue-processor.ts - Loads plugins at startup, runs incoming/outgoing hooks
  • src/channels/telegram-client.ts - Supports metadata.parseMode for rich formatting
  • src/lib/types.ts - Added metadata field to ResponseData

Bug Fixes (found during testing)

  • src/lib/invoke.ts - Strip CLAUDECODE env var so CLI works inside Claude Code sessions
  • .agents/.../send_message.ts - Remove message truncation, let channel clients chunk
  • src/queue-processor.ts - Remove handleLongResponse() truncation

Other

  • .gitignore - Expanded patterns for runtime files, secrets, plugins

Plugin API

// .tinyclaw/plugins/my-plugin/index.ts
import type { PluginContext, Hooks } from '../../src/lib/plugins';

// Subscribe to events
export function activate(ctx: PluginContext): void {
  ctx.on('chain_step_start', (e) => { /* agent thinking */ });
  ctx.on('response_ready', (e) => { /* agent done */ });
}

// Transform messages
export const hooks: Hooks = {
  transformOutgoing(message, ctx) {
    if (ctx.channel !== 'telegram') return message;
    return { text: formatted, metadata: { parseMode: 'MarkdownV2' } };
  }
};

Test Plan

  • Build compiles without errors
  • Tested on separate device with Telegram channel
  • Long messages properly chunked into multiple sends
  • Plugin loading works with empty/missing plugins folder

steven1522 and others added 2 commits February 19, 2026 13:46
Plugin System:
- Add src/lib/plugins.ts - auto-discovers plugins from .tinyclaw/plugins/
- Events broadcast to plugin handlers for visualization (3D avatar, etc.)
- Hooks transform incoming/outgoing messages per channel
- Metadata support (e.g., Telegram MarkdownV2 parseMode)

Bug Fixes (found during testing):
- Remove message truncation - let channel clients chunk long messages
- Strip CLAUDECODE env var so CLI works inside Claude Code sessions

Files changed:
- src/lib/plugins.ts (new)
- src/lib/logging.ts, types.ts, queue-processor.ts (plugin integration)
- src/channels/telegram-client.ts (metadata/parseMode support)
- src/lib/invoke.ts (CLAUDECODE fix)
- .agents/.../send_message.ts (remove truncation)
- .gitignore (expanded patterns)
Prevents messages from getting stuck in an infinite retry loop when
Telegram rejects malformed MarkdownV2. On failure, retries without
parse_mode so the message still gets delivered.
@jlia0
Copy link
Collaborator

jlia0 commented Feb 20, 2026

@codex review this PR for adding plugin system

@chatgpt-codex-connector
Copy link

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Re-queuing orphaned files caused infinite restart loops when the agent
triggered a tinyclaw restart — the same message would get recovered and
processed again, triggering another restart. Now orphaned files are
simply deleted on startup.
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