@ngdtrung/video-tools
Agent skills for educational video production, plus a Pi extension that lets agents talk to you on Telegram (approvals, questions, and direct instructions).
Package details
Install @ngdtrung/video-tools from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@ngdtrung/video-tools- Package
@ngdtrung/video-tools- Version
0.0.1- Published
- Sep 23, 2026
- Downloads
- 204/mo · 24/wk
- Author
- ngdtrung
- License
- unknown
- Types
- extension, skill
- Size
- 1.7 MB
- Dependencies
- 0 dependencies · 0 peers
Pi manifest JSON
{
"extensions": [
"./extensions/pi/telegram-approval.ts"
],
"skills": [
"./skills"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
video-tools
Agent skills for educational video production, plus a Pi extension that lets agents talk to you on Telegram (approvals, questions, and direct instructions).
extensions/pi/telegram-approval.ts Pi extension: approvals + ask_user + agent mailbox
(also the inbox daemon: run with --telegram-inboxd)
extensions/pi/telegram-approval.test.ts
extensions/pi/telegram-inboxd.test.ts
skills/ Agent skills (SKILL.md format)
Telegram extension
One bot, one chat, many agents. Agents ask for approval or free-form answers; you can also send instructions to a running agent at any time.
Setup
Create a bot via @BotFather →
/newbot→ copy the token.Get your chat id: message your bot, then open
https://api.telegram.org/bot<TOKEN>/getUpdatesand readchat.id.Export env vars (put in your shell profile):
export TELEGRAM_BOT_TOKEN="123456:ABC..." export TELEGRAM_CHAT_ID="123456789"Install the extension — two options:
pi install(recommended) — the repo is a pi package (pimanifest inpackage.jsondeclares the extension + all skills):pi install npm:@ngdtrung/video-tools # from npm (recommended) pi install git:github.com/ductrung-nguyen/video-tools # or straight from GitHub pi install /path/to/video-tools # or a local cloneAdd
-lto install into project settings (.pi/settings.json) instead of user settings. Manage withpi list/pi remove/pi config.Manual symlink — if you want live repo edits:
git clone git@github.com:ductrung-nguyen/video-tools.git cd video-tools mkdir -p ~/.pi/agent/extensions ln -sfn "$(pwd)/extensions/pi/telegram-approval.ts" \ ~/.pi/agent/extensions/telegram-approval.tsOne file is all you need: the extension spawns itself as the inbox daemon (
--telegram-inboxdflag), so there is no second file to install.Start
pi— a🟢 [agent:name] onlinecard appears in your chat.
Talking to agents
| You send | What happens |
|---|---|
| Reply to an agent's card | Instruction injected into that agent |
@name do X |
Instruction to agent name |
!do X (or @name !do X) |
Interrupt/steer the current turn |
/msg @name text |
Same as @name (autocomplete-friendly) |
/steer @name text |
Same as ! prefix |
/agents or /start |
Live roster (also on the persistent keyboard) |
💬 Message / ⚡ Interrupt buttons on a card |
Bot prompts you; reply to the prompt |
#XXXXXX text |
Answer a specific pending request by tag |
| Bare text | Only routed when exactly one agent awaits your input |
Approval requests (request_approval tool) show ✅ Approve / ❌ Reject /
💬 Other buttons; Reject/Other then ask for a reason — reply to that prompt.
ask_user posts a question with optional quick-reply buttons; free text works
too (reply, #TAG, or bare text when unambiguous).
The inbox daemon
telegram-inboxd keeps the Telegram inbox warm and answers /agents even when
no agent is running. It is managed automatically:
session_startspawns it if absent (pidfile-guarded, single instance)session_shutdownstops it when the last agent session ends
| Env var | Effect |
|---|---|
TELEGRAM_INBOXD=keep |
Never stop it — always-on listener (recommended) |
TELEGRAM_INBOXD=off |
Never auto-spawn |
TELEGRAM_AGENT_NAME=… |
Stable agent name instead of name-xxxx |
TELEGRAM_STATE_DIR=… |
Override inbox location (default $TMPDIR/pi-telegram-approval) |
Standalone run: npm run inboxd (or under systemd --user / tmux / nohup).
How routing works (why it's safe with many agents)
Telegram getUpdates is single-consumer — polling with an offset deletes
updates server-side. All agent processes therefore share one on-disk inbox
($TMPDIR/pi-telegram-approval/inbox-<bot>-<chat>.json): only the process
holding a mkdir lock polls Telegram and stores every update; each agent then
claims only entries tagged with its request id (#XXXXXX) or agent name
(@name, [agent:name]). Ambiguous bare text is never stolen — it's marked
bareRejected and must be re-sent as a reply or with a tag.
Tests
npm test # 8 tests: approvals, anti-steal routing, mailbox, ask_user, daemon
Skills
Four skills in skills/, each a standard SKILL.md bundle:
| Skill | Purpose | Extra requirements |
|---|---|---|
teaching-video-studio |
End-to-end educational video production (research → script → HyperFrames → voice → QA) | HyperFrames skills for rendering |
language-learning-video-studio |
Longitudinal language-learning video series with course memory | Same |
video-catalog |
SQLite catalog of produced videos (dedup, backlinks, publish queue) | sqlite3 with FTS5 |
minimax-tts |
MiniMax Speech 2.8 text-to-speech CLI | pip install requests, MINIMAX_API_KEY |
Skills are discovered from ~/.agents/skills/ (omp) and ~/.pi/agent/skills/
(pi). pi install already registers all skills via the package manifest; for
omp — or pi without the package — copy the skill into ~/.agents/skills/,
then symlink into pi:
REPO_DIR=$(pwd) # run inside your video-tools clone
# canonical copy for omp
cp -r "$REPO_DIR/skills/<name>" ~/.agents/skills/
# symlink for pi
ln -sfn ~/.agents/skills/<name> ~/.pi/agent/skills/<name>
Or symlink the repo directly if you want live edits:
ln -sfn "$REPO_DIR/skills/<name>" ~/.agents/skills/<name>
ln -sfn ~/.agents/skills/<name> ~/.pi/agent/skills/<name>
Repeat per skill. The agent picks them up on next session start.