@poncho-ai/cli 0.21.13 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@poncho-ai/cli",
3
- "version": "0.21.13",
3
+ "version": "0.22.0",
4
4
  "description": "CLI for building and deploying AI agents",
5
5
  "repository": {
6
6
  "type": "git",
@@ -27,9 +27,9 @@
27
27
  "react": "^19.2.4",
28
28
  "react-devtools-core": "^6.1.5",
29
29
  "yaml": "^2.8.1",
30
- "@poncho-ai/harness": "0.20.9",
31
- "@poncho-ai/messaging": "0.2.9",
32
- "@poncho-ai/sdk": "1.4.0"
30
+ "@poncho-ai/harness": "0.20.11",
31
+ "@poncho-ai/messaging": "0.3.0",
32
+ "@poncho-ai/sdk": "1.4.1"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@types/busboy": "^1.5.4",
package/src/index.ts CHANGED
@@ -36,6 +36,7 @@ import {
36
36
  AgentBridge,
37
37
  ResendAdapter,
38
38
  SlackAdapter,
39
+ TelegramAdapter,
39
40
  type AgentRunner,
40
41
  type MessagingAdapter,
41
42
  type RouteRegistrar,
@@ -626,6 +627,32 @@ Connect your agent to Slack so it responds to @mentions:
626
627
 
627
628
  **Vercel deployments:** install \`@vercel/functions\` so Poncho can keep the serverless function alive while processing: \`npm install @vercel/functions\`
628
629
 
630
+ ## Messaging (Telegram)
631
+
632
+ Connect your agent to Telegram so it responds to messages and @mentions:
633
+
634
+ 1. Talk to [@BotFather](https://t.me/BotFather) on Telegram, send \`/newbot\`, and follow the prompts
635
+ 2. Copy the Bot Token
636
+ 3. Set env vars:
637
+ \`\`\`
638
+ TELEGRAM_BOT_TOKEN=123456:ABC-...
639
+ TELEGRAM_WEBHOOK_SECRET=my-secret-token # optional but recommended
640
+ \`\`\`
641
+ 4. Add to \`poncho.config.js\`:
642
+ \`\`\`javascript
643
+ messaging: [{ platform: 'telegram' }]
644
+ \`\`\`
645
+ 5. Register the webhook after deploying:
646
+ \`\`\`bash
647
+ curl -X POST "https://api.telegram.org/bot<TOKEN>/setWebhook" \\
648
+ -H "Content-Type: application/json" \\
649
+ -d '{"url": "https://<your-url>/api/messaging/telegram", "secret_token": "<SECRET>"}'
650
+ \`\`\`
651
+
652
+ The bot responds to all messages in private chats and only to @mentions in groups. Use \`/new\` to reset the conversation.
653
+
654
+ **Vercel deployments:** install \`@vercel/functions\` so Poncho can keep the serverless function alive while processing: \`npm install @vercel/functions\`
655
+
629
656
  ## Messaging (Email via Resend)
630
657
 
631
658
  Connect your agent to email so users can interact by sending emails:
@@ -1155,8 +1182,34 @@ CMD ["node","server.js"]
1155
1182
  return writtenPaths;
1156
1183
  };
1157
1184
 
1185
+ const serializeJs = (value: unknown, indent = 0): string => {
1186
+ const pad = " ".repeat(indent);
1187
+ const padInner = " ".repeat(indent + 1);
1188
+ if (value === null || value === undefined) return String(value);
1189
+ if (typeof value === "boolean" || typeof value === "number") return String(value);
1190
+ if (typeof value === "string") return JSON.stringify(value);
1191
+ if (Array.isArray(value)) {
1192
+ if (value.length === 0) return "[]";
1193
+ const items = value.map((v) => `${padInner}${serializeJs(v, indent + 1)}`);
1194
+ return `[\n${items.join(",\n")},\n${pad}]`;
1195
+ }
1196
+ if (typeof value === "object") {
1197
+ const entries = Object.entries(value as Record<string, unknown>).filter(
1198
+ ([, v]) => v !== undefined,
1199
+ );
1200
+ if (entries.length === 0) return "{}";
1201
+ const safeKey = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
1202
+ const lines = entries.map(([k, v]) => {
1203
+ const key = safeKey.test(k) ? k : JSON.stringify(k);
1204
+ return `${padInner}${key}: ${serializeJs(v, indent + 1)}`;
1205
+ });
1206
+ return `{\n${lines.join(",\n")},\n${pad}}`;
1207
+ }
1208
+ return String(value);
1209
+ };
1210
+
1158
1211
  const renderConfigFile = (config: PonchoConfig): string =>
1159
- `export default ${JSON.stringify(config, null, 2)}\n`;
1212
+ `export default ${serializeJs(config)}\n`;
1160
1213
 
1161
1214
  const writeConfigFile = async (workingDir: string, config: PonchoConfig): Promise<void> => {
1162
1215
  const serialized = renderConfigFile(config);
@@ -2422,6 +2475,27 @@ export const createRequestHandler = async (options?: {
2422
2475
  ` Resend email messaging disabled: ${err instanceof Error ? err.message : String(err)}`,
2423
2476
  );
2424
2477
  }
2478
+ } else if (channelConfig.platform === "telegram") {
2479
+ const adapter = new TelegramAdapter({
2480
+ botTokenEnv: channelConfig.botTokenEnv,
2481
+ webhookSecretEnv: channelConfig.webhookSecretEnv,
2482
+ });
2483
+ const bridge = new AgentBridge({
2484
+ adapter,
2485
+ runner: messagingRunner,
2486
+ waitUntil: waitUntilHook,
2487
+ ownerId: "local-owner",
2488
+ });
2489
+ try {
2490
+ await bridge.start();
2491
+ adapter.registerRoutes(messagingRouteRegistrar);
2492
+ messagingBridges.push(bridge);
2493
+ console.log(` Telegram messaging enabled at /api/messaging/telegram`);
2494
+ } catch (err) {
2495
+ console.warn(
2496
+ ` Telegram messaging disabled: ${err instanceof Error ? err.message : String(err)}`,
2497
+ );
2498
+ }
2425
2499
  }
2426
2500
  }
2427
2501
  }