Repository navigation
Conversation
personal_agent_protocol.ui.PapSignIn (application/vnd.datalayer.pap.sign-in+json, v1): direct, device or mediated; an https page only; the device code for the page and never in the model's view; expires_at, sent_to. from_answer reads a pap_sign_in answer, tool_meta() is the MCP _meta["reactor.ui/display"] that carries it. The core plugin declares the type via provide_display_types, importing the module only when a reactor 1.1 asks. New extra: ui (datalayer_reactor>=1.1.0).
There was a problem hiding this comment.
🟡 Changes recommended
Device codes embedded in sign-in URLs leak into model-visible fallback text despite the page-only guarantee.
1 open finding
What changed in this PR
Adds a typed Reactor UI sign-in display for PAP workflows, targeting Reactor 1.1.
Changes:
- Introduces
PapSignIn, validation, serialization, and MCP metadata. - Registers the display through the Reactor plugin hook.
- Adds UI tests, dependency extra, and release notes.
| File | Description |
|---|---|
pyproject.toml |
Adds the Reactor UI dependency extra. |
personal_agent_protocol/ui.py |
Implements the sign-in display type. |
personal_agent_protocol/reactor.py |
Registers PAP display types. |
personal_agent_protocol/__tests__/test_ui.py |
Tests display behavior and registration. |
CHANGELOG.md |
Documents the new UI integration. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| if self.mode == "direct": | ||
| return f"Sign in at {self.host}: open {self.open}, sign in there, and come back." | ||
| if self.mode == "device": | ||
| return f"Sign in at {self.host}: open {self.open} and enter the code shown there." |
…L may carry the code, so open is audience(page) beside code, and the text names only the company's domain; the test checks the complete model view, not the text with the URL stripped (review on #6)
…tor 1.1.0 is released; the test extra requires it), fixing E402 under the pinned ruff
…he overlap, the retired one refused once the cached set expires, unknown kids refetched at most once a minute); the consent page binds its request to the browser (__Host-poppy_consent, a CSRF token from the cookie, consent_decision refusing cross-site, foreign-origin, unbound and replayed forms) and the operation page's form carries a token from its poppy_session cookie, in Python and TypeScript
…ped: mypy found the Optional)
…orthwind with Ledgerly, every conformance case, the Pydantic AI examples' tools) run with CANARY-minted values and canary passwords; every credential harvested from the wire stays out of logs at DEBUG, raised errors, requested URLs, model-readable bodies, message texts and PapSignIn model views; the npm lib/ embeds no key, token or canary and its browser entry reaches no demo credential. Fixed the leak it found: Ledgerly's connect reply put Northwind's device user code in the message text
…) for replay caches, shared budgets, device polling and SSE fan-out, in Python and TypeScript, with a docs page. Fixed what they found: the memory replay cache never forgot an identifier (it now sweeps expired ones, and the verifiers remember each proof or assertion exactly as long as they would accept it: iat plus the window, exp plus the skew); the shared budget slept under its lock so max_wait never bounded the queue (it now reserves turns, GCRA, refusing a turn beyond max_wait at once, and sleeps again when a timer fires early); check_replay_cache / checkReplayCache and a concurrency option on the store kits
…t the company, the canary suite, load tests and the replay-cache and budget fixes they found)
…rver entry (lib/company/*.js is tsc's unbundled output); API reference regenerated for 0.8.0
…REVISION, OPERATIONS_VERSION in both SDKs, held equal with the docs and packages), aligned Reactor contributions (protocol/reactor-points.json, table-driven lifecycle and tenant tests in both languages; the TypeScript company serves pap.company.mcp; unused profile, extension-handler and key-store points removed; optional points fail closed on ambiguity), every public code example run in CI (docs blocks, Pydantic AI tools, Agent Runtimes PAP apps with agent-runtimes>=1.3.111), compatibility/migration/support pages, signed releases (PyPI attestations, npm provenance)
…datalayer/reactor's own lib/ is not loadable by node: extensionless ESM imports)
…n it asked (the first asks late on a loaded runner, so more callers fit; CI admitted 55 and 28 where the bound ignored that delay)
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

RU-1 (Reactor UI plan), Python slice: the sign-in card's data, typed where PAP lives, so both the gateway and the page depend on the type rather than on a hand-kept shape.
personal_agent_protocol.ui.PapSignIn:@display_type("application/vnd.datalayer.pap.sign-in+json", version=1).mode(direct|device|mediated),open(https only, no userinfo),code(audience("page"), required for device),expires_atandsent_to.text()never contains the code.PapSignIn.from_answer(answer)reads the gateway'spap_sign_inanswer and returnsNonefor any status other thanwaiting_for_the_person.tool_meta()returns{"reactor.ui/display": wire}for an MCP result's_meta.PapCorePlugin.provide_display_typesregisters the type, importing.uilazily. Only reactor 1.1 calls that hook, so the SDK still runs on reactor 1.0.x.ui = ["datalayer_reactor>=1.1.0,<2"].test_ui.pyis skipped (importorskip) until reactor 1.1.0 is on PyPI.Depends on datalayer/reactor#27 (reactor.ui, 1.1.0). Do not release yet. The gateway's
pap_sign_inwill returnPapSignIn.from_answer(...).tool_meta()once both are released.Tests:
test_ui.py(10) andtest_reactor.py, 37 passed locally against the reactor feat/ui-channel checkout.