@datalayer/agent-runtimes 1.4.0 → 1.5.0
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.
- package/dist-embed/chunks/ChatView-CaBuPTyG.js +32 -0
- package/dist-embed/chunks/{DeckComponent-CuRWiARr.js → DeckComponent-cRJJMGgt.js} +1 -1
- package/dist-embed/chunks/{DocumentView-BYU2HREd.js → DocumentView-CiqN9ze6.js} +1 -1
- package/dist-embed/chunks/{EphemeralDocument-BjFSuQKH.js → EphemeralDocument-BjJfn7J-.js} +1 -1
- package/dist-embed/chunks/{ExcalidrawComponent-CFLnMPnf.js → ExcalidrawComponent-BtNXWUN8.js} +1 -1
- package/dist-embed/chunks/{ExcalidrawModal-CB9d5Vpk.js → ExcalidrawModal-C6SEKFlD.js} +1 -1
- package/dist-embed/chunks/{JupyterLexicalExtension-CYnZrelh.js → JupyterLexicalExtension-BuRLImy5.js} +5 -5
- package/dist-embed/chunks/{NotebookToolSurfaces-D62q-lbb.js → NotebookToolSurfaces-ktcGRm7d.js} +1 -1
- package/dist-embed/chunks/{Output-2KxoKu5F.js → Output-BscOPLqE.js} +10 -10
- package/dist-embed/chunks/{YouTubePlugin-CjODyxZ2.js → YouTubePlugin-xBjNr2Iu.js} +1 -1
- package/dist-embed/chunks/{ar-SA-G6X2FPQ2-C-zAYgA-.js → ar-SA-G6X2FPQ2-BB82iKLz.js} +1 -1
- package/dist-embed/chunks/{az-AZ-76LH7QW2-BHq5js6U.js → az-AZ-76LH7QW2-DsMRKXlw.js} +1 -1
- package/dist-embed/chunks/{bg-BG-XCXSNQG7-BTcNNcTc.js → bg-BG-XCXSNQG7-43Y1kPxa.js} +1 -1
- package/dist-embed/chunks/{bn-BD-2XOGV67Q-DXRk27u1.js → bn-BD-2XOGV67Q-CLqPJBll.js} +1 -1
- package/dist-embed/chunks/{ca-ES-6MX7JW3Y-D-0J9rqp.js → ca-ES-6MX7JW3Y-CDFGSEh3.js} +1 -1
- package/dist-embed/chunks/{cs-CZ-2BRQDIVT-CgN3I-57.js → cs-CZ-2BRQDIVT-ByNB8eZd.js} +1 -1
- package/dist-embed/chunks/{da-DK-5WZEPLOC-CHQloSoX.js → da-DK-5WZEPLOC-B7MrVwy8.js} +1 -1
- package/dist-embed/chunks/{de-DE-XR44H4JA-C-Hq84pe.js → de-DE-XR44H4JA-CN1cdk94.js} +1 -1
- package/dist-embed/chunks/{el-GR-BZB4AONW-MTzGcSsP.js → el-GR-BZB4AONW-DnaGhWD1.js} +1 -1
- package/dist-embed/chunks/{es-ES-U4NZUMDT-Thj-4Rwn.js → es-ES-U4NZUMDT-DE1vZzDE.js} +1 -1
- package/dist-embed/chunks/{eu-ES-A7QVB2H4-BEEyNQo-.js → eu-ES-A7QVB2H4-DmHB0zpm.js} +1 -1
- package/dist-embed/chunks/{fa-IR-HGAKTJCU-CtUGmNBZ.js → fa-IR-HGAKTJCU-CNzE8tJj.js} +1 -1
- package/dist-embed/chunks/{fi-FI-Z5N7JZ37-6GMgpkSu.js → fi-FI-Z5N7JZ37-Ca2vTFQC.js} +1 -1
- package/dist-embed/chunks/{fr-FR-RHASNOE6-BakNCbxj.js → fr-FR-RHASNOE6-B0yWFX3_.js} +1 -1
- package/dist-embed/chunks/{gl-ES-HMX3MZ6V-Cwkb9OPk.js → gl-ES-HMX3MZ6V-2_3FMVJq.js} +1 -1
- package/dist-embed/chunks/{he-IL-6SHJWFNN-BaMmvCkr.js → he-IL-6SHJWFNN-BW1lby00.js} +1 -1
- package/dist-embed/chunks/{hi-IN-IWLTKZ5I-1aWewhep.js → hi-IN-IWLTKZ5I-DTixfSwB.js} +1 -1
- package/dist-embed/chunks/{hu-HU-A5ZG7DT2-BIHI23BQ.js → hu-HU-A5ZG7DT2-DOfYwLWP.js} +1 -1
- package/dist-embed/chunks/{id-ID-SAP4L64H-CYpgmx8X.js → id-ID-SAP4L64H-Cwtdtkvg.js} +1 -1
- package/dist-embed/chunks/{index-BhSMzuKq.js → index--qMT5k1q.js} +1 -1
- package/dist-embed/chunks/{index-b1yzCiTq.js → index-B-UP9DlM.js} +1 -1
- package/dist-embed/chunks/{index-DMKsCn-y.js → index-BAwsCLGT.js} +1 -1
- package/dist-embed/chunks/{index-BUhqZVtg.js → index-BITOMOWN.js} +1 -1
- package/dist-embed/chunks/{index-1wTrAXI1.js → index-B_9UD0bt.js} +2 -2
- package/dist-embed/chunks/{index-DtlUttQj.js → index-BgFbP5P0.js} +1 -1
- package/dist-embed/chunks/{index-CC-Ht79i.js → index-CMUTS_sA.js} +1 -1
- package/dist-embed/chunks/{index-B7nmHsEo.js → index-Cgf7tlW3.js} +1 -1
- package/dist-embed/chunks/{index-CsZ2HycN.js → index-CrNfUmIU.js} +1 -1
- package/dist-embed/chunks/{index-DIOcQUrz.js → index-CzuLxFBK.js} +1 -1
- package/dist-embed/chunks/{index-EmZm7_bH.js → index-DEn5R18M.js} +1 -1
- package/dist-embed/chunks/{index-DeVZ-nmF.js → index-DFEBhySA.js} +1 -1
- package/dist-embed/chunks/{index-CMYyiALV.js → index-DYkwi0aX.js} +1 -1
- package/dist-embed/chunks/{index-Fzz2KjFM.js → index-DvpdAlVH.js} +1 -1
- package/dist-embed/chunks/{index-W7TVoWP5.js → index-Dyh5xopp.js} +1 -1
- package/dist-embed/chunks/{index-en9Yf1Yz.js → index-Jt4bWLoz.js} +1 -1
- package/dist-embed/chunks/{index-BbucLMre.js → index-S-sjhoD3.js} +1 -1
- package/dist-embed/chunks/{index-D18sf241.js → index-TRLGqZaF.js} +1 -1
- package/dist-embed/chunks/{index-ZZnjmFwm.js → index-YcqCoWJl.js} +1 -1
- package/dist-embed/chunks/{index-BFLtEBuP.js → index-sQy5cmWo.js} +1 -1
- package/dist-embed/chunks/{it-IT-JPQ66NNP-CLcqplyX.js → it-IT-JPQ66NNP-C3xZ61-6.js} +1 -1
- package/dist-embed/chunks/{ja-JP-DBVTYXUO-u8Qe6tR7.js → ja-JP-DBVTYXUO-CeTmglEb.js} +1 -1
- package/dist-embed/chunks/{kaa-6HZHGXH3-BG2kx50I.js → kaa-6HZHGXH3-D6Jr6B6Y.js} +1 -1
- package/dist-embed/chunks/{kab-KAB-ZGHBKWFO-CSYUpRxd.js → kab-KAB-ZGHBKWFO-pEXBqeuG.js} +1 -1
- package/dist-embed/chunks/{kk-KZ-P5N5QNE5-CpBMgHAz.js → kk-KZ-P5N5QNE5-BRJunmHm.js} +1 -1
- package/dist-embed/chunks/{km-KH-HSX4SM5Z-CoMUUQMb.js → km-KH-HSX4SM5Z--GJgT9rN.js} +1 -1
- package/dist-embed/chunks/{ko-KR-MTYHY66A-DwxY8CGI.js → ko-KR-MTYHY66A-Bjnez4qR.js} +1 -1
- package/dist-embed/chunks/{ku-TR-6OUDTVRD-UoNYUfm0.js → ku-TR-6OUDTVRD-DgOdYJrS.js} +1 -1
- package/dist-embed/chunks/{lt-LT-XHIRWOB4-Dr4uXaEj.js → lt-LT-XHIRWOB4-BMwhrtjM.js} +1 -1
- package/dist-embed/chunks/{lv-LV-5QDEKY6T-CNC56J-_.js → lv-LV-5QDEKY6T-0pxW7YE0.js} +1 -1
- package/dist-embed/chunks/{mr-IN-CRQNXWMA-BKWa9nzZ.js → mr-IN-CRQNXWMA-tndp8BXC.js} +1 -1
- package/dist-embed/chunks/{my-MM-5M5IBNSE-bwAzOWhV.js → my-MM-5M5IBNSE-sispDhO4.js} +1 -1
- package/dist-embed/chunks/{nb-NO-T6EIAALU-CkpsChor.js → nb-NO-T6EIAALU-CjBurOuS.js} +1 -1
- package/dist-embed/chunks/{nl-NL-IS3SIHDZ-COVk4rlb.js → nl-NL-IS3SIHDZ-B58EVmr3.js} +1 -1
- package/dist-embed/chunks/{nn-NO-6E72VCQL-DlyFF-C1.js → nn-NO-6E72VCQL-D1p7LZSq.js} +1 -1
- package/dist-embed/chunks/{oc-FR-POXYY2M6-CFDosV2C.js → oc-FR-POXYY2M6-C1M8sddP.js} +1 -1
- package/dist-embed/chunks/{pa-IN-N4M65BXN-BKRB3O0U.js → pa-IN-N4M65BXN-D8ESzASl.js} +1 -1
- package/dist-embed/chunks/{percentages-BXMCSKIN-D7pnqUsZ.js → percentages-BXMCSKIN-BihMTsFR.js} +3 -3
- package/dist-embed/chunks/{pl-PL-T2D74RX3-C5r2Tds7.js → pl-PL-T2D74RX3-DQGe6LHC.js} +1 -1
- package/dist-embed/chunks/{pt-BR-5N22H2LF-CDnT98bW.js → pt-BR-5N22H2LF-CvXBgZQs.js} +1 -1
- package/dist-embed/chunks/{pt-PT-UZXXM6DQ-C6c4SPk1.js → pt-PT-UZXXM6DQ-BMnnlIUJ.js} +1 -1
- package/dist-embed/chunks/{ro-RO-JPDTUUEW-CW6pbzEZ.js → ro-RO-JPDTUUEW-DZ-9UUH7.js} +1 -1
- package/dist-embed/chunks/{ru-RU-B4JR7IUQ-CbaAJG0w.js → ru-RU-B4JR7IUQ-JlRBwjob.js} +1 -1
- package/dist-embed/chunks/{si-LK-N5RQ5JYF-BZkUjpXF.js → si-LK-N5RQ5JYF-Bx8kHnkd.js} +1 -1
- package/dist-embed/chunks/{sk-SK-C5VTKIMK-DsfWgpPU.js → sk-SK-C5VTKIMK-xsfEfbZb.js} +1 -1
- package/dist-embed/chunks/{sl-SI-NN7IZMDC-Kx0FqxKU.js → sl-SI-NN7IZMDC-SQYUECnr.js} +1 -1
- package/dist-embed/chunks/{subset-shared.chunk-DM3l9OuH.js → subset-shared.chunk-Ch6j8nKC.js} +1 -1
- package/dist-embed/chunks/{subset-worker.chunk-4w4yibm3.js → subset-worker.chunk-pJjck5pR.js} +1 -1
- package/dist-embed/chunks/{sv-SE-XGPEYMSR-DY0ryO-L.js → sv-SE-XGPEYMSR-BxcjSHE2.js} +1 -1
- package/dist-embed/chunks/{ta-IN-2NMHFXQM-CWpIs0i0.js → ta-IN-2NMHFXQM-rItSkDUS.js} +1 -1
- package/dist-embed/chunks/{th-TH-HPSO5L25-Cwkcfb3u.js → th-TH-HPSO5L25-B7UzESFj.js} +1 -1
- package/dist-embed/chunks/{tr-TR-DEFEU3FU-BqJZZl-Y.js → tr-TR-DEFEU3FU-Ci6oNfEX.js} +1 -1
- package/dist-embed/chunks/{uk-UA-QMV73CPH-Dg213mG4.js → uk-UA-QMV73CPH-C9csqvO6.js} +1 -1
- package/dist-embed/chunks/{vi-VN-M7AON7JQ-DY94NKxF.js → vi-VN-M7AON7JQ-DRAj2kZj.js} +1 -1
- package/dist-embed/chunks/{zh-CN-LNUGB5OW-B6I9A7sA.js → zh-CN-LNUGB5OW-DLOyW8hH.js} +1 -1
- package/dist-embed/chunks/{zh-HK-E62DVLB3-D3oqgDOt.js → zh-HK-E62DVLB3-DwC6_2Ws.js} +1 -1
- package/dist-embed/chunks/{zh-TW-RAJ6MFWO-CYwgY0Jo.js → zh-TW-RAJ6MFWO-DEMugIwa.js} +1 -1
- package/dist-embed/datalayer-app-main.js +42 -42
- package/lib/apps/apps/appspec.js +22 -0
- package/lib/apps/core/index.d.ts +8 -0
- package/lib/apps/embed/AppEmbed.js +10 -13
- package/lib/apps/embed/hostBridge.d.ts +47 -13
- package/lib/apps/embed/hostBridge.js +135 -18
- package/lib/apps/index.d.ts +1 -1
- package/lib/apps/index.js +1 -1
- package/lib/apps/plugins/app-elements/QuestionView.d.ts +5 -3
- package/lib/apps/plugins/app-elements/QuestionView.js +15 -2
- package/lib/apps/plugins/app-page/appPageModel.d.ts +6 -8
- package/lib/apps/plugins/app-page/appPageModel.js +0 -2
- package/lib/apps/plugins/app-page/pageRun.d.ts +2 -2
- package/lib/apps/plugins/app-page/pageRun.js +3 -3
- package/lib/apps/plugins/chat/ChatView.js +22 -3
- package/lib/chat/base/ChatBase.js +33 -3
- package/lib/chat/base/uiFiles.d.ts +29 -0
- package/lib/chat/base/uiFiles.js +69 -0
- package/lib/chat/messages/ChatMessageList.d.ts +7 -2
- package/lib/chat/messages/ChatMessageList.js +2 -2
- package/lib/examples/ProtocolSignedRequestsExample.d.ts +10 -0
- package/lib/examples/ProtocolSignedRequestsExample.js +41 -0
- package/lib/examples/ProtocolUcpCheckoutExample.d.ts +10 -0
- package/lib/examples/ProtocolUcpCheckoutExample.js +59 -0
- package/lib/examples/example-selector.js +2 -0
- package/lib/examples/exampleGroups.d.ts +1 -1
- package/lib/examples/exampleGroups.js +4 -0
- package/lib/examples/index.d.ts +2 -0
- package/lib/examples/index.js +2 -0
- package/lib/examples/protocols/signedRequestsDemo.d.ts +27 -0
- package/lib/examples/protocols/signedRequestsDemo.js +59 -0
- package/lib/examples/protocols/ucpCheckoutDemo.d.ts +36 -0
- package/lib/examples/protocols/ucpCheckoutDemo.js +68 -0
- package/lib/protocols/a2a/index.js +1 -0
- package/lib/protocols/agentic-commerce/index.js +1 -0
- package/lib/protocols/core.d.ts +6 -0
- package/lib/protocols/mcp/index.js +1 -0
- package/lib/protocols/pact/index.js +1 -0
- package/lib/protocols/ucp/index.js +1 -0
- package/lib/protocols/ucp/merchant.d.ts +15 -0
- package/lib/protocols/ucp/merchant.js +257 -0
- package/lib/protocols/web-bot-auth/index.js +1 -0
- package/lib/specs/apps.js +87 -6
- package/lib/specs/appspecSchema.js +43 -0
- package/lib/types/agentspecs.d.ts +18 -0
- package/lib/types/protocol.d.ts +7 -0
- package/package.json +2 -2
- package/dist-embed/chunks/ChatView-BpKZPdcp.js +0 -32
package/lib/protocols/core.d.ts
CHANGED
|
@@ -26,6 +26,12 @@ export interface ProtocolDescription {
|
|
|
26
26
|
status: 'implemented' | 'partial' | 'planned';
|
|
27
27
|
specification: string;
|
|
28
28
|
plugin: string;
|
|
29
|
+
/**
|
|
30
|
+
* Its id in the agentspecs protocols catalogue (`agentspecs/protocols`,
|
|
31
|
+
* AGENT_PROTOCOLS PS-01): `web-bot-auth`, `acp`… — how Studio reads a
|
|
32
|
+
* runtime's answer against the catalogue (PR-50).
|
|
33
|
+
*/
|
|
34
|
+
catalogue: string;
|
|
29
35
|
/** The contribution points its plugin declares, its extensions' included. */
|
|
30
36
|
points: string[];
|
|
31
37
|
}
|
|
@@ -69,6 +69,7 @@ export const PactPlugin = definePlugin({
|
|
|
69
69
|
status: 'partial',
|
|
70
70
|
specification: 'https://github.com/openpactprotocol/openpactprotocol/blob/main/docs/spec.md',
|
|
71
71
|
plugin: PACT_PLUGIN,
|
|
72
|
+
catalogue: 'pact',
|
|
72
73
|
points: POINTS.map(point => point.id),
|
|
73
74
|
}, { id: 'pact', order: DEFAULT_ORDER }),
|
|
74
75
|
contribution(PactDelegatedProfiles, { grantType: DEVICE_CODE_GRANT }, { id: 'device-code', order: DEFAULT_ORDER }),
|
|
@@ -64,6 +64,7 @@ export const UcpPlugin = definePlugin({
|
|
|
64
64
|
status: 'partial',
|
|
65
65
|
specification: `https://ucp.dev/${UCP_VERSION}/specification/overview`,
|
|
66
66
|
plugin: UCP_PLUGIN,
|
|
67
|
+
catalogue: 'ucp',
|
|
67
68
|
points: UCP_POINTS.map(point => point.id),
|
|
68
69
|
}, { id: 'ucp', order: DEFAULT_ORDER }),
|
|
69
70
|
],
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** The store's products, as the Python store lists them. */
|
|
2
|
+
export declare const EXAMPLE_STORE_CATALOG: Record<string, {
|
|
3
|
+
title: string;
|
|
4
|
+
price: number;
|
|
5
|
+
}>;
|
|
6
|
+
/** The one payment handler it takes, and the prefix of its test tokens. */
|
|
7
|
+
export declare const EXAMPLE_STORE_HANDLER_ID = "test_pay_1";
|
|
8
|
+
/** The store: its `fetch`, and the orders it took. */
|
|
9
|
+
export declare function exampleStore(base?: string): {
|
|
10
|
+
fetch: typeof fetch;
|
|
11
|
+
orders: Array<{
|
|
12
|
+
order: string;
|
|
13
|
+
checkout: string;
|
|
14
|
+
}>;
|
|
15
|
+
};
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* *Example Store*, the local UCP test merchant, as a `fetch` (AGENT_PROTOCOLS
|
|
7
|
+
* EX-04, EX-10): the same catalogue, totals, email gate, idempotency and
|
|
8
|
+
* test payment as `agent_runtimes.protocols.ucp.merchant.ExampleStore`, so a
|
|
9
|
+
* page or a test buys from it with no network. A test merchant only: it keeps
|
|
10
|
+
* nothing beyond the page, and refuses any payment but its test handler's.
|
|
11
|
+
*
|
|
12
|
+
* @module protocols/ucp/merchant
|
|
13
|
+
*/
|
|
14
|
+
import { CHECKOUT_CAPABILITY, SHOPPING_SERVICE, UCP_VERSION } from './index';
|
|
15
|
+
/** The store's products, as the Python store lists them. */
|
|
16
|
+
export const EXAMPLE_STORE_CATALOG = {
|
|
17
|
+
tea_sencha: { title: 'Sencha green tea, 100 g', price: 1250 },
|
|
18
|
+
tea_assam: { title: 'Assam black tea, 250 g', price: 1800 },
|
|
19
|
+
mug: { title: 'Stoneware mug', price: 2400 },
|
|
20
|
+
};
|
|
21
|
+
/** The one payment handler it takes, and the prefix of its test tokens. */
|
|
22
|
+
export const EXAMPLE_STORE_HANDLER_ID = 'test_pay_1';
|
|
23
|
+
const TEST_TOKEN_PREFIX = 'tok_test_';
|
|
24
|
+
const json = (body, status = 200) => new Response(JSON.stringify(body), {
|
|
25
|
+
status,
|
|
26
|
+
headers: { 'content-type': 'application/json' },
|
|
27
|
+
});
|
|
28
|
+
const refuse = (status, code, content) => json({
|
|
29
|
+
ucp: { version: UCP_VERSION, status: 'error' },
|
|
30
|
+
messages: [{ type: 'error', code, content, severity: 'recoverable' }],
|
|
31
|
+
}, status);
|
|
32
|
+
const meta = () => ({
|
|
33
|
+
version: UCP_VERSION,
|
|
34
|
+
status: 'success',
|
|
35
|
+
capabilities: { [CHECKOUT_CAPABILITY]: [{ version: UCP_VERSION }] },
|
|
36
|
+
payment_handlers: {
|
|
37
|
+
'com.example.test_pay': [
|
|
38
|
+
{
|
|
39
|
+
id: EXAMPLE_STORE_HANDLER_ID,
|
|
40
|
+
version: UCP_VERSION,
|
|
41
|
+
available_instruments: [{ type: 'card' }],
|
|
42
|
+
config: {},
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
async function fingerprint(path, body) {
|
|
48
|
+
const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(path + body));
|
|
49
|
+
return Array.from(new Uint8Array(digest), b => b.toString(16).padStart(2, '0')).join('');
|
|
50
|
+
}
|
|
51
|
+
/** The store: its `fetch`, and the orders it took. */
|
|
52
|
+
export function exampleStore(base = 'https://store.example') {
|
|
53
|
+
const checkouts = new Map();
|
|
54
|
+
const replies = new Map();
|
|
55
|
+
const orders = [];
|
|
56
|
+
const render = (checkout) => {
|
|
57
|
+
let subtotal = 0;
|
|
58
|
+
const lines = checkout.lines.map((line, index) => {
|
|
59
|
+
const product = EXAMPLE_STORE_CATALOG[line.id];
|
|
60
|
+
const amount = product.price * line.quantity;
|
|
61
|
+
subtotal += amount;
|
|
62
|
+
return {
|
|
63
|
+
id: `li_${index + 1}`,
|
|
64
|
+
item: { id: line.id, title: product.title, price: product.price },
|
|
65
|
+
quantity: line.quantity,
|
|
66
|
+
totals: [
|
|
67
|
+
{ type: 'subtotal', amount },
|
|
68
|
+
{ type: 'total', amount },
|
|
69
|
+
],
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
const tax = Math.round(subtotal * 0.08);
|
|
73
|
+
const messages = [];
|
|
74
|
+
if (['incomplete', 'ready_for_complete'].includes(checkout.status)) {
|
|
75
|
+
checkout.status = checkout.buyer?.email
|
|
76
|
+
? 'ready_for_complete'
|
|
77
|
+
: 'incomplete';
|
|
78
|
+
if (!checkout.buyer?.email) {
|
|
79
|
+
messages.push({
|
|
80
|
+
type: 'error',
|
|
81
|
+
code: 'missing',
|
|
82
|
+
path: '$.buyer.email',
|
|
83
|
+
content: 'Buyer email is required',
|
|
84
|
+
severity: 'recoverable',
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
ucp: meta(),
|
|
90
|
+
id: checkout.id,
|
|
91
|
+
status: checkout.status,
|
|
92
|
+
currency: 'USD',
|
|
93
|
+
line_items: lines,
|
|
94
|
+
totals: [
|
|
95
|
+
{ type: 'subtotal', amount: subtotal },
|
|
96
|
+
{ type: 'tax', amount: tax },
|
|
97
|
+
{ type: 'total', amount: subtotal + tax },
|
|
98
|
+
],
|
|
99
|
+
links: [{ type: 'terms_of_service', url: `${base}/terms` }],
|
|
100
|
+
expires_at: checkout.expiresAt,
|
|
101
|
+
...(messages.length ? { messages } : {}),
|
|
102
|
+
...(checkout.buyer?.email ? { buyer: checkout.buyer } : {}),
|
|
103
|
+
...(checkout.order ? { order: checkout.order } : {}),
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
const linesOf = (body) => {
|
|
107
|
+
const lines = [];
|
|
108
|
+
for (const line of body.line_items ?? []) {
|
|
109
|
+
const id = line?.item?.id;
|
|
110
|
+
if (!(id in EXAMPLE_STORE_CATALOG)) {
|
|
111
|
+
return `No product ${id}`;
|
|
112
|
+
}
|
|
113
|
+
lines.push({ id, quantity: Number(line.quantity ?? 1) });
|
|
114
|
+
}
|
|
115
|
+
return lines;
|
|
116
|
+
};
|
|
117
|
+
const handle = (method, path, body) => {
|
|
118
|
+
if (method === 'POST' && path === '/checkout-sessions') {
|
|
119
|
+
const lines = linesOf(body);
|
|
120
|
+
if (typeof lines === 'string') {
|
|
121
|
+
return { status: 404, body: { messages: [{ content: lines }] } };
|
|
122
|
+
}
|
|
123
|
+
const checkout = {
|
|
124
|
+
id: `chk_${crypto.randomUUID().slice(0, 12)}`,
|
|
125
|
+
status: 'incomplete',
|
|
126
|
+
lines,
|
|
127
|
+
buyer: body.buyer ?? {},
|
|
128
|
+
expiresAt: new Date(Date.now() + 60 * 60 * 1000).toISOString(),
|
|
129
|
+
};
|
|
130
|
+
checkouts.set(checkout.id, checkout);
|
|
131
|
+
return { status: 201, body: render(checkout) };
|
|
132
|
+
}
|
|
133
|
+
const [, , id, action] = path.split('/');
|
|
134
|
+
const checkout = checkouts.get(id);
|
|
135
|
+
if (!checkout) {
|
|
136
|
+
return { status: 404, body: { messages: [{ content: 'No checkout' }] } };
|
|
137
|
+
}
|
|
138
|
+
if (method === 'PUT' && !action) {
|
|
139
|
+
if (!['incomplete', 'ready_for_complete'].includes(checkout.status)) {
|
|
140
|
+
return { status: 409, body: render(checkout) };
|
|
141
|
+
}
|
|
142
|
+
if (body.buyer) {
|
|
143
|
+
checkout.buyer = body.buyer;
|
|
144
|
+
}
|
|
145
|
+
if (body.line_items) {
|
|
146
|
+
const lines = linesOf(body);
|
|
147
|
+
if (typeof lines === 'string') {
|
|
148
|
+
return { status: 404, body: { messages: [{ content: lines }] } };
|
|
149
|
+
}
|
|
150
|
+
checkout.lines = lines;
|
|
151
|
+
}
|
|
152
|
+
return { status: 200, body: render(checkout) };
|
|
153
|
+
}
|
|
154
|
+
if (method === 'POST' && action === 'complete') {
|
|
155
|
+
if (checkout.status !== 'ready_for_complete') {
|
|
156
|
+
return { status: 200, body: render(checkout) };
|
|
157
|
+
}
|
|
158
|
+
const [instrument] = body.payment?.instruments ?? [{}];
|
|
159
|
+
const token = String(instrument?.credential?.token ?? '');
|
|
160
|
+
if (instrument?.handler_id !== EXAMPLE_STORE_HANDLER_ID ||
|
|
161
|
+
!token.startsWith(TEST_TOKEN_PREFIX)) {
|
|
162
|
+
return {
|
|
163
|
+
status: 402,
|
|
164
|
+
body: {
|
|
165
|
+
ucp: { version: UCP_VERSION, status: 'error' },
|
|
166
|
+
messages: [
|
|
167
|
+
{
|
|
168
|
+
type: 'error',
|
|
169
|
+
code: 'payment_declined',
|
|
170
|
+
content: 'The payment was declined',
|
|
171
|
+
},
|
|
172
|
+
],
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
const order = {
|
|
177
|
+
id: `ord_${crypto.randomUUID().slice(0, 10)}`,
|
|
178
|
+
permalink_url: `${base}/orders/${checkout.id}`,
|
|
179
|
+
};
|
|
180
|
+
checkout.status = 'completed';
|
|
181
|
+
checkout.order = order;
|
|
182
|
+
orders.push({ order: order.id, checkout: checkout.id });
|
|
183
|
+
return { status: 200, body: render(checkout) };
|
|
184
|
+
}
|
|
185
|
+
if (method === 'POST' && action === 'cancel') {
|
|
186
|
+
if (checkout.status !== 'completed') {
|
|
187
|
+
checkout.status = 'canceled';
|
|
188
|
+
}
|
|
189
|
+
return { status: 200, body: render(checkout) };
|
|
190
|
+
}
|
|
191
|
+
if (method === 'GET' && !action) {
|
|
192
|
+
return { status: 200, body: render(checkout) };
|
|
193
|
+
}
|
|
194
|
+
return { status: 405, body: {} };
|
|
195
|
+
};
|
|
196
|
+
const fetchImpl = (async (input, init) => {
|
|
197
|
+
const url = new URL(String(input));
|
|
198
|
+
if (url.pathname === '/.well-known/ucp') {
|
|
199
|
+
return json({
|
|
200
|
+
ucp: {
|
|
201
|
+
version: UCP_VERSION,
|
|
202
|
+
services: {
|
|
203
|
+
[SHOPPING_SERVICE]: [
|
|
204
|
+
{
|
|
205
|
+
version: UCP_VERSION,
|
|
206
|
+
transport: 'rest',
|
|
207
|
+
endpoint: `${base}/ucp/v1`,
|
|
208
|
+
},
|
|
209
|
+
],
|
|
210
|
+
},
|
|
211
|
+
capabilities: { [CHECKOUT_CAPABILITY]: [{ version: UCP_VERSION }] },
|
|
212
|
+
payment_handlers: meta().payment_handlers,
|
|
213
|
+
},
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
const headers = new Headers(init?.headers);
|
|
217
|
+
const agent = headers.get('UCP-Agent') ?? '';
|
|
218
|
+
if (!/^profile="https:\/\/[^"]+"$/.test(agent)) {
|
|
219
|
+
return refuse(400, 'invalid_ucp_agent', 'UCP-Agent names its profile over https');
|
|
220
|
+
}
|
|
221
|
+
if (!headers.get('Request-Id')) {
|
|
222
|
+
return refuse(400, 'missing_request_id', 'Request-Id is required');
|
|
223
|
+
}
|
|
224
|
+
const method = (init?.method ?? 'GET').toUpperCase();
|
|
225
|
+
const path = url.pathname.replace(/^\/ucp\/v1/, '');
|
|
226
|
+
const raw = typeof init?.body === 'string' ? init.body : '';
|
|
227
|
+
const body = raw ? JSON.parse(raw) : {};
|
|
228
|
+
if (path === '/catalog/search') {
|
|
229
|
+
const query = String(body.query ?? '').toLowerCase();
|
|
230
|
+
return json({
|
|
231
|
+
ucp: { version: UCP_VERSION },
|
|
232
|
+
products: Object.entries(EXAMPLE_STORE_CATALOG)
|
|
233
|
+
.filter(([, product]) => product.title.toLowerCase().includes(query))
|
|
234
|
+
.map(([id, product]) => ({ id, title: product.title })),
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
if (method === 'GET') {
|
|
238
|
+
const answer = handle(method, path, body);
|
|
239
|
+
return json(answer.body, answer.status);
|
|
240
|
+
}
|
|
241
|
+
const key = headers.get('Idempotency-Key');
|
|
242
|
+
if (!key) {
|
|
243
|
+
return refuse(400, 'missing_idempotency_key', 'Idempotency-Key is required');
|
|
244
|
+
}
|
|
245
|
+
const seen = await fingerprint(url.pathname, raw);
|
|
246
|
+
const replied = replies.get(key);
|
|
247
|
+
if (replied) {
|
|
248
|
+
return replied.seen === seen
|
|
249
|
+
? json(replied.body, replied.status)
|
|
250
|
+
: refuse(409, 'idempotency_conflict', 'the key was used for another request');
|
|
251
|
+
}
|
|
252
|
+
const answer = handle(method, path, body);
|
|
253
|
+
replies.set(key, { seen, ...answer });
|
|
254
|
+
return json(answer.body, answer.status);
|
|
255
|
+
});
|
|
256
|
+
return { fetch: fetchImpl, orders };
|
|
257
|
+
}
|
|
@@ -324,6 +324,7 @@ export const WebBotAuthPlugin = definePlugin({
|
|
|
324
324
|
status: 'implemented',
|
|
325
325
|
specification: 'https://datatracker.ietf.org/doc/draft-ietf-webbotauth-httpsig-protocol/',
|
|
326
326
|
plugin: WEB_BOT_AUTH_PLUGIN,
|
|
327
|
+
catalogue: 'web-bot-auth',
|
|
327
328
|
points: WEB_BOT_AUTH_POINTS.map(point => point.id),
|
|
328
329
|
}, { id: 'web_bot_auth', order: DEFAULT_ORDER }),
|
|
329
330
|
contribution(WebBotAuthDirectoryDiscoveries, directoryDiscovery(), {
|
package/lib/specs/apps.js
CHANGED
|
@@ -69,6 +69,7 @@ export const ACCOUNTING_APP_0_0_1 = {
|
|
|
69
69
|
],
|
|
70
70
|
commands: [],
|
|
71
71
|
modes: [],
|
|
72
|
+
actions: [],
|
|
72
73
|
profiles: [],
|
|
73
74
|
language: 'en',
|
|
74
75
|
translations: {},
|
|
@@ -224,6 +225,7 @@ export const CHANGE_DETECTION_APP_0_0_1 = {
|
|
|
224
225
|
],
|
|
225
226
|
commands: [],
|
|
226
227
|
modes: [],
|
|
228
|
+
actions: [],
|
|
227
229
|
profiles: [],
|
|
228
230
|
language: 'en',
|
|
229
231
|
translations: {},
|
|
@@ -386,6 +388,7 @@ export const CROP_MONITORING_APP_0_0_1 = {
|
|
|
386
388
|
],
|
|
387
389
|
commands: [],
|
|
388
390
|
modes: [],
|
|
391
|
+
actions: [],
|
|
389
392
|
profiles: [],
|
|
390
393
|
language: 'en',
|
|
391
394
|
translations: {},
|
|
@@ -528,6 +531,36 @@ export const CUSTOMER_INTERVIEW_APP_0_0_1 = {
|
|
|
528
531
|
],
|
|
529
532
|
commands: [],
|
|
530
533
|
modes: [],
|
|
534
|
+
actions: [
|
|
535
|
+
{
|
|
536
|
+
name: 'save',
|
|
537
|
+
description: 'Save an insight, with the words it cites.',
|
|
538
|
+
payload: {
|
|
539
|
+
description: "An insight, in the interviewer's words, and the interviewee's own that it cites.",
|
|
540
|
+
properties: {
|
|
541
|
+
insight: {
|
|
542
|
+
description: 'What was learned',
|
|
543
|
+
minLength: 1,
|
|
544
|
+
title: 'Insight',
|
|
545
|
+
type: 'string',
|
|
546
|
+
},
|
|
547
|
+
quote: {
|
|
548
|
+
description: "The interviewee's words it cites",
|
|
549
|
+
minLength: 1,
|
|
550
|
+
title: 'Quote',
|
|
551
|
+
type: 'string',
|
|
552
|
+
},
|
|
553
|
+
},
|
|
554
|
+
required: ['insight', 'quote'],
|
|
555
|
+
title: 'Insight',
|
|
556
|
+
type: 'object',
|
|
557
|
+
},
|
|
558
|
+
},
|
|
559
|
+
{
|
|
560
|
+
name: 'finish',
|
|
561
|
+
description: 'End the interview, and record its result.',
|
|
562
|
+
},
|
|
563
|
+
],
|
|
531
564
|
profiles: [],
|
|
532
565
|
settings: {
|
|
533
566
|
type: 'object',
|
|
@@ -723,6 +756,7 @@ export const DATA_QUALITY_APP_0_0_1 = {
|
|
|
723
756
|
starters: [],
|
|
724
757
|
commands: [],
|
|
725
758
|
modes: [],
|
|
759
|
+
actions: [],
|
|
726
760
|
profiles: [],
|
|
727
761
|
language: 'en',
|
|
728
762
|
translations: {},
|
|
@@ -935,6 +969,7 @@ export const DECIDE_APP_0_0_1 = {
|
|
|
935
969
|
],
|
|
936
970
|
commands: [],
|
|
937
971
|
modes: [],
|
|
972
|
+
actions: [],
|
|
938
973
|
profiles: [],
|
|
939
974
|
language: 'en',
|
|
940
975
|
translations: {},
|
|
@@ -1077,6 +1112,7 @@ export const DISASTER_ASSESSMENT_APP_0_0_1 = {
|
|
|
1077
1112
|
],
|
|
1078
1113
|
commands: [],
|
|
1079
1114
|
modes: [],
|
|
1115
|
+
actions: [],
|
|
1080
1116
|
profiles: [],
|
|
1081
1117
|
language: 'en',
|
|
1082
1118
|
translations: {},
|
|
@@ -1221,6 +1257,7 @@ export const EVENT_RESPONSE_APP_0_0_1 = {
|
|
|
1221
1257
|
],
|
|
1222
1258
|
commands: [],
|
|
1223
1259
|
modes: [],
|
|
1260
|
+
actions: [],
|
|
1224
1261
|
profiles: [],
|
|
1225
1262
|
language: 'en',
|
|
1226
1263
|
translations: {},
|
|
@@ -1388,6 +1425,7 @@ export const EXCHANGE_DESK_APP_0_0_1 = {
|
|
|
1388
1425
|
starters: [],
|
|
1389
1426
|
commands: [],
|
|
1390
1427
|
modes: [],
|
|
1428
|
+
actions: [],
|
|
1391
1429
|
profiles: [],
|
|
1392
1430
|
language: 'en',
|
|
1393
1431
|
translations: {},
|
|
@@ -1549,6 +1587,7 @@ export const INBOX_TRIAGE_APP_0_0_1 = {
|
|
|
1549
1587
|
],
|
|
1550
1588
|
commands: [],
|
|
1551
1589
|
modes: [],
|
|
1590
|
+
actions: [],
|
|
1552
1591
|
profiles: [],
|
|
1553
1592
|
language: 'en',
|
|
1554
1593
|
translations: {},
|
|
@@ -1695,6 +1734,7 @@ export const MODEL_CHOICE_APP_0_0_1 = {
|
|
|
1695
1734
|
starters: [],
|
|
1696
1735
|
commands: [],
|
|
1697
1736
|
modes: [],
|
|
1737
|
+
actions: [],
|
|
1698
1738
|
profiles: [],
|
|
1699
1739
|
language: 'en',
|
|
1700
1740
|
translations: {},
|
|
@@ -1974,6 +2014,7 @@ export const MONTH_END_CLOSE_APP_0_0_1 = {
|
|
|
1974
2014
|
],
|
|
1975
2015
|
commands: [],
|
|
1976
2016
|
modes: [],
|
|
2017
|
+
actions: [],
|
|
1977
2018
|
profiles: [],
|
|
1978
2019
|
language: 'en',
|
|
1979
2020
|
translations: {},
|
|
@@ -2150,6 +2191,7 @@ export const ORDER_DESK_APP_0_0_1 = {
|
|
|
2150
2191
|
],
|
|
2151
2192
|
commands: [],
|
|
2152
2193
|
modes: [],
|
|
2194
|
+
actions: [],
|
|
2153
2195
|
profiles: [],
|
|
2154
2196
|
language: 'en',
|
|
2155
2197
|
translations: {},
|
|
@@ -2187,7 +2229,7 @@ export const ORDER_DESK_APP_0_0_1 = {
|
|
|
2187
2229
|
"The journey it takes is the Personal Agent Protocol SDK's demonstration with Manzanita Outfitters, run in the SDK's own tests (personal-agent-protocol 0.10.0).",
|
|
2188
2230
|
],
|
|
2189
2231
|
unverified: [
|
|
2190
|
-
|
|
2232
|
+
'No company answers on Datalayer yet: no test company is served on r1, so it has not run in the Studio against one.',
|
|
2191
2233
|
],
|
|
2192
2234
|
},
|
|
2193
2235
|
},
|
|
@@ -2287,6 +2329,7 @@ export const PIPELINE_REPORT_APP_0_0_1 = {
|
|
|
2287
2329
|
],
|
|
2288
2330
|
commands: [],
|
|
2289
2331
|
modes: [],
|
|
2332
|
+
actions: [],
|
|
2290
2333
|
profiles: [],
|
|
2291
2334
|
language: 'en',
|
|
2292
2335
|
translations: {},
|
|
@@ -2558,6 +2601,7 @@ export const QUOTE_CALCULATOR_APP_0_0_1 = {
|
|
|
2558
2601
|
starters: [],
|
|
2559
2602
|
commands: [],
|
|
2560
2603
|
modes: [],
|
|
2604
|
+
actions: [],
|
|
2561
2605
|
profiles: [],
|
|
2562
2606
|
settings: {
|
|
2563
2607
|
type: 'object',
|
|
@@ -2836,6 +2880,7 @@ export const REPORT_FROM_A_FILE_APP_0_0_1 = {
|
|
|
2836
2880
|
starters: [],
|
|
2837
2881
|
commands: [],
|
|
2838
2882
|
modes: [],
|
|
2883
|
+
actions: [],
|
|
2839
2884
|
profiles: [],
|
|
2840
2885
|
settings: {
|
|
2841
2886
|
type: 'object',
|
|
@@ -3123,6 +3168,7 @@ export const SALES_APP_0_0_1 = {
|
|
|
3123
3168
|
],
|
|
3124
3169
|
commands: [],
|
|
3125
3170
|
modes: [],
|
|
3171
|
+
actions: [],
|
|
3126
3172
|
profiles: [],
|
|
3127
3173
|
language: 'en',
|
|
3128
3174
|
translations: {},
|
|
@@ -3241,6 +3287,7 @@ export const SHIP_OR_FIX_APP_0_0_1 = {
|
|
|
3241
3287
|
starters: [],
|
|
3242
3288
|
commands: [],
|
|
3243
3289
|
modes: [],
|
|
3290
|
+
actions: [],
|
|
3244
3291
|
profiles: [],
|
|
3245
3292
|
language: 'en',
|
|
3246
3293
|
translations: {},
|
|
@@ -3458,6 +3505,7 @@ export const SUPPLIER_COMPARISON_APP_0_0_1 = {
|
|
|
3458
3505
|
starters: [],
|
|
3459
3506
|
commands: [],
|
|
3460
3507
|
modes: [],
|
|
3508
|
+
actions: [],
|
|
3461
3509
|
profiles: [],
|
|
3462
3510
|
language: 'en',
|
|
3463
3511
|
translations: {},
|
|
@@ -3678,6 +3726,7 @@ export const SUPPORT_DESK_APP_0_0_1 = {
|
|
|
3678
3726
|
],
|
|
3679
3727
|
commands: [],
|
|
3680
3728
|
modes: [],
|
|
3729
|
+
actions: [],
|
|
3681
3730
|
profiles: [],
|
|
3682
3731
|
settings: {
|
|
3683
3732
|
type: 'object',
|
|
@@ -3889,7 +3938,7 @@ export const SUPPORT_DESK_APP_0_0_1 = {
|
|
|
3889
3938
|
recorded: [],
|
|
3890
3939
|
unverified: [
|
|
3891
3940
|
'No conversation has run: its agent was switched on in the catalogue on 2026-10-06 and has not answered yet.',
|
|
3892
|
-
"Its two documents are Datalayer's
|
|
3941
|
+
"Its two documents are Datalayer's own examples, for a made-up product: a builder gives their own on What it knows.",
|
|
3893
3942
|
'Its tests have not been run.',
|
|
3894
3943
|
],
|
|
3895
3944
|
},
|
|
@@ -4011,6 +4060,7 @@ export const TRAVEL_DESK_APP_0_0_1 = {
|
|
|
4011
4060
|
],
|
|
4012
4061
|
commands: [],
|
|
4013
4062
|
modes: [],
|
|
4063
|
+
actions: [],
|
|
4014
4064
|
profiles: [],
|
|
4015
4065
|
language: 'en',
|
|
4016
4066
|
translations: {},
|
|
@@ -4045,7 +4095,7 @@ export const TRAVEL_DESK_APP_0_0_1 = {
|
|
|
4045
4095
|
verified: {
|
|
4046
4096
|
live: [],
|
|
4047
4097
|
recorded: [
|
|
4048
|
-
"The journey is
|
|
4098
|
+
"The journey is the developers' PACT example (examples/protocols/pact/personal_agent.py) against its local Provider, Example Air, run in its own tests (version 1.3.112).",
|
|
4049
4099
|
],
|
|
4050
4100
|
unverified: [
|
|
4051
4101
|
"No airline answers PACT on Datalayer yet: the gateway's pact toolset is built, not deployed.",
|
|
@@ -4143,6 +4193,7 @@ export const WEB_RESEARCH_APP_0_0_1 = {
|
|
|
4143
4193
|
],
|
|
4144
4194
|
commands: [],
|
|
4145
4195
|
modes: [],
|
|
4196
|
+
actions: [],
|
|
4146
4197
|
profiles: [],
|
|
4147
4198
|
settings: {
|
|
4148
4199
|
type: 'object',
|
|
@@ -4584,6 +4635,36 @@ export const APP_SOURCES = {
|
|
|
4584
4635
|
message: 'Interview me about my first week with the product.',
|
|
4585
4636
|
},
|
|
4586
4637
|
],
|
|
4638
|
+
actions: [
|
|
4639
|
+
{
|
|
4640
|
+
name: 'save',
|
|
4641
|
+
description: 'Save an insight, with the words it cites.',
|
|
4642
|
+
payload: {
|
|
4643
|
+
description: "An insight, in the interviewer's words, and the interviewee's own that it cites.",
|
|
4644
|
+
properties: {
|
|
4645
|
+
insight: {
|
|
4646
|
+
description: 'What was learned',
|
|
4647
|
+
minLength: 1,
|
|
4648
|
+
title: 'Insight',
|
|
4649
|
+
type: 'string',
|
|
4650
|
+
},
|
|
4651
|
+
quote: {
|
|
4652
|
+
description: "The interviewee's words it cites",
|
|
4653
|
+
minLength: 1,
|
|
4654
|
+
title: 'Quote',
|
|
4655
|
+
type: 'string',
|
|
4656
|
+
},
|
|
4657
|
+
},
|
|
4658
|
+
required: ['insight', 'quote'],
|
|
4659
|
+
title: 'Insight',
|
|
4660
|
+
type: 'object',
|
|
4661
|
+
},
|
|
4662
|
+
},
|
|
4663
|
+
{
|
|
4664
|
+
name: 'finish',
|
|
4665
|
+
description: 'End the interview, and record its result.',
|
|
4666
|
+
},
|
|
4667
|
+
],
|
|
4587
4668
|
settings: {
|
|
4588
4669
|
type: 'object',
|
|
4589
4670
|
properties: {
|
|
@@ -5606,7 +5687,7 @@ export const APP_SOURCES = {
|
|
|
5606
5687
|
"The journey it takes is the Personal Agent Protocol SDK's demonstration with Manzanita Outfitters, run in the SDK's own tests (personal-agent-protocol 0.10.0).",
|
|
5607
5688
|
],
|
|
5608
5689
|
unverified: [
|
|
5609
|
-
|
|
5690
|
+
'No company answers on Datalayer yet: no test company is served on r1, so it has not run in the Studio against one.',
|
|
5610
5691
|
],
|
|
5611
5692
|
},
|
|
5612
5693
|
},
|
|
@@ -6831,7 +6912,7 @@ export const APP_SOURCES = {
|
|
|
6831
6912
|
verified: {
|
|
6832
6913
|
unverified: [
|
|
6833
6914
|
'No conversation has run: its agent was switched on in the catalogue on 2026-10-06 and has not answered yet.',
|
|
6834
|
-
"Its two documents are Datalayer's
|
|
6915
|
+
"Its two documents are Datalayer's own examples, for a made-up product: a builder gives their own on What it knows.",
|
|
6835
6916
|
'Its tests have not been run.',
|
|
6836
6917
|
],
|
|
6837
6918
|
},
|
|
@@ -6927,7 +7008,7 @@ export const APP_SOURCES = {
|
|
|
6927
7008
|
],
|
|
6928
7009
|
verified: {
|
|
6929
7010
|
recorded: [
|
|
6930
|
-
"The journey is
|
|
7011
|
+
"The journey is the developers' PACT example (examples/protocols/pact/personal_agent.py) against its local Provider, Example Air, run in its own tests (version 1.3.112).",
|
|
6931
7012
|
],
|
|
6932
7013
|
unverified: [
|
|
6933
7014
|
"No airline answers PACT on Datalayer yet: the gateway's pact toolset is built, not deployed.",
|
|
@@ -76,6 +76,41 @@ export const APPSPEC_SCHEMA = {
|
|
|
76
76
|
title: 'AppA2AExtension',
|
|
77
77
|
type: 'object',
|
|
78
78
|
},
|
|
79
|
+
AppAction: {
|
|
80
|
+
additionalProperties: false,
|
|
81
|
+
description: 'An action of its code a person presses (`@app.action`, REACTOR_UI RU-5).\n\nWhat its payload is, typed: the JSON Schema of an object, written from the\npydantic model its code declares (`@app.action(name, payload=Model)`); an\naction declaring none takes nothing. The runtime offers it only where a\ndisplay showed it, or to the session that runs it, each press with a\ntoken; a press of an action not declared here is refused, and its payload\nis checked against this schema before its code runs.',
|
|
82
|
+
properties: {
|
|
83
|
+
name: {
|
|
84
|
+
description: 'Its name, as its button presses it',
|
|
85
|
+
pattern: '^[A-Za-z_][A-Za-z0-9_]*$',
|
|
86
|
+
title: 'Name',
|
|
87
|
+
type: 'string',
|
|
88
|
+
},
|
|
89
|
+
description: {
|
|
90
|
+
default: '',
|
|
91
|
+
description: 'What it does, in a sentence',
|
|
92
|
+
title: 'Description',
|
|
93
|
+
type: 'string',
|
|
94
|
+
},
|
|
95
|
+
payload: {
|
|
96
|
+
anyOf: [
|
|
97
|
+
{
|
|
98
|
+
additionalProperties: true,
|
|
99
|
+
type: 'object',
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
type: 'null',
|
|
103
|
+
},
|
|
104
|
+
],
|
|
105
|
+
default: null,
|
|
106
|
+
description: 'The JSON Schema of what it is pressed with, an object; none when it takes nothing (a press with anything is then refused)',
|
|
107
|
+
title: 'Payload',
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
required: ['name'],
|
|
111
|
+
title: 'AppAction',
|
|
112
|
+
type: 'object',
|
|
113
|
+
},
|
|
79
114
|
AppChecks: {
|
|
80
115
|
additionalProperties: false,
|
|
81
116
|
description: "Optional: checks from the catalogue, for a builder who wants them — and its code's own.",
|
|
@@ -536,6 +571,14 @@ export const APPSPEC_SCHEMA = {
|
|
|
536
571
|
title: 'Modes',
|
|
537
572
|
type: 'array',
|
|
538
573
|
},
|
|
574
|
+
actions: {
|
|
575
|
+
description: 'The actions of its code a person presses (`@app.action`, REACTOR_UI RU-5), each with the JSON Schema of its payload: what its buttons offer, with a token, and nothing else',
|
|
576
|
+
items: {
|
|
577
|
+
$ref: '#/$defs/AppAction',
|
|
578
|
+
},
|
|
579
|
+
title: 'Actions',
|
|
580
|
+
type: 'array',
|
|
581
|
+
},
|
|
539
582
|
profiles: {
|
|
540
583
|
description: 'Several assistants in one application, two at least: the person picks one before the conversation starts — the first unless they do — and keeps it to the end; its instructions, model and starters go with every run (LOOP P-20). None when unsaid',
|
|
541
584
|
items: {
|