You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-up documentation work triggered by MervinPraison/PraisonAI#1520 — fix(gateway): remove duplicate PairingStore.list_pending and preserve legacy keys (merged 2026-04-22).
That PR:
Removed a duplicate list_pending() method on PairingStore (the second definition was silently overriding the first at class-define time).
Consolidated the response so list_pending() now returns both the canonical keys used by the CLI / tests and the UI-friendly aliases used by the praisonai.ui._pairing banner.
Added optional channel_type filtering.
Because the PR codifies the stable response schema for list_pending() and surfaces the fact that multiple consumers (CLI, UI banner, REST endpoint GET /api/pairing/pending) depend on it, this is the right moment to close several existing documentation gaps around gateway pairing.
This issue is scoped for a doc-writing agent. All paths below are relative to the MervinPraison/PraisonAIDocs repo unless stated otherwise.
Note
Per AGENTS.md §1.8, all new/updated pages must live under docs/features/, docs/guides/, docs/cli/, docs/tools/, or docs/best-practices/ — never docs/concepts/. The existing Gateway Pairing content already lives in docs/best-practices/bot-security.mdx, which is allowed.
SDK Ground Truth (read these BEFORE writing docs)
Per AGENTS.md §1.2 (SDK-First Documentation Cycle), read each file before documenting any symbol from it. All paths are in MervinPraison/PraisonAI @ main (merged commit 3d8a3dc):
File
Why it matters
src/praisonai/praisonai/gateway/pairing.py
PairingStore class — authoritative for list_pending, list_paired, generate_code, verify_and_pair, is_paired, approve, revoke.
src/praisonai/praisonai/gateway/pairing_routes.py
Starlette routes — authoritative for GET /api/pairing/pending, POST /api/pairing/approve, POST /api/pairing/revoke.
src/praisonai/praisonai/cli/commands/pairing.py
typer app — authoritative for praisonai pairing {list,approve,revoke,clear} CLI subcommands.
src/praisonai/praisonai/cli/app.py
Line 537: app.add_typer(pairing_app, name="pairing", ...) registers the subcommand group.
src/praisonai/praisonai/ui/_pairing.py
UI banner consumer — confirms why the channel / user_id / user_name / age_seconds aliases are retained.
src/praisonai/praisonai/bots/_unknown_user.py (line 171) and _auth.py (line 129)
Both emit the hint praisonai pairing approve {platform} {code} to users — confirms the CLI command is public/user-facing.
Authoritative contract for `list_pending()[*]["code"
Recommendation: Update existing content, do NOT create a new page
After reviewing the change and the existing docs, this is an UPDATE, not a new page:
The Gateway Pairing section already exists in docs/best-practices/bot-security.mdx (lines ~215–265).
That section currently carries stale <Warning> callouts claiming the APIs are "planned functionality" and "conceptual". Those warnings are now incorrect — the APIs ship, are tested, and are referenced from the bot error messages users see in production.
There are real gaps (CLI subcommands, REST endpoints, list_pending response schema) that fit naturally as subsections of the existing Gateway Pairing area rather than a new top-level page.
If the existing section grows past ~300 lines after these updates, the doc author may split CLI and REST content into a dedicated docs/features/gateway-pairing.mdx page and link to it from bot-security.mdx. Default to updating in place.
Changes Required
Change 1 — Remove stale "planned functionality" warnings
File:docs/best-practices/bot-security.mdx
At lines ~217–219, remove:
<Warning>
**Note:** The pairing system described below represents planned functionality. Current SDK implementation may differ. Verify against actual SDK documentation.
</Warning>
Also remove the inline code comment # Note: This API is conceptual - verify implementation at ~line 236, and the # Note: Verify this API exists in current SDK at ~line 258.
Rationale:PairingStore ships today. Tests (test_gateway_approval.py) cover it. The CLI (praisonai pairing ...) is wired up in cli/app.py. Bot auth errors reference it. The warnings are misleading.
Keep the unrelated Doctor warning at ~line 269 unchanged — that one concerns a different command.
Change 2 — Document the list_pending() response schema
File:docs/best-practices/bot-security.mdx, inside the Gateway Pairing subsection (after the existing §4 "Check Status" block, ~line 265).
Add a new "List Pending Requests" subsection showing both keys. Follow AGENTS.md §6 style rules — one-sentence intros, active voice, no forbidden phrases.
Minimum code example:
frompraisonaiagents.gateway.pairingimportPairingStorestore=PairingStore()
# All pending codes across every channelforreqinstore.list_pending():
print(req["code"], req["channel_type"], req["channel_id"], req["age_seconds"])
# Filter by channeltelegram_only=store.list_pending(channel_type="telegram")
Important
The exact import path is from praisonaiagents.gateway.pairing import PairingStore only if the praisonaiagents package re-exports it. The ground-truth source file lives at src/praisonai/praisonai/gateway/pairing.py inside the praisonai CLI package, not praisonai-agents. Before publishing, the doc agent must verify the correct import path by checking praisonaiagents/gateway/__init__.py and praisonai/gateway/__init__.py in the synced source tree. Do not guess — AGENTS.md §1.2 forbids it.
Response schema table (extracted directly from pairing.py lines 295–305):
Key
Type
Source
Notes
code
str
canonical
8-char pairing code
channel_type
str
canonical
e.g. "telegram", "discord", "slack", "whatsapp"
channel_id
str | None
canonical
Bound channel id if code was generated with one
created_at
float
canonical
Unix timestamp (seconds) when code was generated
channel
str
UI alias
Same value as channel_type, kept for UI banner compatibility
user_id
str
UI alias
Currently equals code (see note in approve() docstring)
user_name
str
UI alias
Formatted as "User {code}"
age_seconds
int
UI alias
int(now - created_at)
Add a short <Note>:
Canonical keys (code, channel_type, channel_id, created_at) are the stable contract. The channel, user_id, user_name, and age_seconds aliases are provided for UI consumers and should not be relied on for scripting — use the canonical keys.
Change 3 — Document the praisonai pairing CLI subcommands
File: prefer extending existing docs/cli/bot.mdx with a new "Pairing Subcommands" section. If that page is the wrong home (check its scope first), create docs/cli/pairing.mdx and add it under the "CLI" group in docs.json (per AGENTS.md §1.8, never under "Concepts").
Commands to document (source: src/praisonai/praisonai/cli/commands/pairing.py):
Platform values:telegram, discord, slack, whatsapp (from typer Argument help text).
Required example — this is the exact command the bot prints to users, so it must appear verbatim in the docs:
praisonai pairing approve telegram abc12345
Include a Mermaid sequence diagram (per AGENTS.md §3.4) showing the end-to-end pairing flow:
User → Bot (DM) : unknown, triggers pairing
Bot → PairingStore : generate_code(channel_type, channel_id)
Bot → User : "Ask owner to run: praisonai pairing approve telegram abc12345"
Owner → CLI : praisonai pairing approve telegram abc12345
CLI → PairingStore : verify_and_pair()
PairingStore → Disk : _save() (atomic)
User → Bot : now authorised
Use the standard color palette from AGENTS.md §3.1 (dark red #8B0000 for Agent/User, teal #189AB4 for tools/CLI, green #10B981 for success, white text).
Change 4 — Document the REST API endpoints
Target file: pick one of:
Extend docs/best-practices/bot-security.mdx with a final "REST API" subsection, or
Create docs/features/gateway-pairing-api.mdx if content exceeds a few paragraphs. Register under the "Features" group in docs.json (never "Concepts").
Rate-limited via pairing_pending bucket when a rate limiter is attached
POST
/api/pairing/approve
{ "channel": str, "code": str }
{ "approved": true, ... }
Rate-limited via pairing_approve bucket
POST
/api/pairing/revoke
{ "channel": str, "user_id": str }
{ "revoked": true, ... }
Rate-limited via pairing_revoke bucket
The doc agent must read pairing_routes.py end-to-end to confirm the exact request/response JSON shapes and any auth requirements — auth_checker is a required constructor argument on create_pairing_routes(...), so these endpoints are authenticated; call that out explicitly.
Change 5 — (Optional but recommended) Add a feature-level troubleshooting note
The Troubleshooting → Pairing Issues block already exists (~line 462 of bot-security.mdx). Extend it with a new bullet covering the symptom fixed by this PR, phrased as user-facing guidance (not SDK-internal):
Symptom:praisonai pairing approve reports "Invalid or expired code" even though a code was just generated from the UI (or vice versa). Fix: Upgrade to praisonai >= <version that contains #1520>. Older builds shipped a duplicate internal method that stripped the canonical code key when the UI pairing banner was loaded.
The doc agent should replace <version that contains #1520> with the actual release version by checking CHANGELOG.md / pyproject.toml in MervinPraison/PraisonAI at the time of writing — do not leave the placeholder.
Out of Scope
Do not add or alter anything under docs/concepts/ (AGENTS.md §1.8 — human-approved only).
Do not touch auto-generated docs/js/* or docs/rust/* parity pages.
Do not document PairingStore._pending, _paired, _save, _prune_expired, or any other underscore-prefixed internals.
Do not regenerate docs.json from scratch — apply minimal additions only.
Acceptance Criteria
Stale "planned functionality" warnings in docs/best-practices/bot-security.mdx removed.
list_pending() response schema documented with both canonical + alias keys and a <Note> clarifying which to rely on.
praisonai pairing list | approve | revoke | clear documented with the exact approve telegram abc12345 command shown verbatim (matches the string emitted by _unknown_user.py and _auth.py).
/api/pairing/{pending,approve,revoke} documented with auth + rate-limit notes.
Mermaid diagram follows the §3.1 color palette (white text, #8B0000 / #189AB4 / #10B981).
Every code example runs copy-paste, includes all imports, uses no placeholder secrets (AGENTS.md §5.1).
Import paths verified against the actual praisonaiagents/gateway/__init__.py / praisonai/gateway/__init__.py — no guesses.
The working branch per the session instructions is claude/admiring-euler-ODEBP. Create and push to that branch, then open a draft PR against main in MervinPraison/PraisonAIDocs.
Remember AGENTS.md §1.1 item 6: these docs are user-focused, not SDK-focused. The auto-generated SDK reference covers parameter-by-parameter detail. This issue's target audience is a self-hosting bot operator who wants to know: "how do I approve a pending channel without reading Python source?"
Context
Follow-up documentation work triggered by MervinPraison/PraisonAI#1520 — fix(gateway): remove duplicate
PairingStore.list_pendingand preserve legacy keys (merged 2026-04-22).That PR:
list_pending()method onPairingStore(the second definition was silently overriding the first at class-define time).list_pending()now returns both the canonical keys used by the CLI / tests and the UI-friendly aliases used by thepraisonai.ui._pairingbanner.channel_typefiltering.Because the PR codifies the stable response schema for
list_pending()and surfaces the fact that multiple consumers (CLI, UI banner, REST endpointGET /api/pairing/pending) depend on it, this is the right moment to close several existing documentation gaps around gateway pairing.This issue is scoped for a doc-writing agent. All paths below are relative to the
MervinPraison/PraisonAIDocsrepo unless stated otherwise.Note
Per
AGENTS.md§1.8, all new/updated pages must live underdocs/features/,docs/guides/,docs/cli/,docs/tools/, ordocs/best-practices/— neverdocs/concepts/. The existing Gateway Pairing content already lives indocs/best-practices/bot-security.mdx, which is allowed.SDK Ground Truth (read these BEFORE writing docs)
Per
AGENTS.md§1.2 (SDK-First Documentation Cycle), read each file before documenting any symbol from it. All paths are inMervinPraison/PraisonAI@main(merged commit3d8a3dc):src/praisonai/praisonai/gateway/pairing.pyPairingStoreclass — authoritative forlist_pending,list_paired,generate_code,verify_and_pair,is_paired,approve,revoke.src/praisonai/praisonai/gateway/pairing_routes.pyGET /api/pairing/pending,POST /api/pairing/approve,POST /api/pairing/revoke.src/praisonai/praisonai/cli/commands/pairing.pytyperapp — authoritative forpraisonai pairing {list,approve,revoke,clear}CLI subcommands.src/praisonai/praisonai/cli/app.pyapp.add_typer(pairing_app, name="pairing", ...)registers the subcommand group.src/praisonai/praisonai/ui/_pairing.pychannel/user_id/user_name/age_secondsaliases are retained.src/praisonai/praisonai/bots/_unknown_user.py(line 171) and_auth.py(line 129)praisonai pairing approve {platform} {code}to users — confirms the CLI command is public/user-facing.src/praisonai/tests/unit/gateway/test_gateway_approval.py::test_pending_persists_across_instancesRecommendation: Update existing content, do NOT create a new page
After reviewing the change and the existing docs, this is an UPDATE, not a new page:
docs/best-practices/bot-security.mdx(lines ~215–265).<Warning>callouts claiming the APIs are "planned functionality" and "conceptual". Those warnings are now incorrect — the APIs ship, are tested, and are referenced from the bot error messages users see in production.list_pendingresponse schema) that fit naturally as subsections of the existing Gateway Pairing area rather than a new top-level page.If the existing section grows past ~300 lines after these updates, the doc author may split CLI and REST content into a dedicated
docs/features/gateway-pairing.mdxpage and link to it frombot-security.mdx. Default to updating in place.Changes Required
Change 1 — Remove stale "planned functionality" warnings
File:
docs/best-practices/bot-security.mdxAt lines ~217–219, remove:
Also remove the inline code comment
# Note: This API is conceptual - verify implementationat ~line 236, and the# Note: Verify this API exists in current SDKat ~line 258.Rationale:
PairingStoreships today. Tests (test_gateway_approval.py) cover it. The CLI (praisonai pairing ...) is wired up incli/app.py. Bot auth errors reference it. The warnings are misleading.Keep the unrelated Doctor warning at ~line 269 unchanged — that one concerns a different command.
Change 2 — Document the
list_pending()response schemaFile:
docs/best-practices/bot-security.mdx, inside the Gateway Pairing subsection (after the existing §4 "Check Status" block, ~line 265).Add a new "List Pending Requests" subsection showing both keys. Follow
AGENTS.md§6 style rules — one-sentence intros, active voice, no forbidden phrases.Minimum code example:
Important
The exact import path is
from praisonaiagents.gateway.pairing import PairingStoreonly if thepraisonaiagentspackage re-exports it. The ground-truth source file lives atsrc/praisonai/praisonai/gateway/pairing.pyinside thepraisonaiCLI package, notpraisonai-agents. Before publishing, the doc agent must verify the correct import path by checkingpraisonaiagents/gateway/__init__.pyandpraisonai/gateway/__init__.pyin the synced source tree. Do not guess —AGENTS.md§1.2 forbids it.Response schema table (extracted directly from
pairing.pylines 295–305):codestrchannel_typestr"telegram","discord","slack","whatsapp"channel_idstr | Nonecreated_atfloatchannelstrchannel_type, kept for UI banner compatibilityuser_idstrcode(see note inapprove()docstring)user_namestr"User {code}"age_secondsintint(now - created_at)Add a short
<Note>:Change 3 — Document the
praisonai pairingCLI subcommandsFile: prefer extending existing
docs/cli/bot.mdxwith a new "Pairing Subcommands" section. If that page is the wrong home (check its scope first), createdocs/cli/pairing.mdxand add it under the "CLI" group indocs.json(perAGENTS.md§1.8, never under "Concepts").Commands to document (source:
src/praisonai/praisonai/cli/commands/pairing.py):praisonai pairing list--store-dirpraisonai pairing approve PLATFORM CODE [CHANNEL_ID]platform,code, optionalchannel_id--label,--store-dirpraisonai pairing revoke PLATFORM CHANNEL_IDplatform,channel_id--store-dirpraisonai pairing clear--store-dir(verify flags in source)Platform values:
telegram,discord,slack,whatsapp(from typerArgumenthelp text).Required example — this is the exact command the bot prints to users, so it must appear verbatim in the docs:
Include a Mermaid sequence diagram (per
AGENTS.md§3.4) showing the end-to-end pairing flow:Use the standard color palette from
AGENTS.md§3.1 (dark red#8B0000for Agent/User, teal#189AB4for tools/CLI, green#10B981for success, white text).Change 4 — Document the REST API endpoints
Target file: pick one of:
docs/best-practices/bot-security.mdxwith a final "REST API" subsection, ordocs/features/gateway-pairing-api.mdxif content exceeds a few paragraphs. Register under the "Features" group indocs.json(never "Concepts").Endpoints (source:
src/praisonai/praisonai/gateway/pairing_routes.py):GET/api/pairing/pendinglist_pending()schema (see Change 2)pairing_pendingbucket when a rate limiter is attachedPOST/api/pairing/approve{ "channel": str, "code": str }{ "approved": true, ... }pairing_approvebucketPOST/api/pairing/revoke{ "channel": str, "user_id": str }{ "revoked": true, ... }pairing_revokebucketThe doc agent must read
pairing_routes.pyend-to-end to confirm the exact request/response JSON shapes and any auth requirements —auth_checkeris a required constructor argument oncreate_pairing_routes(...), so these endpoints are authenticated; call that out explicitly.Change 5 — (Optional but recommended) Add a feature-level troubleshooting note
The Troubleshooting → Pairing Issues block already exists (~line 462 of
bot-security.mdx). Extend it with a new bullet covering the symptom fixed by this PR, phrased as user-facing guidance (not SDK-internal):The doc agent should replace
<version that contains #1520>with the actual release version by checkingCHANGELOG.md/pyproject.tomlinMervinPraison/PraisonAIat the time of writing — do not leave the placeholder.Out of Scope
docs/concepts/(AGENTS.md§1.8 — human-approved only).docs/js/*ordocs/rust/*parity pages.PairingStore._pending,_paired,_save,_prune_expired, or any other underscore-prefixed internals.docs.jsonfrom scratch — apply minimal additions only.Acceptance Criteria
docs/best-practices/bot-security.mdxremoved.list_pending()response schema documented with both canonical + alias keys and a<Note>clarifying which to rely on.praisonai pairing list | approve | revoke | cleardocumented with the exactapprove telegram abc12345command shown verbatim (matches the string emitted by_unknown_user.pyand_auth.py)./api/pairing/{pending,approve,revoke}documented with auth + rate-limit notes.#8B0000/#189AB4/#10B981).AGENTS.md§5.1).praisonaiagents/gateway/__init__.py/praisonai/gateway/__init__.py— no guesses.docs.jsonJSON validation (AGENTS.md§1.9 rule 8).Notes for the Doc Agent
The working branch per the session instructions is
claude/admiring-euler-ODEBP. Create and push to that branch, then open a draft PR againstmaininMervinPraison/PraisonAIDocs.Remember
AGENTS.md§1.1 item 6: these docs are user-focused, not SDK-focused. The auto-generated SDK reference covers parameter-by-parameter detail. This issue's target audience is a self-hosting bot operator who wants to know: "how do I approve a pending channel without reading Python source?"