@datalayer/agent-runtimes 1.5.9 → 1.5.10

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.
@@ -1114,6 +1114,24 @@ export const APPSPEC_SCHEMA = {
1114
1114
  title: 'AppPageOutput',
1115
1115
  type: 'object',
1116
1116
  },
1117
+ AppPair: {
1118
+ additionalProperties: false,
1119
+ description: "One of a pair of examples, a PACT business and the personal agent that asks it\n(AGENT_PROTOCOLS PR-13, E-02; decided 2026-10-13).\n\nA personal agent's issuer is its own application's, known only once a copy\nexists: when a person has copied both of a pair, the Studio registers the\npersonal agent's copy with the business's copy (`pact.business.registered_agents`)\nand points the personal agent at the business's own domain.",
1120
+ properties: {
1121
+ id: {
1122
+ description: "The pair's id, the same on both of its applications",
1123
+ title: 'Id',
1124
+ type: 'string',
1125
+ },
1126
+ role: {
1127
+ $ref: '#/$defs/PairRole',
1128
+ description: '`business`, or `personal_agent`: the one that asks it',
1129
+ },
1130
+ },
1131
+ required: ['id', 'role'],
1132
+ title: 'AppPair',
1133
+ type: 'object',
1134
+ },
1117
1135
  AppPap: {
1118
1136
  additionalProperties: false,
1119
1137
  description: 'Personal Agent Protocol: the companies it works with, and whether it is one.\n\nA `pap` block names the profile it is written for (PAP_DATALAYER S-03): one\nDatalayer speaks, or it is refused in a sentence. An application without the\nblock has none.',
@@ -1652,6 +1670,41 @@ export const APPSPEC_SCHEMA = {
1652
1670
  title: 'AppScenario',
1653
1671
  type: 'object',
1654
1672
  },
1673
+ AppSignedFetch: {
1674
+ additionalProperties: false,
1675
+ description: 'Signed fetch: the sites it reads pages of, signed with its Web Bot Auth key (AGENT_PROTOCOLS EX-11).',
1676
+ properties: {
1677
+ sites: {
1678
+ description: 'Sites, each by its exact domain: read with GET only, every request signed',
1679
+ items: {
1680
+ $ref: '#/$defs/AppSignedFetchSite',
1681
+ },
1682
+ title: 'Sites',
1683
+ type: 'array',
1684
+ },
1685
+ },
1686
+ title: 'AppSignedFetch',
1687
+ type: 'object',
1688
+ },
1689
+ AppSignedFetchSite: {
1690
+ additionalProperties: false,
1691
+ description: "A website the application reads pages of, each request signed (AGENT_PROTOCOLS EX-11).\n\nDecided 2026-10-13: a *signed fetch* names exact sites, an allow-list.\nDatalayer's gateway reads a page there with `GET` only, on its safe\negress path (public addresses only), each request signed with the\napplication's own Web Bot Auth key and recorded; reading is under the\napplication's Rules like any read. Named by its domain: no other host is\nreached, and no credential is ever part of a spec.",
1692
+ properties: {
1693
+ id: {
1694
+ description: 'Stable within the application: `example-verifier`',
1695
+ title: 'Id',
1696
+ type: 'string',
1697
+ },
1698
+ site: {
1699
+ description: "The site's domain, exactly: `verify.examples.datalayer.run`",
1700
+ title: 'Site',
1701
+ type: 'string',
1702
+ },
1703
+ },
1704
+ required: ['id', 'site'],
1705
+ title: 'AppSignedFetchSite',
1706
+ type: 'object',
1707
+ },
1655
1708
  AppSpaceGrant: {
1656
1709
  additionalProperties: false,
1657
1710
  description: 'A Space the application may reach.',
@@ -2360,6 +2413,12 @@ export const APPSPEC_SCHEMA = {
2360
2413
  title: 'Layout',
2361
2414
  type: 'string',
2362
2415
  },
2416
+ PairRole: {
2417
+ description: 'Which side of a pair of examples an application is (AGENT_PROTOCOLS PR-13).',
2418
+ enum: ['business', 'personal_agent'],
2419
+ title: 'PairRole',
2420
+ type: 'string',
2421
+ },
2363
2422
  PapAgents: {
2364
2423
  description: 'Which personal agents a company application accepts.',
2365
2424
  enum: ['any', 'registered'],
@@ -2567,7 +2626,7 @@ export const APPSPEC_SCHEMA = {
2567
2626
  type: 'array',
2568
2627
  },
2569
2628
  protocols: {
2570
- description: 'The agent protocols it speaks, ids of the protocols catalogue (AGENT_PROTOCOLS PS-02): its `pap`, `pact` and `a2a` blocks, and each merchant of `commerce`, are refused unless their protocol is listed, and a planned protocol only while it is not offered',
2629
+ description: 'The agent protocols it speaks, ids of the protocols catalogue (AGENT_PROTOCOLS PS-02): its `pap`, `pact`, `signed_fetch` and `a2a` blocks, and each merchant of `commerce`, are refused unless their protocol is listed, and a planned protocol only while it is not offered',
2571
2630
  items: {
2572
2631
  type: 'string',
2573
2632
  },
@@ -2594,6 +2653,22 @@ export const APPSPEC_SCHEMA = {
2594
2653
  $ref: '#/$defs/AppCommerce',
2595
2654
  description: 'UCP and ACP: merchants it shops at for each person',
2596
2655
  },
2656
+ signed_fetch: {
2657
+ $ref: '#/$defs/AppSignedFetch',
2658
+ description: 'Web Bot Auth: the sites it reads pages of, GET only, each request signed with its key',
2659
+ },
2660
+ pair: {
2661
+ anyOf: [
2662
+ {
2663
+ $ref: '#/$defs/AppPair',
2664
+ },
2665
+ {
2666
+ type: 'null',
2667
+ },
2668
+ ],
2669
+ default: null,
2670
+ description: 'One of a pair of examples: a PACT business, or the personal agent that asks it',
2671
+ },
2597
2672
  a2a: {
2598
2673
  $ref: '#/$defs/AppA2A',
2599
2674
  description: 'A2A: the extensions its Agent Card advertises',
@@ -162,7 +162,7 @@ export const WEB_BOT_AUTH_PROTOCOL_0_0_1 = {
162
162
  id: 'web-bot-auth',
163
163
  version: '0.0.1',
164
164
  name: 'Web Bot Auth',
165
- description: 'Signed outbound requests (RFC 9421) and the key directory a website checks them against.',
165
+ description: 'Signed outbound requests (RFC 9421) and the key directory a website checks them against. In applications, every request to a company, business or merchant is signed, and a signed fetch reads pages at the sites an application names, GET only (decided 2026-10-13).',
166
166
  publisher: 'Cloudflare (IETF draft)',
167
167
  layer: 'identity',
168
168
  specUrl: 'https://datatracker.ietf.org/doc/draft-ietf-webbotauth-httpsig-protocol/',
@@ -173,7 +173,8 @@ export const WEB_BOT_AUTH_PROTOCOL_0_0_1 = {
173
173
  python: ['agent-runtimes'],
174
174
  typescript: ['@datalayer/agent-runtimes', 'web-bot-auth'],
175
175
  },
176
- protocolTools: [],
176
+ protocolTools: ['signed-fetch'],
177
+ appspecBlock: 'signed_fetch',
177
178
  };
178
179
  export const PROTOCOL_CATALOGUE = {
179
180
  a2a: A2A_PROTOCOL_0_0_1,
@@ -156,7 +156,7 @@ export interface ProtocolSpec {
156
156
  /** Its tools' action-class tables (`agentspecs/protocol-tools`). */
157
157
  protocolTools: string[];
158
158
  /** The Appspec block it configures, if any: refused unless `protocols` lists it. */
159
- appspecBlock?: 'pap' | 'pact' | 'a2a';
159
+ appspecBlock?: 'pap' | 'pact' | 'a2a' | 'signed_fetch';
160
160
  }
161
161
  /** A check a Frame requires of the output of work done under it. */
162
162
  export interface FrameGuardSpec {
@@ -630,6 +630,34 @@ export interface AppCommerceMerchantSpec {
630
630
  export interface AppCommerceSpec {
631
631
  merchants: AppCommerceMerchantSpec[];
632
632
  }
633
+ /**
634
+ * A website the application reads pages of, each request signed with its
635
+ * own Web Bot Auth key (AGENT_PROTOCOLS EX-11, decided 2026-10-13): the
636
+ * gateway's `signed-fetch` toolset reads there with GET only. Never a
637
+ * credential.
638
+ */
639
+ export interface AppSignedFetchSiteSpec {
640
+ /** Stable within the application: `example-verifier`. */
641
+ id: string;
642
+ /** The site's domain, exactly: `verify.examples.datalayer.run`. */
643
+ site: string;
644
+ }
645
+ /** Signed fetch: the exact sites it reads pages of, an allow-list. */
646
+ export interface AppSignedFetchSpec {
647
+ sites: AppSignedFetchSiteSpec[];
648
+ }
649
+ /**
650
+ * One of a pair of examples, a PACT business and the personal agent that
651
+ * asks it (AGENT_PROTOCOLS PR-13; decided 2026-10-13): when a person has
652
+ * copied both, the Studio registers the personal agent's copy with the
653
+ * business's copy and points the personal agent there.
654
+ */
655
+ export interface AppPairSpec {
656
+ /** The pair's id, the same on both of its applications. */
657
+ id: string;
658
+ /** Which side of the pair it is. */
659
+ role: 'business' | 'personal_agent';
660
+ }
633
661
  /**
634
662
  * An A2A extension the application's Agent Card advertises, beside the
635
663
  * runtime's own (AGENT_PROTOCOLS PR-02). Its params are public: never a
@@ -1237,6 +1265,10 @@ export interface AppSpec {
1237
1265
  pact?: AppPactSpec;
1238
1266
  /** UCP and ACP: the merchants it shops at for each person (AGENT_PROTOCOLS PI-01). */
1239
1267
  commerce?: AppCommerceSpec;
1268
+ /** Signed fetch: the sites it reads pages of, each request signed (AGENT_PROTOCOLS EX-11). */
1269
+ signed_fetch?: AppSignedFetchSpec;
1270
+ /** One of a pair of examples: a PACT business, or the personal agent that asks it (PR-13). */
1271
+ pair?: AppPairSpec;
1240
1272
  /** A2A: the extensions its Agent Card advertises (AGENT_PROTOCOLS PR-02). */
1241
1273
  a2a?: AppA2ASpec;
1242
1274
  rules: AppRuleSpec[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datalayer/agent-runtimes",
3
- "version": "1.5.9",
3
+ "version": "1.5.10",
4
4
  "type": "module",
5
5
  "workspaces": [
6
6
  ".",
@@ -156,8 +156,8 @@ def load_specs(specs_dir: Path) -> tuple[list[dict[str, Any]], dict[str, Any]]:
156
156
  mode="json", by_alias=True
157
157
  ):
158
158
  spec.pop("pap")
159
- # PACT, commerce and A2A's extensions the same way (AGENT_PROTOCOLS PI-01, PR-02).
160
- for block in ("pact", "commerce", "a2a"):
159
+ # PACT, commerce, signed fetch and A2A's extensions the same way (AGENT_PROTOCOLS PI-01, PR-02, EX-11).
160
+ for block in ("pact", "commerce", "signed_fetch", "a2a"):
161
161
  if block in spec and spec[block] == type(getattr(app, block))().model_dump(
162
162
  mode="json", by_alias=True
163
163
  ):
@@ -26,7 +26,7 @@ from versioning import ensure_spec_version, version_suffix
26
26
 
27
27
  LAYERS = ("transport", "consent", "identity", "commerce", "ui")
28
28
  STATUSES = ("shipped", "planned")
29
- BLOCKS = ("pap", "pact", "a2a")
29
+ BLOCKS = ("pap", "pact", "a2a", "signed_fetch")
30
30
 
31
31
 
32
32
  def load_protocol_specs(specs_dir: Path) -> list[dict[str, Any]]: