Gateway Session Address

Stable, shareable session URLs — no raw UUIDs, reconnect-safe

Every Gateway session gets a stable, shareable address like chat/<agentId>/<slug>-<shortId> so a link works across reconnects and never leaks the raw UUID.

Diagram

🔑 session key

🔧 build_session_path

🔗 shareable URL

🧩 parse_session_path

📇 SessionRef

🔍 resolver

✅ session id

Quick Start

  1. Build a shareable URL

    Turn a runtime session key into a stable URL segment.

    python
    from praisonaiagents import Agent
    from praisonaiagents.gateway import build_session_path
    
    agent = Agent(name="assistant", instructions="Be helpful.")
    agent.start("Kick off a session")
    
    url = build_session_path(
        agent_id="assistant",
        session_key="agent:assistant:a3f9c2e1-7b04-4c8e-9f21-1234abcd5678",
        display_name="Quarterly report",
    )
    # -> "chat/assistant/quarterly-report-abcd5678"
  2. Parse a path back into a SessionRef

    Recover the reference a resolver looks up.

    python
    from praisonaiagents.gateway import parse_session_path
    
    ref = parse_session_path("chat/assistant/quarterly-report-abcd5678")
    # SessionRef(agent_id="assistant", short_id="abcd5678", slug_hint="quarterly-report")

How It Works

A client sends a friendly path; the gateway’s session.resolve maps it back to a concrete session id.

Diagram
StoreResolverGateway (session.resolve)ClientStoreResolverGateway (session.resolve)Clientsession.resolve(“chat/assistant/quarterly-report-abcd5678”)SessionRef(agent_id, short_id, slug_hint)lookup short id scoped to agentsession_idsession_idsession_id
URL segmentSessionRef fieldWhat the resolver uses
<agentId>agent_idScopes the lookup — short ids only unique per agent
<shortId>short_idPrimary key the resolver matches against
<slug>slug_hintHuman label hint; also carries a reserved-name sentinel
!<key>literal_keyExact key from the escape hatch

User interaction flow

A user copies a chat URL from their laptop and pastes it on their phone. The mobile client calls session.resolve with the friendly path; the gateway returns the concrete session id and the same conversation reopens — no raw UUID ever changed hands.

Diagram
GatewayPhoneLaptopGatewayPhoneLaptopcopy chat/assistant/quarterly-report-abcd5678paste linksession.resolve(path)session_idrejoin session_idsame conversation reopens

The four addressing forms

Pick the form that matches how much the URL should reveal.

Diagram

Has a display label

No label

Well-known session

Key must stay literal

How is the session named?

chat/agent/slug-shortId

chat/agent/shortId

chat/agent/main

chat/agent/!key

FormWhen it appears
chat/<agent>/<slug>-<shortId>Default — a session with a display name
chat/<agent>/<shortId>No display name to slug
chat/<agent>/main (global / default / root)Reserved sentinel — a well-known named session
chat/<agent>/!<percent-encoded-key>Literal-key escape hatch for file-like keys

Configuration Options

These are pure functions and constants — no config class.

Function / fieldParameterTypeDefaultDescription
build_session_pathagent_idstr—Agent id (scopes short-id uniqueness)
build_session_pathsession_keystr—Opaque runtime key (usually contains a UUID tail)
build_session_pathdisplay_nameOptional[str]NoneHuman label used to derive the slug
build_session_pathnamespacestr"chat"Leading namespace segment
slugifydisplay_nameOptional[str]—Human label to slugify
slugifymax_lenint48Max slug length before truncation
derive_short_idsession_keystr—Key whose terminating hex run is shortened
parse_session_pathpathstr—Path to parse into a SessionRef
SessionRefagent_idstr—Scopes short-id lookup
SessionRefshort_idOptional[str]NoneShort id the resolver looks up
SessionRefslug_hintOptional[str]NoneSlug/label hint; also carries a reserved-name sentinel
SessionRefliteral_keyOptional[str]NoneExact key from the !-escape hatch
constantSHORT_ID_LENint8Length of derived short ids
constantRESERVED_NAMESfrozenset[str]{"main","global","default","root"}Sentinel final segments

All seven symbols import from one place:

python
from praisonaiagents.gateway import (
    SessionRef,
    build_session_path,
    parse_session_path,
    derive_short_id,
    slugify,
    RESERVED_NAMES,
    SHORT_ID_LEN,
)

Common Patterns

Dashboard deep-link — build a shareable URL from an agent plus its session key.

python
from praisonaiagents.gateway import build_session_path

link = build_session_path(
    agent_id="assistant",
    session_key="agent:assistant:a3f9c2e1-7b04-4c8e-9f21-1234abcd5678",
    display_name="Quarterly report",
)
# -> "chat/assistant/quarterly-report-abcd5678"

Cross-device reconnect — parse an incoming path, then ask the gateway to resolve it.

python
from praisonaiagents.gateway import parse_session_path

ref = parse_session_path("chat/assistant/quarterly-report-abcd5678")
# Hand ref to session.resolve; the concrete resolver handler is a wrapper follow-up.

File-like key round-trip — keys that look like assets survive losslessly via the escape hatch.

python
from praisonaiagents.gateway import build_session_path, parse_session_path

path = build_session_path("bot", "report.js")
# -> "chat/bot/!report.js"
ref = parse_session_path(path)
# SessionRef(agent_id="bot", literal_key="report.js")

Best Practices

Prefer short-id + slug over the literal escape hatch

The !<key> form exposes the whole key in the URL. Let build_session_path derive a short id whenever the key has a UUID tail so the raw key stays hidden.

Keep short ids per-agent

Short ids only need to be unique within one agent’s namespace — agent_id scopes the lookup, and a resolver disambiguates the rare clash.

Treat main / global / default / root as named sessions

Reserved sentinels are friendly named sessions, not short-id lookups. A resolver maps them to a well-known session such as the agent’s main conversation.

Never rebuild an agent_id by concatenation

Always percent-escape via build_session_path and let parse_session_path decode. An id containing / (e.g. team/assistant) round-trips correctly only when it goes through the grammar.


Related