personal-agent-protocol 0.3.2__tar.gz → 0.4.0__tar.gz
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.
- personal_agent_protocol-0.4.0/CHANGELOG.md +32 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/PKG-INFO +7 -3
- personal_agent_protocol-0.4.0/docs/docs/examples/account-tokens.mdx +73 -0
- personal_agent_protocol-0.4.0/docs/docs/examples/conversation-control.mdx +63 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/examples/conversation-events.mdx +2 -2
- personal_agent_protocol-0.4.0/docs/docs/examples/conversation-streaming.mdx +65 -0
- personal_agent_protocol-0.4.0/docs/docs/examples/device-sign-in.mdx +44 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/examples/index.mdx +11 -1
- personal_agent_protocol-0.4.0/docs/docs/examples/mediated-sign-in.mdx +60 -0
- personal_agent_protocol-0.4.0/docs/docs/examples/operations.mdx +76 -0
- personal_agent_protocol-0.4.0/docs/docs/examples/two-companies.mdx +73 -0
- personal_agent_protocol-0.4.0/docs/docs/examples/user-with-a-company.mdx +62 -0
- personal_agent_protocol-0.4.0/docs/docs/guides/account-tokens.mdx +90 -0
- personal_agent_protocol-0.4.0/docs/docs/guides/cli.mdx +219 -0
- personal_agent_protocol-0.4.0/docs/docs/guides/company.mdx +152 -0
- personal_agent_protocol-0.4.0/docs/docs/guides/conversations.mdx +86 -0
- personal_agent_protocol-0.4.0/docs/docs/guides/device-sign-in.mdx +108 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/guides/extensions.mdx +5 -2
- personal_agent_protocol-0.4.0/docs/docs/guides/mediated-sign-in.mdx +89 -0
- personal_agent_protocol-0.4.0/docs/docs/guides/operations.mdx +101 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/guides/personal-agent.mdx +14 -11
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/index.mdx +4 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/protocol/coverage.mdx +21 -2
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/protocol/status.mdx +22 -12
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/sdk/python-api.mdx +43 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/sdk/typescript-api.mdx +50 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/sdk/typescript.mdx +5 -3
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/sidebars.js +14 -0
- personal_agent_protocol-0.4.0/examples/pydantic-ai/README.md +49 -0
- personal_agent_protocol-0.4.0/examples/pydantic-ai/account-tokens/README.md +20 -0
- personal_agent_protocol-0.4.0/examples/pydantic-ai/account-tokens/app.py +184 -0
- personal_agent_protocol-0.4.0/examples/pydantic-ai/conversation-control/README.md +17 -0
- personal_agent_protocol-0.4.0/examples/pydantic-ai/conversation-control/app.py +192 -0
- personal_agent_protocol-0.4.0/examples/pydantic-ai/conversation-streaming/README.md +18 -0
- personal_agent_protocol-0.4.0/examples/pydantic-ai/conversation-streaming/app.py +158 -0
- personal_agent_protocol-0.4.0/examples/pydantic-ai/device-sign-in/README.md +16 -0
- personal_agent_protocol-0.4.0/examples/pydantic-ai/device-sign-in/app.py +205 -0
- personal_agent_protocol-0.4.0/examples/pydantic-ai/mediated-sign-in/README.md +18 -0
- personal_agent_protocol-0.4.0/examples/pydantic-ai/mediated-sign-in/app.py +151 -0
- personal_agent_protocol-0.4.0/examples/pydantic-ai/operations/README.md +19 -0
- personal_agent_protocol-0.4.0/examples/pydantic-ai/operations/app.py +295 -0
- personal_agent_protocol-0.4.0/examples/pydantic-ai/two-companies/README.md +22 -0
- personal_agent_protocol-0.4.0/examples/pydantic-ai/two-companies/app.py +177 -0
- personal_agent_protocol-0.4.0/examples/pydantic-ai/user-with-a-company/README.md +20 -0
- personal_agent_protocol-0.4.0/examples/pydantic-ai/user-with-a-company/app.py +195 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/package.json +2 -2
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/__init__.py +96 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/__tests__/test_accounts.py +247 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/__tests__/test_cli_protocol.py +367 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/__tests__/test_company_end_to_end.py +250 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/__tests__/test_company_refusals.py +236 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/__tests__/test_conformance.py +85 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/__tests__/test_conversation_control.py +258 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/__tests__/test_device.py +229 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/__tests__/test_direct_and_api.py +162 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/__tests__/test_fixtures.py +217 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/__tests__/test_mcp_and_web.py +393 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/__tests__/test_mediated.py +341 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/__tests__/test_operations.py +296 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/__tests__/test_pairings.py +483 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/__tests__/test_real_sockets.py +54 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/__tests__/test_requirements.py +92 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/__tests__/test_two_companies.py +164 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/__version__.py +1 -1
- personal_agent_protocol-0.4.0/personal_agent_protocol/accounts.py +413 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/apis.py +153 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/cli_commands.py +1291 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/cli_host.py +470 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/cli_plugin.py +16 -2
- personal_agent_protocol-0.4.0/personal_agent_protocol/company/__init__.py +164 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/company/asgi.py +71 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/company/points.py +407 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/company/service.py +1698 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/company/verify.py +110 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/conformance.py +2611 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/conversations.py +275 -14
- personal_agent_protocol-0.4.0/personal_agent_protocol/demo/__init__.py +12 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/demo/conformance.py +136 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/demo/kit.py +334 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/demo/ledgerly.py +424 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/demo/manzanita.py +339 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/demo/northwind.py +150 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/demo/sockets.py +210 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/device.py +404 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/extensions.py +81 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/mcp.py +270 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/mediated.py +418 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/models.py +42 -0
- personal_agent_protocol-0.4.0/personal_agent_protocol/operations.py +578 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/reactor.py +71 -3
- personal_agent_protocol-0.4.0/personal_agent_protocol/requirements.py +187 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/sessions.py +75 -16
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/transport.py +75 -1
- personal_agent_protocol-0.4.0/protocol/fixtures/conformance/conversations.json +164 -0
- personal_agent_protocol-0.4.0/protocol/fixtures/conformance/lifecycle.json +263 -0
- personal_agent_protocol-0.4.0/protocol/fixtures/conformance/operations.json +190 -0
- personal_agent_protocol-0.4.0/protocol/fixtures/conformance/protocol.json +590 -0
- personal_agent_protocol-0.4.0/protocol/fixtures/conformance/security.json +429 -0
- personal_agent_protocol-0.4.0/protocol/requirements.yaml +2203 -0
- personal_agent_protocol-0.4.0/protocol/scenarios/user-with-a-company.json +48 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/pyproject.toml +9 -0
- personal_agent_protocol-0.4.0/src/__tests__/accounts.test.mjs +140 -0
- personal_agent_protocol-0.4.0/src/__tests__/company.test.mjs +450 -0
- personal_agent_protocol-0.4.0/src/__tests__/conversation-control.test.mjs +126 -0
- personal_agent_protocol-0.4.0/src/__tests__/device.test.mjs +145 -0
- personal_agent_protocol-0.4.0/src/__tests__/fixtures.test.mjs +114 -0
- personal_agent_protocol-0.4.0/src/__tests__/mediated.test.mjs +142 -0
- personal_agent_protocol-0.4.0/src/__tests__/operations.test.mjs +151 -0
- personal_agent_protocol-0.4.0/src/__tests__/pairing.test.mjs +38 -0
- personal_agent_protocol-0.4.0/src/__tests__/support/journey.mjs +128 -0
- personal_agent_protocol-0.4.0/src/__tests__/support/lines.mjs +28 -0
- personal_agent_protocol-0.4.0/src/__tests__/support/run-agent.mjs +49 -0
- personal_agent_protocol-0.4.0/src/__tests__/support/serve-company.mjs +49 -0
- personal_agent_protocol-0.4.0/src/__tests__/support/tls-company.mjs +30 -0
- personal_agent_protocol-0.4.0/src/__tests__/support/world.mjs +284 -0
- personal_agent_protocol-0.4.0/src/accounts.ts +319 -0
- personal_agent_protocol-0.4.0/src/company/index.ts +109 -0
- personal_agent_protocol-0.4.0/src/company/node.ts +133 -0
- personal_agent_protocol-0.4.0/src/company/points.ts +328 -0
- personal_agent_protocol-0.4.0/src/company/service.ts +1625 -0
- personal_agent_protocol-0.4.0/src/company/verify.ts +119 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/src/conversations.ts +259 -1
- personal_agent_protocol-0.4.0/src/demo/manzanita.ts +314 -0
- personal_agent_protocol-0.4.0/src/device.ts +435 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/src/index.ts +58 -0
- personal_agent_protocol-0.4.0/src/mediated.ts +368 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/src/models.ts +38 -4
- personal_agent_protocol-0.4.0/src/operations.ts +422 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/src/reactor.ts +55 -1
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/src/server.ts +1 -0
- personal_agent_protocol-0.3.2/CHANGELOG.md +0 -7
- personal_agent_protocol-0.3.2/docs/docs/guides/cli.mdx +0 -146
- personal_agent_protocol-0.3.2/docs/docs/guides/company.mdx +0 -67
- personal_agent_protocol-0.3.2/examples/pydantic-ai/README.md +0 -35
- personal_agent_protocol-0.3.2/protocol/requirements.yaml +0 -121
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/.github/workflows/build.yaml +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/.github/workflows/docs.yaml +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/.github/workflows/py-code-style.yaml +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/.github/workflows/py-tests.yaml +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/.github/workflows/py-typing.yaml +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/.github/workflows/release.yaml +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/.github/workflows/reusable-python.yaml +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/.github/workflows/typescript.yaml +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/.gitignore +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/.licenserc.yaml +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/.pre-commit-config.yaml +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/.vscode/settings.json +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/Dockerfile +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/LICENSE +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/Makefile +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/README.md +2 -2
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/RELEASE.md +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/.gitignore +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/LICENSE +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/Makefile +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/README.md +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/concepts/architecture.mdx +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/concepts/glossary.mdx +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/concepts/protocol-tour.mdx +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/contributing/sdk-design.mdx +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/examples/agent-identity.mdx +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/examples/browser-session.mdx +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/examples/company-discovery.mdx +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/examples/conversation-messages.mdx +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/examples/direct-sign-in-boundary.mdx +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/examples/direct-sign-in-lifecycle.mdx +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/examples/dpop-proof.mdx +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/examples/dpop-transport.mdx +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/examples/session-assertion.mdx +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/examples/session-lifecycle.mdx +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/getting-started/index.mdx +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/guides/agent-runtimes.mdx +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/guides/conformance.mdx +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/guides/cryptography.mdx +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/guides/direct-sign-in.mdx +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/guides/pydantic-ai.mdx +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/guides/sessions.mdx +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/protocol/open-topics.mdx +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/sdk/python.mdx +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/security/index.mdx +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/studio/integration.mdx +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docusaurus.config.js +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/package.json +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/src/css/custom.css +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/src/pages/index.module.css +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/static/img/bricks.svg +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/static/img/building-construction.svg +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/static/img/cloud-sun.svg +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/static/img/cloud.svg +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/static/img/collaboration.svg +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/static/img/copy-left.svg +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/static/img/datalayer/logo.png +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/static/img/datalayer/logo.svg +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/static/img/datalayer/personas/business.svg +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/static/img/datalayer/personas/data-scientist.svg +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/static/img/datalayer/personas/devops.svg +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/static/img/datalayer/project/project-line.svg +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/static/img/favicon.ico +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/static/img/jupyter.svg +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/static/img/open-source.svg +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/static/img/react-js.svg +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/static/img/react-js2.svg +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/static/img/ringed-planet.svg +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/static/img/robot.svg +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/static/img/rocket.svg +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/static/img/shield.svg +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/static/img/sparkles.svg +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/static/img/streamlit.gif +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/static/img/super-hero.svg +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/static/img/target.svg +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/static/img/thumbs-up.svg +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/examples/README.md +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/examples/pydantic-ai/agent-identity/README.md +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/examples/pydantic-ai/agent-identity/app.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/examples/pydantic-ai/browser-session/README.md +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/examples/pydantic-ai/browser-session/app.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/examples/pydantic-ai/company-discovery/README.md +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/examples/pydantic-ai/company-discovery/app.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/examples/pydantic-ai/conversation-events/README.md +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/examples/pydantic-ai/conversation-events/app.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/examples/pydantic-ai/conversation-messages/README.md +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/examples/pydantic-ai/conversation-messages/app.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/examples/pydantic-ai/direct-sign-in-boundary/README.md +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/examples/pydantic-ai/direct-sign-in-boundary/app.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/examples/pydantic-ai/direct-sign-in-lifecycle/README.md +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/examples/pydantic-ai/direct-sign-in-lifecycle/app.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/examples/pydantic-ai/dpop-proof/README.md +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/examples/pydantic-ai/dpop-proof/app.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/examples/pydantic-ai/dpop-transport/README.md +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/examples/pydantic-ai/dpop-transport/app.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/examples/pydantic-ai/session-assertion/README.md +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/examples/pydantic-ai/session-assertion/app.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/examples/pydantic-ai/session-lifecycle/README.md +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/examples/pydantic-ai/session-lifecycle/app.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/__tests__/__init__.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/__tests__/conftest.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/__tests__/test_auth.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/__tests__/test_browser.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/__tests__/test_cli.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/__tests__/test_conversations.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/__tests__/test_crypto.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/__tests__/test_discovery.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/__tests__/test_identity.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/__tests__/test_models.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/__tests__/test_pairwise.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/__tests__/test_reactor.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/__tests__/test_sessions.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/__tests__/test_transport.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/auth.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/browser.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/cli.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/config.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/crypto.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/discovery.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/errors.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/identity.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/json.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/pairwise.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/personal_agent_protocol/py.typed +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/protocol/UPSTREAM.md +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/protocol/fixtures/client-metadata-valid.json +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/protocol/fixtures/conversation-events-valid.json +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/protocol/fixtures/discovery-valid.json +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/protocol/fixtures/jwks-valid.json +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/protocol/fixtures/oauth-metadata-valid.json +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/protocol/fixtures/operation-valid.json +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/protocol/fixtures/session-token-valid.json +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/scripts/generate_api_reference.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/scripts/validate_pydantic_ai_examples.py +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/src/__tests__/auth.test.mjs +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/src/__tests__/browser.test.mjs +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/src/__tests__/conversations.test.mjs +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/src/__tests__/crypto.test.mjs +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/src/__tests__/discovery.test.mjs +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/src/__tests__/identity.test.mjs +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/src/__tests__/reactor.test.mjs +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/src/__tests__/server.test.mjs +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/src/__tests__/sessions.test.mjs +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/src/__tests__/transport.test.mjs +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/src/auth.ts +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/src/browser-server.ts +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/src/browser.ts +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/src/crypto.ts +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/src/discovery.ts +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/src/errors.ts +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/src/identity.ts +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/src/json.ts +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/src/secret.ts +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/src/sessions.ts +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/src/transport.ts +0 -0
- {personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/tsconfig.json +0 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
~ Copyright (c) 2023-2024 Datalayer, Inc.
|
|
3
|
+
~
|
|
4
|
+
~ BSD 3-Clause License
|
|
5
|
+
-->
|
|
6
|
+
|
|
7
|
+
# Changelog
|
|
8
|
+
|
|
9
|
+
## 0.4.0 (2026-10-11)
|
|
10
|
+
|
|
11
|
+
Both sides of PAP draft 0.1 and Operations v1, in Python and TypeScript.
|
|
12
|
+
|
|
13
|
+
- **Personal agent:** Account Tokens (refresh, serialized rotation, narrowing,
|
|
14
|
+
revocation), Mediated Sign-In with protected input, conversation streaming
|
|
15
|
+
(SSE, `text-delta`, `Last-Event-ID`), handoff, Direct Conversations and
|
|
16
|
+
closing, the Operations v1 client (exact approval, standing permissions,
|
|
17
|
+
recovery), resource-bound MCP Bearer, OpenAPI and MCP clients, operations
|
|
18
|
+
from every channel.
|
|
19
|
+
- **Company:** a framework-neutral reference company assembled from Reactor
|
|
20
|
+
points (`pap.company.*`), served over ASGI (Python) and node:http(s)
|
|
21
|
+
(TypeScript): discovery, Sessions, Direct, Device and Mediated Sign-In,
|
|
22
|
+
Account Tokens, conversations, an OpenAPI API and an MCP endpoint, the
|
|
23
|
+
browser session, Operations performed at most once.
|
|
24
|
+
- **Demonstrations:** a user with a company (Manzanita), two companies working
|
|
25
|
+
together (Ledgerly at Northwind Bank), served in process or over real TCP
|
|
26
|
+
and TLS (`server` extra).
|
|
27
|
+
- **Conformance:** the requirement ledger of every MUST and SHOULD
|
|
28
|
+
(`protocol/requirements.yaml`), 113 fixture cases, a runner with JSON and
|
|
29
|
+
JUnit output (91 of 91 against the reference company over TLS), and the four
|
|
30
|
+
Python/TypeScript pairings.
|
|
31
|
+
- **CLI:** `pap sessions`, `auth`, `api`, `conversations`, `operations`,
|
|
32
|
+
`requirements`, `conformance`, with protected input never as an option.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: personal-agent-protocol
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Python SDK for Personal Agent Protocol
|
|
5
5
|
Project-URL: Home, https://github.com/datalayer/personal-agent-protocol
|
|
6
6
|
Project-URL: Documentation, https://personalagentprotocol.org/docs
|
|
@@ -46,6 +46,7 @@ Requires-Dist: datalayer-reactor<2,>=1.0.5
|
|
|
46
46
|
Requires-Dist: httpx<1,>=0.27
|
|
47
47
|
Requires-Dist: pydantic<3,>=2.10
|
|
48
48
|
Requires-Dist: pyjwt[crypto]<3,>=2.13
|
|
49
|
+
Requires-Dist: pyyaml<7,>=6
|
|
49
50
|
Requires-Dist: typer<1,>=0.12
|
|
50
51
|
Provides-Extra: examples
|
|
51
52
|
Requires-Dist: pydantic-ai-slim[openai]<3,>=2.35.0; extra == 'examples'
|
|
@@ -53,10 +54,13 @@ Provides-Extra: lint
|
|
|
53
54
|
Requires-Dist: mdformat-gfm>=0.3.5; extra == 'lint'
|
|
54
55
|
Requires-Dist: mdformat>0.7; extra == 'lint'
|
|
55
56
|
Requires-Dist: ruff; extra == 'lint'
|
|
57
|
+
Provides-Extra: server
|
|
58
|
+
Requires-Dist: uvicorn>=0.30; extra == 'server'
|
|
56
59
|
Provides-Extra: test
|
|
57
60
|
Requires-Dist: pytest-asyncio>=0.21; extra == 'test'
|
|
58
61
|
Requires-Dist: pytest-cov>=4.1; extra == 'test'
|
|
59
62
|
Requires-Dist: pytest>=7.0; extra == 'test'
|
|
63
|
+
Requires-Dist: uvicorn>=0.30; extra == 'test'
|
|
60
64
|
Provides-Extra: typing
|
|
61
65
|
Requires-Dist: mypy>=0.990; extra == 'typing'
|
|
62
66
|
Description-Content-Type: text/markdown
|
|
@@ -71,12 +75,12 @@ Description-Content-Type: text/markdown
|
|
|
71
75
|
|
|
72
76
|
# 🤖 🌸 Personal Agent Protocol
|
|
73
77
|
|
|
74
|
-

|
|
75
|
-
|
|
76
78
|
Python and TypeScript SDKs for the
|
|
77
79
|
[Personal Agent Protocol](https://personalagentprotocol.org), currently
|
|
78
80
|
targeting [draft 0.1](https://personalagentprotocol.org/docs/spec).
|
|
79
81
|
|
|
82
|
+

|
|
83
|
+
|
|
80
84
|
PAP lets a personal agent discover and talk to a company's agent on behalf of
|
|
81
85
|
a person. The company remains responsible for its identity, authorization,
|
|
82
86
|
data, and actions; the personal agent does not need the person's company
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Account Tokens
|
|
3
|
+
description: Keep a user signed in with a rotating Account Token that never leaves the host.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Account Tokens
|
|
7
|
+
|
|
8
|
+
A sign-in returns an Account Token (the OAuth `refresh_token`). The personal
|
|
9
|
+
agent uses it only at the company's token and revocation endpoints, to sign a
|
|
10
|
+
Session in again after its short-lived Session Token expires. The paired
|
|
11
|
+
examples run the real `AccountTokenClient` against Manzanita Outfitters, the
|
|
12
|
+
reference company in `personal_agent_protocol.demo`, with real keys over HTTP
|
|
13
|
+
in one process.
|
|
14
|
+
|
|
15
|
+
```mermaid
|
|
16
|
+
sequenceDiagram
|
|
17
|
+
autonumber
|
|
18
|
+
participant Tool as Agent tool
|
|
19
|
+
participant SDK as AccountTokenClient
|
|
20
|
+
participant Lock as pap.accountTokenLock
|
|
21
|
+
participant Vault as pap.tokenStore
|
|
22
|
+
participant Company as Company token endpoint
|
|
23
|
+
Tool->>SDK: refresh(reference, session_id)
|
|
24
|
+
SDK->>Lock: Hold the reference
|
|
25
|
+
SDK->>Vault: Read Account Token
|
|
26
|
+
SDK->>Company: refresh_token grant + session_id + assertion + DPoP
|
|
27
|
+
Company-->>SDK: Signed-in Session Token + rotated Account Token
|
|
28
|
+
SDK->>Vault: Replace the old token before releasing the lock
|
|
29
|
+
SDK-->>Tool: signed_in, rotated, granted scopes
|
|
30
|
+
Tool->>SDK: refresh(reference, scopes=orders:read)
|
|
31
|
+
SDK->>Company: Narrower scope
|
|
32
|
+
Company-->>SDK: Session with orders:read
|
|
33
|
+
Tool->>SDK: refresh(reference, scopes=orders:admin)
|
|
34
|
+
Company-->>SDK: invalid_scope
|
|
35
|
+
SDK-->>Tool: re_consent_required (sign the user in again)
|
|
36
|
+
Note over Company: Ninety-one days later
|
|
37
|
+
SDK->>Company: refresh_token grant
|
|
38
|
+
Company-->>SDK: invalid_grant
|
|
39
|
+
SDK->>Vault: Delete the stored copy
|
|
40
|
+
SDK-->>Tool: signed_out
|
|
41
|
+
Tool->>SDK: revoke(reference)
|
|
42
|
+
SDK->>Company: RFC 7009 revocation
|
|
43
|
+
Company-->>SDK: 200, every Session signed in with it is signed out
|
|
44
|
+
SDK->>Vault: Delete once the company answered
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The walkthrough:
|
|
48
|
+
|
|
49
|
+
1. **Refresh** signs the same Session in again (`session_id` unchanged) and the
|
|
50
|
+
company rotates the token. The new one replaces the old in the token store
|
|
51
|
+
before the call returns.
|
|
52
|
+
2. **Two refreshes at once** both succeed: the Reactor `pap.accountTokenLock`
|
|
53
|
+
serializes them, so the second presents the token the first rotated in, not
|
|
54
|
+
the one the company already revoked.
|
|
55
|
+
3. **Narrower** scopes are granted; **wider** scopes come back as
|
|
56
|
+
`re_consent_required`, a decision for the user, never a retry.
|
|
57
|
+
4. An **expired** token draws `invalid_grant`; the SDK deletes it and the
|
|
58
|
+
Session continues signed out.
|
|
59
|
+
5. **Revocation** signs out every Session signed in with the token. The next
|
|
60
|
+
question to the company draws an `authorization` event again.
|
|
61
|
+
|
|
62
|
+
The model sees statuses (`signed_in`, `re_consent_required`, `signed_out`),
|
|
63
|
+
whether a rotation happened, and scope names. The Account Token, Session
|
|
64
|
+
Tokens, client assertions, and DPoP proofs stay host-only, behind opaque
|
|
65
|
+
references in Reactor stores.
|
|
66
|
+
|
|
67
|
+
TypeScript has the same client: `new AccountTokenClient({ reactor, fetch })`,
|
|
68
|
+
with `refresh(reference, { context, sessionId, scopes })` and `revoke()`, and
|
|
69
|
+
the lock contributed at `AccountTokenLocks`.
|
|
70
|
+
|
|
71
|
+
- Run the [Pydantic AI example](https://github.com/datalayer/personal-agent-protocol/tree/main/examples/pydantic-ai/account-tokens).
|
|
72
|
+
- Run the [Agent Runtimes example](https://github.com/datalayer/agent-runtimes/tree/main/examples/personal-agent-protocol/account-tokens).
|
|
73
|
+
- Read the [Account Tokens guide](/guides/account-tokens/).
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Conversation control
|
|
3
|
+
description: Sign in mid-conversation, open a Direct Conversation, hand off to a person, and close.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Conversation control
|
|
7
|
+
|
|
8
|
+
A conversation is more than messages. The company can ask the user to sign in
|
|
9
|
+
part-way through, the user can talk to the company directly through the
|
|
10
|
+
agent's interface, either side can bring in a person, and the agent can close
|
|
11
|
+
it. The paired examples drive one Manzanita conversation through all four,
|
|
12
|
+
against a Manzanita with a support desk staffed.
|
|
13
|
+
|
|
14
|
+
```mermaid
|
|
15
|
+
sequenceDiagram
|
|
16
|
+
autonumber
|
|
17
|
+
actor Ada
|
|
18
|
+
participant Atlas as Atlas (personal agent)
|
|
19
|
+
participant Company as Manzanita
|
|
20
|
+
Atlas->>Company: Where is my jacket order? (signed out)
|
|
21
|
+
Company-->>Atlas: authorization: sign_in_required (orders:read orders:write)
|
|
22
|
+
Atlas->>Ada: Sign in on Manzanita's page
|
|
23
|
+
Ada->>Company: Approves the device code
|
|
24
|
+
Atlas->>Company: Same conversation, signed-in token
|
|
25
|
+
Company-->>Atlas: Your order ord_7Hk2 … delivered
|
|
26
|
+
Ada->>Atlas: I'd like to ask about sizing myself
|
|
27
|
+
Atlas->>Company: start_direct(parent) with sender human
|
|
28
|
+
Company-->>Atlas: Direct Conversation cnv_d
|
|
29
|
+
Atlas->>Company: Message or handoff on the parent
|
|
30
|
+
Company-->>Atlas: 409 direct_conversation_open (conversation_id cnv_d)
|
|
31
|
+
Atlas->>Company: close(cnv_d)
|
|
32
|
+
Company-->>Atlas: Parent: direct_closed
|
|
33
|
+
Atlas->>Company: handoff(parent)
|
|
34
|
+
Company-->>Atlas: state queued, then idle with responder human
|
|
35
|
+
Atlas->>Company: close(parent)
|
|
36
|
+
Company-->>Atlas: closed, later messages are conversation_closed
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
- **Sign-in mid-conversation (§7.11).** An `authorization` event says what is
|
|
40
|
+
missing (`sign_in_required` or `insufficient_scope`) and which scopes. The
|
|
41
|
+
host signs in with any mode the company offers and keeps sending to the
|
|
42
|
+
**same conversation ID** with the new token.
|
|
43
|
+
- **Direct Conversations (§7.10).** Only the personal agent starts one, for
|
|
44
|
+
the user to talk with the company in the agent's interface. While it is
|
|
45
|
+
open, the parent refuses messages and handoff with
|
|
46
|
+
`direct_conversation_open`; the SDK puts the open conversation's ID in
|
|
47
|
+
`error.details["conversation_id"]`.
|
|
48
|
+
- **Handoff (§7.9).** `handoff()` asks for a person; the conversation is
|
|
49
|
+
`queued` until one takes it, then `responder` is `human`. When no one is
|
|
50
|
+
available the company says so and the agent continues.
|
|
51
|
+
- **Closing (§7.12).** `close()` ends the conversation; operations it
|
|
52
|
+
proposed or started are not cancelled.
|
|
53
|
+
|
|
54
|
+
The model sees event types, statuses, the company's answers, and error codes.
|
|
55
|
+
Tokens, the device code, and proofs stay host-only; the user code is shown to
|
|
56
|
+
the user by the host, not by the model.
|
|
57
|
+
|
|
58
|
+
TypeScript: `startDirect()`, `handoff()`, and `close()` on
|
|
59
|
+
`ConversationClient`, with the same error codes and details.
|
|
60
|
+
|
|
61
|
+
- Run the [Pydantic AI example](https://github.com/datalayer/personal-agent-protocol/tree/main/examples/pydantic-ai/conversation-control).
|
|
62
|
+
- Run the [Agent Runtimes example](https://github.com/datalayer/agent-runtimes/tree/main/examples/personal-agent-protocol/conversation-control).
|
|
63
|
+
- Read the [conversations guide](/guides/conversations/).
|
|
@@ -50,8 +50,8 @@ missing.
|
|
|
50
50
|
|
|
51
51
|
Session Tokens, DPoP proofs, pairwise identity, and the saved cursor remain in
|
|
52
52
|
the trusted host. A model or UI receives only the event fields it needs. A
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
company that streams can be read over SSE instead, with reconnects and
|
|
54
|
+
display-only `text-delta` frames: see [conversation streaming](./conversation-streaming).
|
|
55
55
|
|
|
56
56
|
Run the [Pydantic AI example](https://github.com/datalayer/personal-agent-protocol/tree/main/examples/pydantic-ai/conversation-events)
|
|
57
57
|
or the [Agent Runtimes example](https://github.com/datalayer/agent-runtimes/tree/main/examples/personal-agent-protocol/conversation-events).
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Conversation streaming
|
|
3
|
+
description: Stream a company's reply over SSE, reconnect from Last-Event-ID, and never act on a delta.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Conversation streaming
|
|
7
|
+
|
|
8
|
+
A company that streams answers `GET …/events` with `Accept: text/event-stream`.
|
|
9
|
+
Events arrive as SSE frames with their IDs, and `text-delta` frames carry a
|
|
10
|
+
message while it is still being written. The paired examples stream a
|
|
11
|
+
Manzanita conversation through a connection that breaks in the middle of the
|
|
12
|
+
company's first reply.
|
|
13
|
+
|
|
14
|
+
```mermaid
|
|
15
|
+
sequenceDiagram
|
|
16
|
+
autonumber
|
|
17
|
+
participant Tool as Agent tool
|
|
18
|
+
participant SDK as ConversationClient.stream()
|
|
19
|
+
participant Net as Network
|
|
20
|
+
participant Company
|
|
21
|
+
SDK->>Company: GET /events (Accept: text/event-stream) + DPoP
|
|
22
|
+
Company-->>SDK: id evt_1 (user message)
|
|
23
|
+
Company-->>SDK: text-delta msg_r (half of the reply)
|
|
24
|
+
Net--xSDK: Connection drops before message msg_r
|
|
25
|
+
SDK-->>Tool: TextDelta (actionable = false)
|
|
26
|
+
SDK-->>Tool: StreamReconnected(last_event_id=evt_1, discarded=[msg_r])
|
|
27
|
+
SDK->>Company: GET /events, Last-Event-ID: evt_1
|
|
28
|
+
Company-->>SDK: text-delta msg_r, id evt_2 (complete message)
|
|
29
|
+
SDK-->>Tool: Message event evt_2 (the one to show and act on)
|
|
30
|
+
Company-->>SDK: Stream ends, conversation still open
|
|
31
|
+
SDK-->>Tool: StreamReconnected(last_event_id=evt_2)
|
|
32
|
+
Tool->>Company: close()
|
|
33
|
+
SDK->>Company: GET /events, Last-Event-ID: evt_2
|
|
34
|
+
Company-->>SDK: id evt_3 state closed
|
|
35
|
+
SDK-->>Tool: State closed, the iterator ends
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
What the stream guarantees:
|
|
39
|
+
|
|
40
|
+
- **Deltas are display only.** `TextDelta.actionable` is always `False`; the
|
|
41
|
+
complete `message` event replaces the pieces. A host routes deltas to a
|
|
42
|
+
typing indicator, never to anything that acts.
|
|
43
|
+
- **Reconnects resume.** When the company ends the stream, the SDK reopens it
|
|
44
|
+
with `Last-Event-ID` set to the last event handled, and yields
|
|
45
|
+
`StreamReconnected` so the UI knows.
|
|
46
|
+
- **Partial messages are discarded.** Pieces whose complete message never
|
|
47
|
+
arrived are listed in `discarded_message_ids`, so the display drops them.
|
|
48
|
+
- **No event twice.** Replayed events are suppressed by ID, within a bounded
|
|
49
|
+
set that fails closed.
|
|
50
|
+
- **Bounded retries.** After `max_reconnects` reconnects in a row without a
|
|
51
|
+
new event, the stream fails with `stream_unavailable`. A company that does
|
|
52
|
+
not stream answers JSON; the SDK raises `sse_unsupported` and the host falls
|
|
53
|
+
back to the long-polling `events()` reader.
|
|
54
|
+
|
|
55
|
+
The model sees the company's complete messages, how many deltas and
|
|
56
|
+
reconnects there were, and that nothing was delivered twice. The Session
|
|
57
|
+
Token, DPoP proofs, and pairwise identity stay host-only.
|
|
58
|
+
|
|
59
|
+
TypeScript: `for await (const item of client.stream(endpoint, id, options))`,
|
|
60
|
+
where `item.kind` is `"text-delta"` or `"reconnected"` for the two
|
|
61
|
+
stream-only items.
|
|
62
|
+
|
|
63
|
+
- Run the [Pydantic AI example](https://github.com/datalayer/personal-agent-protocol/tree/main/examples/pydantic-ai/conversation-streaming).
|
|
64
|
+
- Run the [Agent Runtimes example](https://github.com/datalayer/agent-runtimes/tree/main/examples/personal-agent-protocol/conversation-streaming).
|
|
65
|
+
- Read the [conversations guide](/guides/conversations/).
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Device Sign-In
|
|
3
|
+
description: Hand authentication to the user, pace polling, and protect every credential.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Device Sign-In
|
|
7
|
+
|
|
8
|
+
The paired examples use the real SDK state machine against a deterministic
|
|
9
|
+
company transport. They demonstrate a terminal-style personal agent that
|
|
10
|
+
cannot receive a browser callback.
|
|
11
|
+
|
|
12
|
+
```mermaid
|
|
13
|
+
sequenceDiagram
|
|
14
|
+
autonumber
|
|
15
|
+
actor User
|
|
16
|
+
participant Tool as Read-only agent tool
|
|
17
|
+
participant SDK as DeviceSignInClient
|
|
18
|
+
participant Company
|
|
19
|
+
participant Vault as Reactor stores
|
|
20
|
+
Tool->>SDK: Begin for existing signed-out Session
|
|
21
|
+
SDK->>Company: Request device authorization
|
|
22
|
+
Company-->>SDK: Link, user code, interval, private device code
|
|
23
|
+
SDK->>Vault: Save private device code
|
|
24
|
+
SDK-->>Tool: Link, user code, opaque reference
|
|
25
|
+
Tool-->>User: Authenticate on company page
|
|
26
|
+
SDK->>Company: Poll at interval with DPoP
|
|
27
|
+
Company-->>SDK: authorization_pending
|
|
28
|
+
SDK->>Company: Poll at interval
|
|
29
|
+
Company-->>SDK: slow_down
|
|
30
|
+
Note over SDK: Increase interval by five seconds
|
|
31
|
+
SDK->>Company: Poll at new interval
|
|
32
|
+
Company-->>SDK: Signed-in Session + Account Token + partial scopes
|
|
33
|
+
SDK->>Vault: Store Account Token
|
|
34
|
+
SDK-->>Tool: Safe lifecycle evidence + opaque token reference
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The model sees that the link and code were presented, early polling was
|
|
38
|
+
suppressed, pending and slow-down responses were respected, the original
|
|
39
|
+
Session was upgraded, and one requested scope was omitted. It never sees the
|
|
40
|
+
device code, assertions, proofs, or tokens.
|
|
41
|
+
|
|
42
|
+
- Run the [Pydantic AI example](https://github.com/datalayer/personal-agent-protocol/tree/main/examples/pydantic-ai/device-sign-in).
|
|
43
|
+
- Run the [Agent Runtimes example](https://github.com/datalayer/agent-runtimes/tree/main/examples/personal-agent-protocol/device-sign-in).
|
|
44
|
+
- Read the production [Device Sign-In guide](/guides/device-sign-in/).
|
{personal_agent_protocol-0.3.2 → personal_agent_protocol-0.4.0}/docs/docs/examples/index.mdx
RENAMED
|
@@ -22,9 +22,19 @@ capability owns sensitive work, and what may safely cross into model context.
|
|
|
22
22
|
| [Session lifecycle](./session-lifecycle) | Start, retry, and renew a signed-out Session | An authorization server |
|
|
23
23
|
| [Direct Sign-In lifecycle](./direct-sign-in-lifecycle) | Upgrade the same Session after user consent | A browser callback |
|
|
24
24
|
| [Browser Session](./browser-session) | Join a controlled browser to the same Session | A signed browser assertion |
|
|
25
|
+
| [Account Tokens](./account-tokens) | Refresh, rotate, narrow, expire, and revoke without exposing the token | A signed-in Session |
|
|
26
|
+
| [Mediated Sign-In](./mediated-sign-in) | Relay protected input to one endpoint, then a one-time code | Declared mediated fields |
|
|
27
|
+
| [Conversation streaming](./conversation-streaming) | Stream over SSE, reconnect from `Last-Event-ID`, never act on deltas | An open conversation |
|
|
28
|
+
| [Conversation control](./conversation-control) | Sign in mid-conversation, go direct, hand off, and close | An `authorization` event |
|
|
29
|
+
| [Operations](./operations) | Confirm the exact revision, recover lost answers, use standing permissions | A proposed operation |
|
|
30
|
+
| [A user with a company](./user-with-a-company) | The whole journey with Manzanita, both sides from the SDK | A user's request |
|
|
31
|
+
| [Two companies](./two-companies) | Ledgerly acts for Ada at Northwind, by composition | Two PAP relationships |
|
|
25
32
|
|
|
26
33
|
The examples use deterministic or local transports where needed, so they can
|
|
27
|
-
teach the boundary without real credentials.
|
|
34
|
+
teach the boundary without real credentials. The newer flows run against the
|
|
35
|
+
reference company in `personal_agent_protocol.demo`: real keys and real HTTP
|
|
36
|
+
over ASGI in one process, with no network. The two journeys at the end of the
|
|
37
|
+
table combine several features; each other page showcases one. Production hosts replace those
|
|
28
38
|
fixtures through Reactor contributions for egress, state, browsers, signing,
|
|
29
39
|
DPoP, key custody, and token storage.
|
|
30
40
|
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Mediated Sign-In
|
|
3
|
+
description: Relay the user's credentials to one company endpoint, once, without a model seeing them.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Mediated Sign-In
|
|
7
|
+
|
|
8
|
+
Some companies cannot send their users to a browser. They declare the fields
|
|
9
|
+
they need (`auth.mediated.fields`) and an endpoint on their own domain, and
|
|
10
|
+
the personal agent relays what the user types. It is the one sign-in mode
|
|
11
|
+
where a password passes through the agent's host, so the SDK narrows what the
|
|
12
|
+
host can do with it. The paired examples run the real `MediatedSignInClient`
|
|
13
|
+
against Manzanita Outfitters, which asks for an email, a password, and then a
|
|
14
|
+
one-time code.
|
|
15
|
+
|
|
16
|
+
```mermaid
|
|
17
|
+
sequenceDiagram
|
|
18
|
+
autonumber
|
|
19
|
+
actor User
|
|
20
|
+
participant Tool as Agent tool
|
|
21
|
+
participant SDK as MediatedSignInClient
|
|
22
|
+
participant Input as pap.protectedInput (host surface)
|
|
23
|
+
participant Company as Company mediated endpoint
|
|
24
|
+
Tool->>SDK: sign_in(declared fields, signed-out Session)
|
|
25
|
+
SDK->>SDK: Endpoint on the company's domain? Otherwise refuse before asking
|
|
26
|
+
SDK->>Input: Ask for Email and Password for manzanita.example
|
|
27
|
+
User->>Input: Types them (never into the chat)
|
|
28
|
+
SDK->>Company: POST credentials once + DPoP, no redirect followed
|
|
29
|
+
SDK->>SDK: Drop the values
|
|
30
|
+
Company-->>SDK: code_required, sign_in_id, sent_to a•••@example.com
|
|
31
|
+
SDK-->>Tool: code_required + opaque reference + masked sent_to
|
|
32
|
+
Tool->>SDK: submit_code(reference, same Session)
|
|
33
|
+
SDK->>Input: Ask for the code
|
|
34
|
+
User->>Input: Types the code
|
|
35
|
+
SDK->>Company: POST code only to …/sign_in_id
|
|
36
|
+
Company-->>SDK: complete + signed-in Session + Account Token
|
|
37
|
+
SDK-->>Tool: complete, granted scopes, Account Token reference
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The walkthrough also shows the refusals:
|
|
41
|
+
|
|
42
|
+
- An endpoint off the company's domain is `unsafe_mediated_endpoint`, raised
|
|
43
|
+
before the user is asked anything.
|
|
44
|
+
- The protected input must answer exactly the declared fields, none empty.
|
|
45
|
+
- Only the Session that started a sign-in can finish it
|
|
46
|
+
(`session_mismatch`); the pending state is kept for the right one.
|
|
47
|
+
- A wrong code is `code_required` again with the same reference; the company
|
|
48
|
+
ends the sign-in with `failed` after its attempt limit.
|
|
49
|
+
|
|
50
|
+
The model sees field labels, which fields are secret, the company's domain,
|
|
51
|
+
the masked destination of the code, statuses, and granted scopes. The
|
|
52
|
+
credentials and the code exist only in the host's protected input and in the
|
|
53
|
+
one request body; the Session Token and Account Token stay in Reactor stores.
|
|
54
|
+
|
|
55
|
+
TypeScript: `new MediatedSignInClient({ reactor, fetch })` with `signIn()` and
|
|
56
|
+
`submitCode()`, the trusted surface contributed at `ProtectedInputs`.
|
|
57
|
+
|
|
58
|
+
- Run the [Pydantic AI example](https://github.com/datalayer/personal-agent-protocol/tree/main/examples/pydantic-ai/mediated-sign-in).
|
|
59
|
+
- Run the [Agent Runtimes example](https://github.com/datalayer/agent-runtimes/tree/main/examples/personal-agent-protocol/mediated-sign-in).
|
|
60
|
+
- Read the [Mediated Sign-In guide](/guides/mediated-sign-in/).
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Operations
|
|
3
|
+
description: Confirm exactly what the user approved, at most once, and recover a lost answer.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Operations
|
|
7
|
+
|
|
8
|
+
An operation is something a company proposes and performs only once it is
|
|
9
|
+
confirmed: a payment, an exchange, a cancellation. The Operations extension
|
|
10
|
+
(version 1) makes the approval exact and durable. The paired examples confirm
|
|
11
|
+
Northwind Bank's proposed payments; Northwind marks payments as not requiring
|
|
12
|
+
the user's own approval, so a standing permission may confirm them too.
|
|
13
|
+
|
|
14
|
+
```mermaid
|
|
15
|
+
sequenceDiagram
|
|
16
|
+
autonumber
|
|
17
|
+
actor Ada
|
|
18
|
+
participant Atlas as Atlas host
|
|
19
|
+
participant Store as pap.standingPermissionStore
|
|
20
|
+
participant Bank as Northwind operations endpoint
|
|
21
|
+
Note over Atlas,Bank: Both poppy.json and agent.json list operations version 1
|
|
22
|
+
Bank-->>Atlas: Proposal op_1 revision 1 (EUR 1250.00 to Acme GmbH)
|
|
23
|
+
Atlas->>Store: reserve(company, account, action, terms)
|
|
24
|
+
Store-->>Atlas: Nothing covers it
|
|
25
|
+
Atlas->>Ada: Show the summary and terms
|
|
26
|
+
Ada->>Atlas: Approve revision 1 (approve: revision + digest)
|
|
27
|
+
Note over Bank: The bank revises: EUR 1262.50, a fee added
|
|
28
|
+
Atlas->>Bank: POST op_1/confirm (revision 1, approved_by user)
|
|
29
|
+
Bank-->>Atlas: 409 terms_changed + revision 2
|
|
30
|
+
Atlas->>Ada: What changed: summary, amount.amount
|
|
31
|
+
Ada->>Atlas: Approve revision 2
|
|
32
|
+
Atlas->>Bank: POST op_1/confirm (revision 2)
|
|
33
|
+
Bank--xAtlas: Performed, but the answer is lost
|
|
34
|
+
Atlas->>Bank: GET op_1 (same ID, never re-proposed)
|
|
35
|
+
Bank-->>Atlas: succeeded + result.summary
|
|
36
|
+
Bank-->>Atlas: Proposal op_2 (EUR 980.00)
|
|
37
|
+
Atlas->>Store: reserve: payee, amount ≤ 2000.00, EUR, one use
|
|
38
|
+
Store-->>Atlas: Reservation
|
|
39
|
+
Atlas->>Bank: POST op_2/confirm (approved_by standing_permission)
|
|
40
|
+
Bank-->>Atlas: succeeded
|
|
41
|
+
Atlas->>Store: commit (a refusal would release the use)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The walkthrough:
|
|
45
|
+
|
|
46
|
+
1. **Negotiation.** `operations_endpoint()` returns the endpoint only when the
|
|
47
|
+
company and the agent both list `operations` version 1. A company answers
|
|
48
|
+
an agent that does not with `extension_required`.
|
|
49
|
+
2. **Exact approval.** `approve(operation)` records the revision and a digest
|
|
50
|
+
of its summary and terms. A confirmation for any other revision is refused
|
|
51
|
+
locally (`approval_mismatch`); a chat message never confirms anything.
|
|
52
|
+
3. **Changed terms.** `terms_changed` returns the new revision and the changed
|
|
53
|
+
term paths, to show the user before asking again.
|
|
54
|
+
4. **Recovery.** If a confirm's answer is lost, the SDK reads the same
|
|
55
|
+
operation back. It is never re-proposed or assumed failed; a retried
|
|
56
|
+
confirm returns the same record, and the company performs it once.
|
|
57
|
+
5. **Standing permissions.** A permission names one company, account, and
|
|
58
|
+
action, with limits on term paths (a maximum or allowed values), an expiry,
|
|
59
|
+
and optional uses. The Reactor `pap.standingPermissionStore` reserves a use
|
|
60
|
+
only when every limit covers the revision; the use is committed when the
|
|
61
|
+
company confirms and released when it refuses. A revision that requires the
|
|
62
|
+
user's approval is never confirmed this way.
|
|
63
|
+
6. **Cancel.** A proposal becomes `cancelled`, and the company's
|
|
64
|
+
`result.summary` says nothing was changed.
|
|
65
|
+
|
|
66
|
+
The model sees states, revisions, changed term paths, error codes, and the
|
|
67
|
+
company's `result.summary` as written. Tokens and proofs stay host-only, and
|
|
68
|
+
the decision to approve stays with the user in the host's own interface.
|
|
69
|
+
|
|
70
|
+
TypeScript: `OperationsClient`, `operationsEndpoint()`, and `approve()`
|
|
71
|
+
(asynchronous there, since the digest uses Web Crypto), with standing
|
|
72
|
+
permissions contributed at `StandingPermissionStores`.
|
|
73
|
+
|
|
74
|
+
- Run the [Pydantic AI example](https://github.com/datalayer/personal-agent-protocol/tree/main/examples/pydantic-ai/operations).
|
|
75
|
+
- Run the [Agent Runtimes example](https://github.com/datalayer/agent-runtimes/tree/main/examples/personal-agent-protocol/operations).
|
|
76
|
+
- Read the [Operations guide](/guides/operations/).
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Two companies
|
|
3
|
+
description: Ledgerly pays Ada's invoices at Northwind Bank, by composing two PAP relationships.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Two companies
|
|
7
|
+
|
|
8
|
+
:::caution Composition, not a draft 0.1 feature
|
|
9
|
+
|
|
10
|
+
PAP draft 0.1 defines no company-to-company protocol. This example composes
|
|
11
|
+
two ordinary PAP relationships for the same user. Ledgerly is a **company** to
|
|
12
|
+
Ada's personal agent, Atlas, and a **personal agent** at Northwind Bank for
|
|
13
|
+
the same Ada, with its own `client_id` and keys on its own domain.
|
|
14
|
+
|
|
15
|
+
:::
|
|
16
|
+
|
|
17
|
+
Ledgerly, an accounting firm, pays Ada's supplier invoices from her Northwind
|
|
18
|
+
account. Every approval is an Operation, never a chat message, and a standing
|
|
19
|
+
permission is itself an Operation Ada approves.
|
|
20
|
+
|
|
21
|
+
```mermaid
|
|
22
|
+
sequenceDiagram
|
|
23
|
+
autonumber
|
|
24
|
+
actor Ada
|
|
25
|
+
participant Atlas as Atlas (Ada's agent)
|
|
26
|
+
participant L as Ledgerly (company to Atlas, agent at Northwind)
|
|
27
|
+
participant N as Northwind Bank
|
|
28
|
+
Atlas->>L: Pay INV-0042 (signed in to Ledgerly)
|
|
29
|
+
L-->>Atlas: Connect Ledgerly: open northwind.example/device
|
|
30
|
+
Ada->>N: Approves Ledgerly's code on Northwind's page
|
|
31
|
+
Atlas->>L: Done. Pay INV-0042
|
|
32
|
+
L->>N: Conversation: pay INV-0042
|
|
33
|
+
N-->>L: Operation n_1: EUR 1250.00 to Acme GmbH
|
|
34
|
+
L-->>Atlas: Operation l_1 quoting n_1 as written
|
|
35
|
+
Ada->>Atlas: Approve l_1
|
|
36
|
+
Atlas->>L: Confirm l_1 (approved_by user)
|
|
37
|
+
L->>N: n_1 unchanged? Confirm n_1 (approved_by user)
|
|
38
|
+
N-->>L: Sent … Bank reference NW-0001
|
|
39
|
+
L-->>Atlas: Northwind Bank: Sent … NW-0001
|
|
40
|
+
Atlas->>L: Allow Acme payments up to EUR 2000 without asking
|
|
41
|
+
L-->>Atlas: Operation: standing permission, 5 uses, 30 days
|
|
42
|
+
Ada->>Atlas: Approve it
|
|
43
|
+
Atlas->>L: Pay INV-0043
|
|
44
|
+
L->>N: Pay, n_2 EUR 980.00 within bounds
|
|
45
|
+
L->>N: Confirm n_2 (approved_by standing_permission)
|
|
46
|
+
L-->>Atlas: Paid under your standing permission: …
|
|
47
|
+
Atlas->>L: Pay INV-0044
|
|
48
|
+
L->>N: n_3 EUR 3400.00 beyond bounds
|
|
49
|
+
L-->>Atlas: Operation for Ada to approve
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
What each party enforces:
|
|
53
|
+
|
|
54
|
+
- **Northwind** sees a personal agent called Ledgerly, signed in by Ada on
|
|
55
|
+
Northwind's own page, confirming its proposals. Its records say who approved
|
|
56
|
+
each payment: `user` for the first, `standing_permission` for the second.
|
|
57
|
+
- **Ledgerly** confirms at Northwind only the exact revision Ada approved: its
|
|
58
|
+
executor checks Northwind's revision and terms are unchanged before
|
|
59
|
+
confirming, and relays Northwind's `result.summary` as written. Within the
|
|
60
|
+
standing permission's term-by-term bounds it confirms itself and tells Ada
|
|
61
|
+
what was done; beyond them, it proposes a new operation for her.
|
|
62
|
+
- **Atlas** treats Ledgerly like any company: it shows each operation's
|
|
63
|
+
summary and terms, and confirms only what Ada approved.
|
|
64
|
+
|
|
65
|
+
The model sees summaries as the companies wrote them, who approved each
|
|
66
|
+
payment, and that the composition involves no company-to-company protocol.
|
|
67
|
+
It never sees a token, code, or proof of any of the three parties.
|
|
68
|
+
|
|
69
|
+
The same world runs in `personal_agent_protocol/__tests__/test_two_companies.py`.
|
|
70
|
+
|
|
71
|
+
- Run the [Pydantic AI example](https://github.com/datalayer/personal-agent-protocol/tree/main/examples/pydantic-ai/two-companies).
|
|
72
|
+
- Run the [Agent Runtimes example](https://github.com/datalayer/agent-runtimes/tree/main/examples/personal-agent-protocol/two-companies).
|
|
73
|
+
- Read the [Operations guide](/guides/operations/) and the [company guide](/guides/company/).
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: A user with a company
|
|
3
|
+
description: One user, one company, from a first question to a confirmed exchange and sign-out.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# A user with a company
|
|
7
|
+
|
|
8
|
+
The whole journey of the upstream home page's example: Ada's jacket is not
|
|
9
|
+
warm enough, and she asks her personal agent, Atlas, to exchange it at
|
|
10
|
+
Manzanita Outfitters. Both sides come from this SDK. Manzanita is the
|
|
11
|
+
[reference company](/guides/company/) assembled from Reactor contributions,
|
|
12
|
+
Atlas is a personal agent with a real ES256 identity, and they talk real HTTP
|
|
13
|
+
over ASGI in one process, with no network and no model in the protocol path.
|
|
14
|
+
|
|
15
|
+
```mermaid
|
|
16
|
+
sequenceDiagram
|
|
17
|
+
autonumber
|
|
18
|
+
actor Ada
|
|
19
|
+
participant Atlas as Atlas (personal agent)
|
|
20
|
+
participant M as Manzanita (company)
|
|
21
|
+
Atlas->>M: Discovery + OAuth metadata
|
|
22
|
+
Atlas->>M: Signed-out Session (assertion + DPoP)
|
|
23
|
+
Ada->>Atlas: Where is my jacket order?
|
|
24
|
+
Atlas->>M: Start conversation
|
|
25
|
+
M-->>Atlas: Sign in first + authorization: sign_in_required
|
|
26
|
+
Atlas->>M: Device authorization for the same Session
|
|
27
|
+
Atlas->>Ada: Open manzanita.example/device and enter the code
|
|
28
|
+
Ada->>M: Signs in and approves on Manzanita's page
|
|
29
|
+
Atlas->>M: Poll → signed-in Session + Account Token
|
|
30
|
+
Ada->>Atlas: Exchange it for something warmer
|
|
31
|
+
Atlas->>M: Same conversation, signed in
|
|
32
|
+
M-->>Atlas: Operation op_1 rev 1: USD 70.00 more
|
|
33
|
+
Atlas->>Ada: Show summary and terms
|
|
34
|
+
Ada->>Atlas: Approve this revision
|
|
35
|
+
Atlas->>M: Confirm rev 1 (approved_by user)
|
|
36
|
+
M-->>Atlas: succeeded + result.summary
|
|
37
|
+
Atlas->>M: Confirm again (a retry)
|
|
38
|
+
M-->>Atlas: Same record, performed once
|
|
39
|
+
Atlas->>M: Refresh narrowed to orders:read
|
|
40
|
+
Ada->>Atlas: Sign me out
|
|
41
|
+
Atlas->>M: Revoke the Account Token
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Each step is one feature, documented on its own page:
|
|
45
|
+
[company discovery](./company-discovery), [session lifecycle](./session-lifecycle),
|
|
46
|
+
[conversation control](./conversation-control) for the `authorization`
|
|
47
|
+
event, [Device Sign-In](./device-sign-in), [Operations](./operations), and
|
|
48
|
+
[Account Tokens](./account-tokens).
|
|
49
|
+
|
|
50
|
+
The model sees the steps in plain words: what the company asked, where Ada
|
|
51
|
+
signed in, what was proposed, what she approved, and what Manzanita did, in
|
|
52
|
+
its own words. It never sees the device code, a token, an assertion, or a
|
|
53
|
+
proof. Ada approves in the host's interface; the model can explain the
|
|
54
|
+
proposal but cannot approve it.
|
|
55
|
+
|
|
56
|
+
The same world runs in `personal_agent_protocol/__tests__/test_company_end_to_end.py`,
|
|
57
|
+
which also covers Mediated Sign-In with a one-time code, streaming, and a
|
|
58
|
+
stranger refused with `conversation_not_found`.
|
|
59
|
+
|
|
60
|
+
- Run the [Pydantic AI example](https://github.com/datalayer/personal-agent-protocol/tree/main/examples/pydantic-ai/user-with-a-company).
|
|
61
|
+
- Run the [Agent Runtimes example](https://github.com/datalayer/agent-runtimes/tree/main/examples/personal-agent-protocol/user-with-a-company).
|
|
62
|
+
- Read the [company guide](/guides/company/).
|