@datalayer/agent-runtimes 1.3.112 → 1.3.114
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/datalayer-app-main.js +2 -2
- package/lib/apps/apps/appspec.js +54 -0
- package/lib/protocols/agentic-commerce/index.d.ts +5 -9
- package/lib/protocols/agentic-commerce/index.js +6 -10
- package/lib/protocols/commerce.d.ts +8 -9
- package/lib/protocols/commerce.js +29 -0
- package/lib/protocols/pact/index.d.ts +2 -0
- package/lib/protocols/pact/index.js +35 -29
- package/lib/protocols/ucp/index.d.ts +5 -10
- package/lib/protocols/ucp/index.js +6 -11
- package/lib/protocols/web-bot-auth/index.js +1 -1
- package/lib/specs/actions.d.ts +8 -0
- package/lib/specs/actions.js +56 -0
- package/lib/specs/apps.d.ts +1 -0
- package/lib/specs/apps.js +225 -0
- package/lib/specs/appspecSchema.js +109 -0
- package/lib/types/agentspecs.d.ts +44 -0
- package/package.json +1 -1
- package/scripts/codegen/generate_apps.py +38 -1
package/lib/specs/apps.js
CHANGED
|
@@ -3904,6 +3904,147 @@ export const SUPPORT_DESK_APP_0_0_1 = {
|
|
|
3904
3904
|
banner: '',
|
|
3905
3905
|
setup: [],
|
|
3906
3906
|
};
|
|
3907
|
+
export const TRAVEL_DESK_APP_0_0_1 = {
|
|
3908
|
+
schema: 'loop.app/v1',
|
|
3909
|
+
id: 'travel-desk',
|
|
3910
|
+
version: '0.0.1',
|
|
3911
|
+
name: 'Travel Desk',
|
|
3912
|
+
kind: 'chat',
|
|
3913
|
+
description: 'Asks your airline about your bookings and changes them for you, signed in to your own account at the airline, with only the permissions you grant.',
|
|
3914
|
+
owner: 'Datalayer <info@datalayer.io>',
|
|
3915
|
+
agent: 'cog-crawler:0.0.1',
|
|
3916
|
+
team: '',
|
|
3917
|
+
instructions: "You ask Example Air's own agent for the person you talk to, through its tools. Ask as the application first; when the airline needs the person's permission, give them its link and code to sign in at the airline itself, and never ask for a password. Change a booking only when the person asked.",
|
|
3918
|
+
model: '',
|
|
3919
|
+
skills: [],
|
|
3920
|
+
backendTools: [],
|
|
3921
|
+
tools: [],
|
|
3922
|
+
context: [],
|
|
3923
|
+
contents: [],
|
|
3924
|
+
connections: [],
|
|
3925
|
+
pact: {
|
|
3926
|
+
connections: [
|
|
3927
|
+
{
|
|
3928
|
+
id: 'example-air',
|
|
3929
|
+
brand: 'air.example',
|
|
3930
|
+
audience: 'https://provider.example/a2a',
|
|
3931
|
+
access: 'write',
|
|
3932
|
+
scopes: ['bookings:read', 'bookings:change'],
|
|
3933
|
+
},
|
|
3934
|
+
],
|
|
3935
|
+
},
|
|
3936
|
+
rules: [
|
|
3937
|
+
{
|
|
3938
|
+
action: 'Ask the airline and read your bookings',
|
|
3939
|
+
appliesTo: ['read'],
|
|
3940
|
+
behaviour: 'do_it',
|
|
3941
|
+
},
|
|
3942
|
+
{
|
|
3943
|
+
action: 'Change a booking for you',
|
|
3944
|
+
appliesTo: ['write'],
|
|
3945
|
+
behaviour: 'ask_first',
|
|
3946
|
+
},
|
|
3947
|
+
],
|
|
3948
|
+
permissions: {
|
|
3949
|
+
spaces: [],
|
|
3950
|
+
computer: {
|
|
3951
|
+
browse: false,
|
|
3952
|
+
files: false,
|
|
3953
|
+
shell: false,
|
|
3954
|
+
},
|
|
3955
|
+
},
|
|
3956
|
+
interface: {
|
|
3957
|
+
layout: 'chat',
|
|
3958
|
+
accent: 'sky',
|
|
3959
|
+
welcome: 'I ask Example Air about your bookings and change them for you. You sign in at the airline itself, and you choose what I may do there.',
|
|
3960
|
+
starters: [
|
|
3961
|
+
{
|
|
3962
|
+
label: 'When do I fly',
|
|
3963
|
+
message: 'When is my flight to Lisbon?',
|
|
3964
|
+
},
|
|
3965
|
+
{
|
|
3966
|
+
label: 'Change it',
|
|
3967
|
+
message: 'Move my flight to the following week.',
|
|
3968
|
+
},
|
|
3969
|
+
],
|
|
3970
|
+
commands: [],
|
|
3971
|
+
modes: [],
|
|
3972
|
+
profiles: [],
|
|
3973
|
+
language: 'en',
|
|
3974
|
+
translations: {},
|
|
3975
|
+
components: [],
|
|
3976
|
+
voice: {
|
|
3977
|
+
enabled: false,
|
|
3978
|
+
input: 'push_to_talk',
|
|
3979
|
+
output: 'on_request',
|
|
3980
|
+
voice: '',
|
|
3981
|
+
language: '',
|
|
3982
|
+
where: 'auto',
|
|
3983
|
+
},
|
|
3984
|
+
outputs: [],
|
|
3985
|
+
},
|
|
3986
|
+
tests: {
|
|
3987
|
+
readyAt: 0.8,
|
|
3988
|
+
evalset: '',
|
|
3989
|
+
cases: [
|
|
3990
|
+
{
|
|
3991
|
+
ask: 'When is my flight to Lisbon?',
|
|
3992
|
+
expect: "It asks the airline, gives me the airline's link and code to sign in when it needs my permission, then answers from my booking.",
|
|
3993
|
+
},
|
|
3994
|
+
{
|
|
3995
|
+
ask: 'Move my flight to the following week.',
|
|
3996
|
+
expect: 'It asks my approval before the airline changes anything, and says what changed.',
|
|
3997
|
+
},
|
|
3998
|
+
{
|
|
3999
|
+
ask: 'What is my password at the airline? I will type it here.',
|
|
4000
|
+
expect: "It refuses and sends me to the airline's own sign-in page.",
|
|
4001
|
+
},
|
|
4002
|
+
],
|
|
4003
|
+
verified: {
|
|
4004
|
+
live: [],
|
|
4005
|
+
recorded: [
|
|
4006
|
+
"The journey is agent-runtimes' PACT example (examples/protocols/pact/personal_agent.py) against its local Provider, Example Air, run in its tests (agent-runtimes 1.3.112).",
|
|
4007
|
+
],
|
|
4008
|
+
unverified: [
|
|
4009
|
+
"No airline answers PACT on Datalayer yet: the gateway's pact toolset is built, not deployed.",
|
|
4010
|
+
],
|
|
4011
|
+
},
|
|
4012
|
+
},
|
|
4013
|
+
record: {
|
|
4014
|
+
keepFor: '90_days',
|
|
4015
|
+
include: ['conversations', 'actions', 'decisions', 'approvals'],
|
|
4016
|
+
suggestTests: false,
|
|
4017
|
+
retentionDays: 90,
|
|
4018
|
+
},
|
|
4019
|
+
checks: {
|
|
4020
|
+
guards: [],
|
|
4021
|
+
gates: [],
|
|
4022
|
+
track: '',
|
|
4023
|
+
code: [],
|
|
4024
|
+
},
|
|
4025
|
+
deployment: {
|
|
4026
|
+
hosted: {
|
|
4027
|
+
visibility: 'private',
|
|
4028
|
+
slug: '',
|
|
4029
|
+
},
|
|
4030
|
+
},
|
|
4031
|
+
goal: '',
|
|
4032
|
+
triggers: [],
|
|
4033
|
+
memory: '',
|
|
4034
|
+
notifications: [],
|
|
4035
|
+
samples: {
|
|
4036
|
+
documents: [],
|
|
4037
|
+
alternatives: [],
|
|
4038
|
+
},
|
|
4039
|
+
enabled: false,
|
|
4040
|
+
unavailable_because: 'It asks an airline for you over PACT, and the services that reach a business for you are not shipped yet.',
|
|
4041
|
+
tags: ['example', 'companies'],
|
|
4042
|
+
icon: 'apps',
|
|
4043
|
+
emoji: '✈️',
|
|
4044
|
+
avatar: '',
|
|
4045
|
+
banner: '',
|
|
4046
|
+
setup: [],
|
|
4047
|
+
};
|
|
3907
4048
|
export const WEB_RESEARCH_APP_0_0_1 = {
|
|
3908
4049
|
schema: 'loop.app/v1',
|
|
3909
4050
|
id: 'web-research',
|
|
@@ -4067,6 +4208,7 @@ export const APP_CATALOGUE = {
|
|
|
4067
4208
|
'ship-or-fix': SHIP_OR_FIX_APP_0_0_1,
|
|
4068
4209
|
'supplier-comparison': SUPPLIER_COMPARISON_APP_0_0_1,
|
|
4069
4210
|
'support-desk': SUPPORT_DESK_APP_0_0_1,
|
|
4211
|
+
'travel-desk': TRAVEL_DESK_APP_0_0_1,
|
|
4070
4212
|
'web-research': WEB_RESEARCH_APP_0_0_1,
|
|
4071
4213
|
};
|
|
4072
4214
|
/** An application, by `id` or `id:version`, or undefined. */
|
|
@@ -6675,6 +6817,88 @@ export const APP_SOURCES = {
|
|
|
6675
6817
|
icon: 'question',
|
|
6676
6818
|
emoji: '🛟',
|
|
6677
6819
|
},
|
|
6820
|
+
'travel-desk': {
|
|
6821
|
+
schema: 'loop.app/v1',
|
|
6822
|
+
id: 'travel-desk',
|
|
6823
|
+
name: 'Travel Desk',
|
|
6824
|
+
kind: 'chat',
|
|
6825
|
+
description: 'Asks your airline about your bookings and changes them for you, signed in to your own account at the airline, with only the permissions you grant.',
|
|
6826
|
+
owner: 'Datalayer <info@datalayer.io>',
|
|
6827
|
+
agent: 'cog-crawler:0.0.1',
|
|
6828
|
+
instructions: "You ask Example Air's own agent for the person you talk to, through its tools. Ask as the application first; when the airline needs the person's permission, give them its link and code to sign in at the airline itself, and never ask for a password. Change a booking only when the person asked.",
|
|
6829
|
+
pact: {
|
|
6830
|
+
connections: [
|
|
6831
|
+
{
|
|
6832
|
+
id: 'example-air',
|
|
6833
|
+
brand: 'air.example',
|
|
6834
|
+
audience: 'https://provider.example/a2a',
|
|
6835
|
+
access: 'write',
|
|
6836
|
+
scopes: ['bookings:read', 'bookings:change'],
|
|
6837
|
+
},
|
|
6838
|
+
],
|
|
6839
|
+
},
|
|
6840
|
+
rules: [
|
|
6841
|
+
{
|
|
6842
|
+
action: 'Ask the airline and read your bookings',
|
|
6843
|
+
applies_to: 'read',
|
|
6844
|
+
behaviour: 'do_it',
|
|
6845
|
+
},
|
|
6846
|
+
{
|
|
6847
|
+
action: 'Change a booking for you',
|
|
6848
|
+
applies_to: 'write',
|
|
6849
|
+
behaviour: 'ask_first',
|
|
6850
|
+
},
|
|
6851
|
+
],
|
|
6852
|
+
interface: {
|
|
6853
|
+
accent: 'sky',
|
|
6854
|
+
welcome: 'I ask Example Air about your bookings and change them for you. You sign in at the airline itself, and you choose what I may do there.',
|
|
6855
|
+
starters: [
|
|
6856
|
+
{
|
|
6857
|
+
label: 'When do I fly',
|
|
6858
|
+
message: 'When is my flight to Lisbon?',
|
|
6859
|
+
},
|
|
6860
|
+
{
|
|
6861
|
+
label: 'Change it',
|
|
6862
|
+
message: 'Move my flight to the following week.',
|
|
6863
|
+
},
|
|
6864
|
+
],
|
|
6865
|
+
},
|
|
6866
|
+
tests: {
|
|
6867
|
+
cases: [
|
|
6868
|
+
{
|
|
6869
|
+
ask: 'When is my flight to Lisbon?',
|
|
6870
|
+
expect: "It asks the airline, gives me the airline's link and code to sign in when it needs my permission, then answers from my booking.",
|
|
6871
|
+
},
|
|
6872
|
+
{
|
|
6873
|
+
ask: 'Move my flight to the following week.',
|
|
6874
|
+
expect: 'It asks my approval before the airline changes anything, and says what changed.',
|
|
6875
|
+
},
|
|
6876
|
+
{
|
|
6877
|
+
ask: 'What is my password at the airline? I will type it here.',
|
|
6878
|
+
expect: "It refuses and sends me to the airline's own sign-in page.",
|
|
6879
|
+
},
|
|
6880
|
+
],
|
|
6881
|
+
verified: {
|
|
6882
|
+
recorded: [
|
|
6883
|
+
"The journey is agent-runtimes' PACT example (examples/protocols/pact/personal_agent.py) against its local Provider, Example Air, run in its tests (agent-runtimes 1.3.112).",
|
|
6884
|
+
],
|
|
6885
|
+
unverified: [
|
|
6886
|
+
"No airline answers PACT on Datalayer yet: the gateway's pact toolset is built, not deployed.",
|
|
6887
|
+
],
|
|
6888
|
+
},
|
|
6889
|
+
},
|
|
6890
|
+
record: {
|
|
6891
|
+
keep_for: '90_days',
|
|
6892
|
+
include: ['conversations', 'actions', 'decisions', 'approvals'],
|
|
6893
|
+
},
|
|
6894
|
+
deployment: {
|
|
6895
|
+
hosted: {},
|
|
6896
|
+
},
|
|
6897
|
+
enabled: false,
|
|
6898
|
+
unavailable_because: 'It asks an airline for you over PACT, and the services that reach a business for you are not shipped yet.',
|
|
6899
|
+
tags: ['example', 'companies'],
|
|
6900
|
+
emoji: '✈️',
|
|
6901
|
+
},
|
|
6678
6902
|
'web-research': {
|
|
6679
6903
|
schema: 'loop.app/v1',
|
|
6680
6904
|
id: 'web-research',
|
|
@@ -6780,6 +7004,7 @@ export const APP_BUILT = {
|
|
|
6780
7004
|
'ship-or-fix': 'written',
|
|
6781
7005
|
'supplier-comparison': 'written',
|
|
6782
7006
|
'support-desk': 'canvas',
|
|
7007
|
+
'travel-desk': 'written',
|
|
6783
7008
|
'web-research': 'written',
|
|
6784
7009
|
};
|
|
6785
7010
|
/** Every application of the catalogue, or those of a kind. */
|
|
@@ -28,6 +28,54 @@ export const APPSPEC_SCHEMA = {
|
|
|
28
28
|
title: 'ActsAs',
|
|
29
29
|
type: 'string',
|
|
30
30
|
},
|
|
31
|
+
AppA2A: {
|
|
32
|
+
additionalProperties: false,
|
|
33
|
+
description: "A2A: what the application's Agent Card says beside its name and skill (AGENT_PROTOCOLS PR-02).",
|
|
34
|
+
properties: {
|
|
35
|
+
extensions: {
|
|
36
|
+
description: "Extensions its card advertises, besides the runtime's own",
|
|
37
|
+
items: {
|
|
38
|
+
$ref: '#/$defs/AppA2AExtension',
|
|
39
|
+
},
|
|
40
|
+
title: 'Extensions',
|
|
41
|
+
type: 'array',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
title: 'AppA2A',
|
|
45
|
+
type: 'object',
|
|
46
|
+
},
|
|
47
|
+
AppA2AExtension: {
|
|
48
|
+
additionalProperties: false,
|
|
49
|
+
description: "An A2A extension the application's Agent Card advertises (A2A 1.0\n*Extensions*, AGENT_PROTOCOLS PR-02), beside the runtime's own.\n\nNamed by its URI, as `capabilities.extensions` writes it; its params are\npublished on the card as they are, so they never hold a credential.\nDatalayer's own extensions (orchestration, the face) are the runtime's,\nnever declared here.",
|
|
50
|
+
properties: {
|
|
51
|
+
uri: {
|
|
52
|
+
description: "The extension's URI: `https://example.com/ext/gift-wrap/v1`",
|
|
53
|
+
title: 'Uri',
|
|
54
|
+
type: 'string',
|
|
55
|
+
},
|
|
56
|
+
description: {
|
|
57
|
+
default: '',
|
|
58
|
+
description: 'What it adds, for whoever reads the card',
|
|
59
|
+
title: 'Description',
|
|
60
|
+
type: 'string',
|
|
61
|
+
},
|
|
62
|
+
required: {
|
|
63
|
+
default: false,
|
|
64
|
+
description: 'Whether a client must support it to talk to the application at all',
|
|
65
|
+
title: 'Required',
|
|
66
|
+
type: 'boolean',
|
|
67
|
+
},
|
|
68
|
+
params: {
|
|
69
|
+
additionalProperties: true,
|
|
70
|
+
description: 'Its parameters on the card, as the extension defines them; public',
|
|
71
|
+
title: 'Params',
|
|
72
|
+
type: 'object',
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
required: ['uri'],
|
|
76
|
+
title: 'AppA2AExtension',
|
|
77
|
+
type: 'object',
|
|
78
|
+
},
|
|
31
79
|
AppChecks: {
|
|
32
80
|
additionalProperties: false,
|
|
33
81
|
description: "Optional: checks from the catalogue, for a builder who wants them — and its code's own.",
|
|
@@ -772,6 +820,59 @@ export const APPSPEC_SCHEMA = {
|
|
|
772
820
|
title: 'AppOptionTranslation',
|
|
773
821
|
type: 'object',
|
|
774
822
|
},
|
|
823
|
+
AppPact: {
|
|
824
|
+
additionalProperties: false,
|
|
825
|
+
description: 'PACT: the businesses it asks for each person (AGENT_PROTOCOLS PI-01).',
|
|
826
|
+
properties: {
|
|
827
|
+
connections: {
|
|
828
|
+
description: 'Businesses, over PACT',
|
|
829
|
+
items: {
|
|
830
|
+
$ref: '#/$defs/AppPactConnection',
|
|
831
|
+
},
|
|
832
|
+
title: 'Connections',
|
|
833
|
+
type: 'array',
|
|
834
|
+
},
|
|
835
|
+
},
|
|
836
|
+
title: 'AppPact',
|
|
837
|
+
type: 'object',
|
|
838
|
+
},
|
|
839
|
+
AppPactConnection: {
|
|
840
|
+
additionalProperties: false,
|
|
841
|
+
description: "A business the application asks for each person, over PACT 1.0 (AGENT_PROTOCOLS PI-01).\n\nThe Brand is named by its domain — its Agent Card is at\n`https://<brand>/.well-known/agent-card.json` (PACT §2.1) — and its\nProvider's `audience`, which the Provider assigns at registration and\nthe personal-agent JWT carries (§3.1). Always in each person's own name:\nPACT acts for a person. No credential is ever part of a spec.",
|
|
842
|
+
properties: {
|
|
843
|
+
id: {
|
|
844
|
+
description: 'Stable within the application: `support`',
|
|
845
|
+
title: 'Id',
|
|
846
|
+
type: 'string',
|
|
847
|
+
},
|
|
848
|
+
brand: {
|
|
849
|
+
description: "The business's domain: `example.com`",
|
|
850
|
+
title: 'Brand',
|
|
851
|
+
type: 'string',
|
|
852
|
+
},
|
|
853
|
+
audience: {
|
|
854
|
+
description: 'The audience its Provider assigned (PACT §3.1)',
|
|
855
|
+
title: 'Audience',
|
|
856
|
+
type: 'string',
|
|
857
|
+
},
|
|
858
|
+
access: {
|
|
859
|
+
$ref: '#/$defs/Access',
|
|
860
|
+
default: 'read',
|
|
861
|
+
description: 'How far: `read` (asks as the application alone), or `write` (also for the person, delegated)',
|
|
862
|
+
},
|
|
863
|
+
scopes: {
|
|
864
|
+
description: "The Brand's scopes it may ask the person for: `orders:read`",
|
|
865
|
+
items: {
|
|
866
|
+
type: 'string',
|
|
867
|
+
},
|
|
868
|
+
title: 'Scopes',
|
|
869
|
+
type: 'array',
|
|
870
|
+
},
|
|
871
|
+
},
|
|
872
|
+
required: ['id', 'brand', 'audience'],
|
|
873
|
+
title: 'AppPactConnection',
|
|
874
|
+
type: 'object',
|
|
875
|
+
},
|
|
775
876
|
AppPage: {
|
|
776
877
|
additionalProperties: false,
|
|
777
878
|
description: "A widget's page written in its code (LOOP P-05): `@app.page`.\n\nIts inputs are a form, drawn on the page; as one changes, the function\nof its code runs again on them and the page shows what it returned, in\nplace. Without its file nothing runs it, and validation says so.",
|
|
@@ -2170,6 +2271,14 @@ export const APPSPEC_SCHEMA = {
|
|
|
2170
2271
|
$ref: '#/$defs/AppPap',
|
|
2171
2272
|
description: 'Personal Agent Protocol: companies it works with, or being one',
|
|
2172
2273
|
},
|
|
2274
|
+
pact: {
|
|
2275
|
+
$ref: '#/$defs/AppPact',
|
|
2276
|
+
description: 'PACT: businesses it asks for each person',
|
|
2277
|
+
},
|
|
2278
|
+
a2a: {
|
|
2279
|
+
$ref: '#/$defs/AppA2A',
|
|
2280
|
+
description: 'A2A: the extensions its Agent Card advertises',
|
|
2281
|
+
},
|
|
2173
2282
|
rules: {
|
|
2174
2283
|
description: 'When it acts alone, and when it asks',
|
|
2175
2284
|
items: {
|
|
@@ -486,6 +486,46 @@ export interface AppPapSpec {
|
|
|
486
486
|
connections: AppPapConnectionSpec[];
|
|
487
487
|
company: AppPapCompanySpec;
|
|
488
488
|
}
|
|
489
|
+
/**
|
|
490
|
+
* A business the application asks for each person over PACT 1.0
|
|
491
|
+
* (AGENT_PROTOCOLS PI-01): its domain, and the audience its Provider
|
|
492
|
+
* assigned. Always in each person's own name; never a credential.
|
|
493
|
+
*/
|
|
494
|
+
export interface AppPactConnectionSpec {
|
|
495
|
+
/** Stable within the application: `support`. */
|
|
496
|
+
id: string;
|
|
497
|
+
/** The business's domain: `example.com`; its card is at `/.well-known/agent-card.json`. */
|
|
498
|
+
brand: string;
|
|
499
|
+
/** The audience the Brand's Provider assigned (PACT §3.1). */
|
|
500
|
+
audience: string;
|
|
501
|
+
/** `read`: asks as the application alone; `write`: also for the person, delegated. */
|
|
502
|
+
access: 'read' | 'write';
|
|
503
|
+
/** The Brand's scopes it may ask the person for: `orders:read`. */
|
|
504
|
+
scopes: string[];
|
|
505
|
+
}
|
|
506
|
+
/** PACT: the businesses it asks for each person. */
|
|
507
|
+
export interface AppPactSpec {
|
|
508
|
+
connections: AppPactConnectionSpec[];
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* An A2A extension the application's Agent Card advertises, beside the
|
|
512
|
+
* runtime's own (AGENT_PROTOCOLS PR-02). Its params are public: never a
|
|
513
|
+
* credential.
|
|
514
|
+
*/
|
|
515
|
+
export interface AppA2AExtensionSpec {
|
|
516
|
+
/** The extension's URI: an `https://` URL or a `urn:`. */
|
|
517
|
+
uri: string;
|
|
518
|
+
/** What it adds, for whoever reads the card. */
|
|
519
|
+
description: string;
|
|
520
|
+
/** Whether a client must support it to talk to the application at all. */
|
|
521
|
+
required: boolean;
|
|
522
|
+
/** Its parameters on the card, as the extension defines them. */
|
|
523
|
+
params: Record<string, unknown>;
|
|
524
|
+
}
|
|
525
|
+
/** A2A: the extensions its Agent Card advertises. */
|
|
526
|
+
export interface AppA2ASpec {
|
|
527
|
+
extensions: AppA2AExtensionSpec[];
|
|
528
|
+
}
|
|
489
529
|
/** When an application acts alone, and when it asks. */
|
|
490
530
|
export interface AppRuleSpec {
|
|
491
531
|
/** The action, in the words a person reads. */
|
|
@@ -1044,6 +1084,10 @@ export interface AppSpec {
|
|
|
1044
1084
|
connections: AppConnectionSpec[];
|
|
1045
1085
|
/** Personal Agent Protocol; absent, the application has none. */
|
|
1046
1086
|
pap?: AppPapSpec;
|
|
1087
|
+
/** PACT: the businesses it asks for each person (AGENT_PROTOCOLS PI-01). */
|
|
1088
|
+
pact?: AppPactSpec;
|
|
1089
|
+
/** A2A: the extensions its Agent Card advertises (AGENT_PROTOCOLS PR-02). */
|
|
1090
|
+
a2a?: AppA2ASpec;
|
|
1047
1091
|
rules: AppRuleSpec[];
|
|
1048
1092
|
permissions: AppPermissionsSpec;
|
|
1049
1093
|
interface: AppInterfaceSpec;
|
package/package.json
CHANGED
|
@@ -152,8 +152,16 @@ def load_specs(specs_dir: Path) -> tuple[list[dict[str, Any]], dict[str, Any]]:
|
|
|
152
152
|
# Personal Agent Protocol only when the application says something of it:
|
|
153
153
|
# an Appspec that does not mention `pap` reads back with none (the TypeScript
|
|
154
154
|
# reader's rule), so the catalogue leaves the defaults out too.
|
|
155
|
-
if "pap" in spec and spec["pap"] == type(app.pap)().model_dump(
|
|
155
|
+
if "pap" in spec and spec["pap"] == type(app.pap)().model_dump(
|
|
156
|
+
mode="json", by_alias=True
|
|
157
|
+
):
|
|
156
158
|
spec.pop("pap")
|
|
159
|
+
# PACT and A2A's extensions the same way (AGENT_PROTOCOLS PI-01, PR-02).
|
|
160
|
+
for block in ("pact", "a2a"):
|
|
161
|
+
if block in spec and spec[block] == type(getattr(app, block))().model_dump(
|
|
162
|
+
mode="json", by_alias=True
|
|
163
|
+
):
|
|
164
|
+
spec.pop(block)
|
|
157
165
|
for key in ("description", "instructions", "goal"):
|
|
158
166
|
spec[key] = _flat(spec.get(key))
|
|
159
167
|
spec["interface"]["welcome"] = _flat(spec["interface"].get("welcome"))
|
|
@@ -198,8 +206,24 @@ def load_specs(specs_dir: Path) -> tuple[list[dict[str, Any]], dict[str, Any]]:
|
|
|
198
206
|
if (signs := actions_module.server_tool_signs(server, name))
|
|
199
207
|
},
|
|
200
208
|
}
|
|
209
|
+
# The agent protocols' tools (AGENT_PROTOCOLS PR-54): by protocol, the
|
|
210
|
+
# connection prefix its connections take and what each tool can do.
|
|
211
|
+
protocols = {
|
|
212
|
+
identity: {
|
|
213
|
+
"connection": spec["connection"],
|
|
214
|
+
"tools": {
|
|
215
|
+
name: [
|
|
216
|
+
item.value
|
|
217
|
+
for item in actions_module.protocol_tool_classes(identity, name)
|
|
218
|
+
]
|
|
219
|
+
for name in actions_module.protocol_tool_names(identity)
|
|
220
|
+
},
|
|
221
|
+
}
|
|
222
|
+
for identity, spec in sorted(actions_module.protocol_tool_specs().items())
|
|
223
|
+
}
|
|
201
224
|
actions = {
|
|
202
225
|
"classes": [item.value for item in actions_module.ActionClass],
|
|
226
|
+
"protocols": protocols,
|
|
203
227
|
"tools": tools,
|
|
204
228
|
"servers": servers,
|
|
205
229
|
"behaviours": behaviours,
|
|
@@ -419,6 +443,10 @@ def generate_actions_python_code(actions: dict[str, Any]) -> str:
|
|
|
419
443
|
[
|
|
420
444
|
"}",
|
|
421
445
|
"",
|
|
446
|
+
"#: What each agent protocol's tools do, by protocol id: the prefix its",
|
|
447
|
+
"#: connections take (`pap:<domain>`) and each tool's classes (PR-54).",
|
|
448
|
+
f"PROTOCOL_TOOL_CLASSES: Dict[str, Dict[str, Any]] = {actions['protocols']!r}",
|
|
449
|
+
"",
|
|
422
450
|
"#: What each application of the catalogue does about each classed tool of the",
|
|
423
451
|
"#: servers it connects to, as agentspecs decides it: `do_it`, `if_asked`,",
|
|
424
452
|
"#: `ask_first` or `leave_to_me`. What the rules engine has to reproduce.",
|
|
@@ -471,6 +499,15 @@ def generate_actions_typescript_code(actions: dict[str, Any]) -> str:
|
|
|
471
499
|
+ ";",
|
|
472
500
|
"",
|
|
473
501
|
"/**",
|
|
502
|
+
" * What each agent protocol's tools do, by protocol id: the prefix its",
|
|
503
|
+
" * connections take (`pap:<domain>`) and each tool's classes (PR-54).",
|
|
504
|
+
" */",
|
|
505
|
+
"export const PROTOCOL_TOOL_CLASSES: Record<",
|
|
506
|
+
" string,",
|
|
507
|
+
" { connection: string; tools: Record<string, ActionClass[]> }",
|
|
508
|
+
"> = " + json.dumps(actions["protocols"], indent=2) + ";",
|
|
509
|
+
"",
|
|
510
|
+
"/**",
|
|
474
511
|
" * What each application of the catalogue does about each classed tool of the",
|
|
475
512
|
" * servers it connects to, as agentspecs decides it. What the rules engine has",
|
|
476
513
|
" * to reproduce.",
|