Add cross-agent-handoff example (shared session across agents) - #387
Add cross-agent-handoff example (shared session across agents)#387HarshaNalluru wants to merge 3 commits into
Conversation
|
|
||
| # unique per run so the demo starts clean; in production use a stable id such | ||
| # as the call / conversation id so the same session is resumable later. | ||
| session_name = f"call-handoff-demo-{uuid.uuid4().hex[:8]}" |
There was a problem hiding this comment.
CONSIDER session_name = f"call-handoff-demo-{uuid.uuid4().hex[:8]}"
Because this session is immediately push_index()ed, every run creates a new cloud index with a random name and no cleanup path. That can leak indexes/docs into a user's project just from trying the demo. Either use a stable demo name that is reused, or clean up in main() after the handoff completes, e.g. try: ... finally: await _client().delete_index(session_name).
Codex reviewThe new live-labs handoff example is straightforward and mostly follows the existing session pattern. The main concern is that the runnable demo leaves persistent cloud state behind on every execution. |
There was a problem hiding this comment.
Pull request overview
Adds a new experimental runnable Python example under moss-live-labs/ demonstrating cross-agent handoff by having multiple agents share a single named Moss session (agent A writes + pushes; agent B resumes and queries).
Changes:
- Introduces a new
cross-agent-handoffexample script that simulates two independent agents using the same session name. - Adds minimal project scaffolding for running the example via
uv(pyproject, lockfile, env template, python version pin). - Documents the concept and run instructions in a new README.
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| moss-live-labs/examples/cross-agent-handoff/cross_agent_handoff.py | New runnable example simulating agent A session push and agent B resume/query flow. |
| moss-live-labs/examples/cross-agent-handoff/README.md | Explains the handoff concept and how to run the demo. |
| moss-live-labs/examples/cross-agent-handoff/pyproject.toml | Defines a small uv project with moss + python-dotenv dependencies. |
| moss-live-labs/examples/cross-agent-handoff/uv.lock | Pins resolved dependencies for reproducible installs. |
| moss-live-labs/examples/cross-agent-handoff/.env.example | Template for required Moss credentials. |
| moss-live-labs/examples/cross-agent-handoff/.python-version | Pins the example’s Python version to 3.12. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ## Resources | ||
|
|
||
| - [Docs](https://docs.moss.dev/docs/build/cross-agent-handoff) |
| def _client() -> MossClient: | ||
| return MossClient( | ||
| project_id=os.environ["MOSS_PROJECT_ID"], | ||
| project_key=os.environ["MOSS_PROJECT_KEY"], | ||
| ) |
…g creds, root docs link
|
Addressed the review:
|
| # hand off: persist the session so any other agent can resume it | ||
| await session.push_index() | ||
| print("[agent A - chat] wrote 3 turns and pushed the session to the cloud\n") |
| The first agent opens a session by name, writes the conversation, and pushes it | ||
| to the cloud. The second agent, a different process or device, opens the *same* | ||
| session name. Because that index already exists, Moss resumes it (no | ||
| re-embedding), and the agent can query context it never directly received: |
|
Addressed the latest review:
|
| # hand off: push to the cloud. push_index() queues a server-side indexing job, | ||
| # so wait for it to finish before another agent tries to resume the session. | ||
| result = await session.push_index() | ||
| if result.job_id: | ||
| await moss.wait_for_job(result.job_id) | ||
| print("[agent A - chat] wrote 3 turns and pushed the session to the cloud\n") |
| finally: | ||
| # demo cleanup: this run pushed a cloud index, so remove it. In production | ||
| # you would keep the session (a stable, resumable id) instead of deleting it. | ||
| await _client().delete_index(session_name) | ||
| print(f"\ncleaned up demo session: {session_name}") |
| result = await session.push_index() # queues a cloud indexing job | ||
| await moss.wait_for_job(result.job_id) # wait until it's ready to resume | ||
|
|
| `push_index()` doesn't finish instantly: it queues server-side processing and | ||
| returns a `job_id`. Wait for that job (`wait_for_job`, or poll `get_job_status`) | ||
| before another agent resumes the session, otherwise the index may not be ready | ||
| to auto-load yet. |
What
A small, runnable example under
moss-live-labs/examples/cross-agent-handoffthat moves a conversation between agents without the customer repeating themselves, using one shared Moss session.The idea
Each agent keeps its own private context, so a handoff (chat to voice, bot to human, phone to laptop) usually resets to zero. Instead, all agents share one named session. Agent A writes the conversation and pushes it; Agent B opens the same session by name, resumes it (no re-embedding), and queries context it never directly received.
Contents
cross_agent_handoff.py— simulates two independent agents in one process: A pushes a session, B (a fresh client) resumes it and answers about the charge, the refund, and the order number, none of which it was told directlyREADME.md,.env.example,.python-version,pyproject.toml,uv.lockRun
Notes
semantic-cacheexample (moss.session(index_name=...),add_docs,push_index,query).uv lockresolves, but I have not run it against a live Moss project in this environment (no credentials here). Worth a quickuv runbefore merge to confirm B sees A's pushed context.