@datalayer/agent-runtimes 1.5.55 → 1.5.57

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.
@@ -55,9 +55,15 @@ export function PapSignInCard({ context, send, }) {
55
55
  };
56
56
  // Who the person signs in at: the company itself for a Direct Sign-In (P-04), the page's host otherwise.
57
57
  const named = read.company ?? read.host;
58
+ // The company that asks, by name and domain, beside the page (PAP 0.2 §4.6, §4.7).
59
+ const org = read.organization;
58
60
  const title = read.mode === 'mediated'
59
- ? PAP_SIGN_IN_WORDS.mediatedTitle(read.host)
60
- : PAP_SIGN_IN_WORDS.title(named);
61
+ ? org
62
+ ? PAP_SIGN_IN_WORDS.mediatedTitleFor(org.name, org.domain, read.host)
63
+ : PAP_SIGN_IN_WORDS.mediatedTitle(read.host)
64
+ : org && read.mode === 'device'
65
+ ? PAP_SIGN_IN_WORDS.titleFor(org.name, org.domain, read.host)
66
+ : PAP_SIGN_IN_WORDS.title(named);
61
67
  return (_jsxs(Box, { as: "section", "aria-label": title, my: 2, p: 3, border: "1px solid", borderColor: "border.default", borderRadius: 2, bg: "canvas.subtle", maxWidth: 480, children: [_jsx(Heading, { as: "h4", sx: { fontSize: 2, mb: 1 }, children: title }), _jsx(Text, { as: "p", sx: { mt: 0, mb: 2, color: 'fg.muted', fontSize: 1 }, children: read.mode === 'device'
62
68
  ? PAP_SIGN_IN_WORDS.device
63
69
  : read.mode === 'mediated'
@@ -16,11 +16,12 @@ const PapAuthorizationBoundaryView = () => {
16
16
  setError(null);
17
17
  try {
18
18
  const clientId = 'https://assistant.example/agent.json';
19
- const tokenEndpoint = 'https://shop.example/oauth/token';
19
+ // PAP 0.2 §4.2: the assertion names the company's issuer, not its token endpoint.
20
+ const issuer = 'https://shop.example';
20
21
  const claims = buildSessionAssertionClaims({
21
22
  clientId,
22
23
  pairwiseUserId: generatePairwiseUserId(),
23
- tokenEndpoint,
24
+ issuer,
24
25
  });
25
26
  const request = await buildDirectSignInRequest({
26
27
  authorizationEndpoint: 'https://shop.example/oauth/authorize',
@@ -32,7 +33,7 @@ const PapAuthorizationBoundaryView = () => {
32
33
  setSummary({
33
34
  session: {
34
35
  issuerBoundToClient: claims.iss === clientId,
35
- audienceBoundToTokenEndpoint: claims.aud === tokenEndpoint,
36
+ audienceBoundToIssuer: claims.aud === issuer,
36
37
  lifetimeSeconds: claims.exp - claims.iat,
37
38
  pairwiseSubjectWithheld: true,
38
39
  uniqueRequestIdWithheld: true,
@@ -13,7 +13,7 @@ const SAMPLE_DOMAIN = 'shop.example';
13
13
  const sampleCompany = (domain) => ({
14
14
  discoveryUrl: `https://${domain}/.well-known/poppy.json`,
15
15
  document: parseDiscoveryDocument({
16
- protocol_version: '0.1',
16
+ protocol_version: '0.2',
17
17
  organization: { name: 'Example Shop', domain },
18
18
  auth: {
19
19
  issuer: `https://auth.${domain}`,
@@ -28,7 +28,7 @@ const STEPS = [
28
28
  channel: 'Discovery',
29
29
  messages: conversationStart,
30
30
  facts: [
31
- { label: 'Publishes', value: 'poppy.json · draft 0.1' },
31
+ { label: 'Publishes', value: 'poppy.json · draft 0.2' },
32
32
  { label: 'Returns', value: 'Company conversation agent' },
33
33
  { label: 'Sign-in', value: "Northstar's own page" },
34
34
  ],
@@ -38,7 +38,7 @@ const STEPS = [
38
38
  request: 'Accept: application/json',
39
39
  response: `200 OK
40
40
  {
41
- "protocol_version": "0.1",
41
+ "protocol_version": "0.2",
42
42
  "organization": { "name": "Northstar Outfitters" },
43
43
  "auth": { "issuer": "https://auth.northstar.example" },
44
44
  "agent": { "protocols": [{ "type": "poppy" }] }
@@ -224,7 +224,7 @@ const companyReply = (response) => {
224
224
  */
225
225
  const runJourney = async () => {
226
226
  parseDiscoveryDocument({
227
- protocol_version: '0.1',
227
+ protocol_version: '0.2',
228
228
  organization: { name: 'Northstar Outfitters', domain: 'northstar.example' },
229
229
  auth: {
230
230
  issuer: 'https://auth.northstar.example',
@@ -243,7 +243,7 @@ const runJourney = async () => {
243
243
  buildSessionAssertionClaims({
244
244
  clientId: 'https://atlas.example/agent.json',
245
245
  pairwiseUserId: 'usr_host_only_journey',
246
- tokenEndpoint: 'https://auth.northstar.example/oauth/token',
246
+ issuer: 'https://auth.northstar.example',
247
247
  });
248
248
  await buildDirectSignInRequest({
249
249
  authorizationEndpoint: 'https://auth.northstar.example/oauth/authorize',
@@ -3,7 +3,7 @@
3
3
  "title": "Account Tokens",
4
4
  "description": "Refresh, rotation, narrowing, re-consent, and revocation of the Account Token Atlas holds for Ada at Manzanita, which never leaves the host's vault.",
5
5
  "generator": "examples/personal-agent-protocol/traces/generate.py",
6
- "sdk": "personal-agent-protocol 0.16.0",
6
+ "sdk": "personal-agent-protocol 0.25.0",
7
7
  "parties": [
8
8
  {
9
9
  "id": "user",
@@ -90,7 +90,7 @@
90
90
  "content-type": "application/json"
91
91
  },
92
92
  "body": {
93
- "protocol_version": "0.1",
93
+ "protocol_version": "0.2",
94
94
  "organization": {
95
95
  "name": "Manzanita Outfitters",
96
96
  "domain": "manzanita.example"
@@ -147,6 +147,9 @@
147
147
  "web": {
148
148
  "browser_session_endpoint": "https://manzanita.example/poppy/browser-session"
149
149
  },
150
+ "feedback": {
151
+ "endpoint": "https://manzanita.example/poppy/feedback"
152
+ },
150
153
  "extensions": {
151
154
  "operations": {
152
155
  "version": "1",
@@ -3,7 +3,7 @@
3
3
  "title": "Conversation control",
4
4
  "description": "A Direct Conversation under an open one, a handoff to a person at Manzanita, and closing, through the real ConversationClient.",
5
5
  "generator": "examples/personal-agent-protocol/traces/generate.py",
6
- "sdk": "personal-agent-protocol 0.16.0",
6
+ "sdk": "personal-agent-protocol 0.25.0",
7
7
  "parties": [
8
8
  {
9
9
  "id": "user",
@@ -90,7 +90,7 @@
90
90
  "content-type": "application/json"
91
91
  },
92
92
  "body": {
93
- "protocol_version": "0.1",
93
+ "protocol_version": "0.2",
94
94
  "organization": {
95
95
  "name": "Manzanita Outfitters",
96
96
  "domain": "manzanita.example"
@@ -147,6 +147,9 @@
147
147
  "web": {
148
148
  "browser_session_endpoint": "https://manzanita.example/poppy/browser-session"
149
149
  },
150
+ "feedback": {
151
+ "endpoint": "https://manzanita.example/poppy/feedback"
152
+ },
150
153
  "extensions": {
151
154
  "operations": {
152
155
  "version": "1",
@@ -3,7 +3,7 @@
3
3
  "title": "Conversation streaming",
4
4
  "description": "Atlas reads a Manzanita conversation over Server-Sent Events: display-only text deltas, complete message events, and a resume from Last-Event-ID.",
5
5
  "generator": "examples/personal-agent-protocol/traces/generate.py",
6
- "sdk": "personal-agent-protocol 0.16.0",
6
+ "sdk": "personal-agent-protocol 0.25.0",
7
7
  "parties": [
8
8
  {
9
9
  "id": "user",
@@ -90,7 +90,7 @@
90
90
  "content-type": "application/json"
91
91
  },
92
92
  "body": {
93
- "protocol_version": "0.1",
93
+ "protocol_version": "0.2",
94
94
  "organization": {
95
95
  "name": "Manzanita Outfitters",
96
96
  "domain": "manzanita.example"
@@ -147,6 +147,9 @@
147
147
  "web": {
148
148
  "browser_session_endpoint": "https://manzanita.example/poppy/browser-session"
149
149
  },
150
+ "feedback": {
151
+ "endpoint": "https://manzanita.example/poppy/feedback"
152
+ },
150
153
  "extensions": {
151
154
  "operations": {
152
155
  "version": "1",
@@ -3,7 +3,7 @@
3
3
  "title": "Mediated Sign-In",
4
4
  "description": "Ada signs in to Manzanita without leaving Atlas: the host's protected input collects the fields Manzanita declares and sends them to Manzanita's endpoint, once.",
5
5
  "generator": "examples/personal-agent-protocol/traces/generate.py",
6
- "sdk": "personal-agent-protocol 0.16.0",
6
+ "sdk": "personal-agent-protocol 0.25.0",
7
7
  "parties": [
8
8
  {
9
9
  "id": "user",
@@ -90,7 +90,7 @@
90
90
  "content-type": "application/json"
91
91
  },
92
92
  "body": {
93
- "protocol_version": "0.1",
93
+ "protocol_version": "0.2",
94
94
  "organization": {
95
95
  "name": "Manzanita Outfitters",
96
96
  "domain": "manzanita.example"
@@ -147,6 +147,9 @@
147
147
  "web": {
148
148
  "browser_session_endpoint": "https://manzanita.example/poppy/browser-session"
149
149
  },
150
+ "feedback": {
151
+ "endpoint": "https://manzanita.example/poppy/feedback"
152
+ },
150
153
  "extensions": {
151
154
  "operations": {
152
155
  "version": "1",
@@ -3,7 +3,7 @@
3
3
  "title": "Operations",
4
4
  "description": "Manzanita proposes an exchange; Atlas confirms only the exact revision Ada approved, at most once.",
5
5
  "generator": "examples/personal-agent-protocol/traces/generate.py",
6
- "sdk": "personal-agent-protocol 0.16.0",
6
+ "sdk": "personal-agent-protocol 0.25.0",
7
7
  "parties": [
8
8
  {
9
9
  "id": "user",
@@ -90,7 +90,7 @@
90
90
  "content-type": "application/json"
91
91
  },
92
92
  "body": {
93
- "protocol_version": "0.1",
93
+ "protocol_version": "0.2",
94
94
  "organization": {
95
95
  "name": "Manzanita Outfitters",
96
96
  "domain": "manzanita.example"
@@ -147,6 +147,9 @@
147
147
  "web": {
148
148
  "browser_session_endpoint": "https://manzanita.example/poppy/browser-session"
149
149
  },
150
+ "feedback": {
151
+ "endpoint": "https://manzanita.example/poppy/feedback"
152
+ },
150
153
  "extensions": {
151
154
  "operations": {
152
155
  "version": "1",
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "slug": "two-companies",
3
3
  "title": "Two companies working together",
4
- "description": "Ledgerly, an accounting firm, is a PAP company to Ada's agent Atlas and a PAP personal agent at Northwind Bank for her. Every approval is an Operation. This is composition: draft 0.1 defines no company-to-company protocol.",
4
+ "description": "Ledgerly, an accounting firm, is a PAP company to Ada's agent Atlas and a PAP personal agent at Northwind Bank for her. Every approval is an Operation. This is composition: draft 0.2 defines no company-to-company protocol.",
5
5
  "generator": "examples/personal-agent-protocol/traces/generate.py",
6
- "sdk": "personal-agent-protocol 0.16.0",
6
+ "sdk": "personal-agent-protocol 0.25.0",
7
7
  "parties": [
8
8
  {
9
9
  "id": "user",
@@ -120,7 +120,7 @@
120
120
  "content-type": "application/json"
121
121
  },
122
122
  "body": {
123
- "protocol_version": "0.1",
123
+ "protocol_version": "0.2",
124
124
  "organization": {
125
125
  "name": "Ledgerly",
126
126
  "domain": "ledgerly.example"
@@ -146,6 +146,9 @@
146
146
  }
147
147
  ]
148
148
  },
149
+ "feedback": {
150
+ "endpoint": "https://ledgerly.example/poppy/feedback"
151
+ },
149
152
  "extensions": {
150
153
  "operations": {
151
154
  "version": "1",
@@ -643,7 +646,7 @@
643
646
  "content-type": "application/json"
644
647
  },
645
648
  "body": {
646
- "protocol_version": "0.1",
649
+ "protocol_version": "0.2",
647
650
  "organization": {
648
651
  "name": "Northwind Bank",
649
652
  "domain": "northwind.example"
@@ -669,6 +672,9 @@
669
672
  }
670
673
  ]
671
674
  },
675
+ "feedback": {
676
+ "endpoint": "https://northwind.example/poppy/feedback"
677
+ },
672
678
  "extensions": {
673
679
  "operations": {
674
680
  "version": "1",
@@ -3,7 +3,7 @@
3
3
  "title": "A user with a company",
4
4
  "description": "Ada asks her personal agent, Atlas, to exchange a jacket at Manzanita Outfitters. Both sides are the PAP Python SDK's demo world: real keys and proofs over in-process HTTP, recorded and redacted.",
5
5
  "generator": "examples/personal-agent-protocol/traces/generate.py",
6
- "sdk": "personal-agent-protocol 0.16.0",
6
+ "sdk": "personal-agent-protocol 0.25.0",
7
7
  "parties": [
8
8
  {
9
9
  "id": "user",
@@ -95,7 +95,7 @@
95
95
  "content-type": "application/json"
96
96
  },
97
97
  "body": {
98
- "protocol_version": "0.1",
98
+ "protocol_version": "0.2",
99
99
  "organization": {
100
100
  "name": "Manzanita Outfitters",
101
101
  "domain": "manzanita.example"
@@ -152,6 +152,9 @@
152
152
  "web": {
153
153
  "browser_session_endpoint": "https://manzanita.example/poppy/browser-session"
154
154
  },
155
+ "feedback": {
156
+ "endpoint": "https://manzanita.example/poppy/feedback"
157
+ },
155
158
  "extensions": {
156
159
  "operations": {
157
160
  "version": "1",
@@ -28,6 +28,15 @@ export type PapSignInWaiting = {
28
28
  * which sends the person on to the company and takes them back only from it.
29
29
  */
30
30
  company?: string;
31
+ /**
32
+ * The company that asks, by name and domain (PAP draft 0.2 §4.6, §4.7): the
33
+ * SDK names it on every Device and Mediated Sign-In, and the card shows both
34
+ * with the link, so a company cannot pass off another's page as its own.
35
+ */
36
+ organization?: {
37
+ name: string;
38
+ domain: string;
39
+ };
31
40
  /** The code to enter, for `device`. */
32
41
  code?: string;
33
42
  /** Where the company sent a code, for `mediated`, when it did. */
@@ -43,10 +52,14 @@ export type PapSignInWaiting = {
43
52
  /** What the card says. */
44
53
  export declare const PAP_SIGN_IN_WORDS: {
45
54
  readonly title: (host: string) => string;
55
+ /** A Device Sign-In, with the company that asks named (PAP 0.2 §4.6). */
56
+ readonly titleFor: (name: string, domain: string, host: string) => string;
46
57
  readonly direct: "Open the company’s page through Datalayer, sign in there, and this conversation goes on once you are back.";
47
58
  readonly device: "Open the company’s page and enter this code there.";
48
59
  /** `mediated`: the page is Datalayer's, which names the company and asks what it asks. */
49
60
  readonly mediatedTitle: (host: string) => string;
61
+ /** A Mediated Sign-In, with the company that asks named (PAP 0.2 §4.7). */
62
+ readonly mediatedTitleFor: (name: string, domain: string, host: string) => string;
50
63
  readonly mediated: "Open this page: it names the company and asks what the company needs. Type it there, never in this conversation.";
51
64
  readonly sentTo: (to: string) => string;
52
65
  readonly needs: (scopes: string[]) => string;
@@ -5,10 +5,14 @@
5
5
  /** What the card says. */
6
6
  export const PAP_SIGN_IN_WORDS = {
7
7
  title: (host) => `Sign in at ${host}`,
8
+ /** A Device Sign-In, with the company that asks named (PAP 0.2 §4.6). */
9
+ titleFor: (name, domain, host) => `Sign in to ${name} (${domain}) at ${host}`,
8
10
  direct: 'Open the company’s page through Datalayer, sign in there, and this conversation goes on once you are back.',
9
11
  device: 'Open the company’s page and enter this code there.',
10
12
  /** `mediated`: the page is Datalayer's, which names the company and asks what it asks. */
11
13
  mediatedTitle: (host) => `Sign in through ${host}`,
14
+ /** A Mediated Sign-In, with the company that asks named (PAP 0.2 §4.7). */
15
+ mediatedTitleFor: (name, domain, host) => `Sign in to ${name} (${domain}) through ${host}`,
12
16
  mediated: 'Open this page: it names the company and asks what the company needs. Type it there, never in this conversation.',
13
17
  sentTo: (to) => `The company sent a code to ${to}.`,
14
18
  needs: (scopes) => `It needs: ${scopes.join(', ')}.`,
@@ -125,6 +129,17 @@ export function readPapSignIn(result) {
125
129
  const company = typeof data.company === 'string' && DOMAIN.test(data.company)
126
130
  ? data.company
127
131
  : '';
132
+ // The company that asks, as the SDK names it (organization_name, organization_domain).
133
+ const organizationName = typeof data.organization_name === 'string'
134
+ ? data.organization_name.trim().slice(0, 200)
135
+ : '';
136
+ const organizationDomain = typeof data.organization_domain === 'string' &&
137
+ DOMAIN.test(data.organization_domain.toLowerCase())
138
+ ? data.organization_domain.toLowerCase()
139
+ : '';
140
+ const organization = organizationName && organizationDomain
141
+ ? { name: organizationName, domain: organizationDomain }
142
+ : undefined;
128
143
  // What the company said it needs: scope tokens only, anything else not shown.
129
144
  const needs = Array.isArray(data.needs)
130
145
  ? data.needs.filter((scope) => typeof scope === 'string' && SCOPE.test(scope))
@@ -134,6 +149,7 @@ export function readPapSignIn(result) {
134
149
  open: url.toString(),
135
150
  host: url.hostname,
136
151
  ...(company ? { company } : {}),
152
+ ...(organization ? { organization } : {}),
137
153
  ...(typeof data.code === 'string' && data.code ? { code: data.code } : {}),
138
154
  ...(data.mode === 'mediated' &&
139
155
  typeof data.sent_to === 'string' &&
@@ -1,4 +1,4 @@
1
1
  export declare const PAP_PLUGIN = "agent-runtimes.protocols.pap";
2
2
  /** The PAP draft the SDK implements (its `PROTOCOL_PROFILE`; Python reads it from the SDK). */
3
- export declare const PAP_PROTOCOL_PROFILE = "0.1";
3
+ export declare const PAP_PROTOCOL_PROFILE = "0.2";
4
4
  export declare const PapPlugin: import("@datalayer/reactor").ReactorPlugin<Record<string, never>, unknown, unknown>;
@@ -18,7 +18,7 @@ import { contribution, definePlugin } from '@datalayer/reactor';
18
18
  import { DEFAULT_ORDER, ProtocolDescriptions } from '../core';
19
19
  export const PAP_PLUGIN = 'agent-runtimes.protocols.pap';
20
20
  /** The PAP draft the SDK implements (its `PROTOCOL_PROFILE`; Python reads it from the SDK). */
21
- export const PAP_PROTOCOL_PROFILE = '0.1';
21
+ export const PAP_PROTOCOL_PROFILE = '0.2';
22
22
  export const PapPlugin = definePlugin({
23
23
  name: PAP_PLUGIN,
24
24
  version: '1.0.0',
@@ -32,7 +32,7 @@ export const PapPlugin = definePlugin({
32
32
  version: PAP_PROTOCOL_PROFILE,
33
33
  roles: ['personal-agent', 'company'],
34
34
  status: 'implemented',
35
- specification: 'https://personalagentprotocol.org/docs/spec',
35
+ specification: 'https://personalagentprotocol.org/docs/0.2/spec',
36
36
  plugin: PAP_PLUGIN,
37
37
  catalogue: 'pap',
38
38
  points: [],
@@ -113,8 +113,8 @@ export const PAP_PROTOCOL_0_0_1 = {
113
113
  description: "A person's agent working with a company for them — signed out, then signed in at the company, its changes confirmed by the person — and an application being a company personal agents reach.",
114
114
  publisher: 'Sierra, Meta',
115
115
  layer: 'consent',
116
- specUrl: 'https://poppy.md',
117
- specVersion: 'draft 0.1',
116
+ specUrl: 'https://personalagentprotocol.org',
117
+ specVersion: 'draft 0.2',
118
118
  status: 'shipped',
119
119
  connects: "Companies, as a person's agent there, or being one",
120
120
  packages: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datalayer/agent-runtimes",
3
- "version": "1.5.55",
3
+ "version": "1.5.57",
4
4
  "type": "module",
5
5
  "workspaces": [
6
6
  ".",
@@ -161,7 +161,7 @@
161
161
  "@datalayer/lexical-loro": "^1.0.6",
162
162
  "@datalayer/primer-addons": "^1.0.40",
163
163
  "@datalayer/primer-rjsf": "^1.0.3",
164
- "@datalayer/personal-agent-protocol": "^0.24.0",
164
+ "@datalayer/personal-agent-protocol": "^0.25.0",
165
165
  "@datalayer/reactor": "^1.3.0",
166
166
  "@datalayer/reactor-commands": "^1.0.4",
167
167
  "@datalayer/reactor-manager": "^1.0.4",