@datalayer/agent-runtimes 1.3.61 โ 1.3.62
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/lib/examples/AgentA2ATeamExample.d.ts +23 -0
- package/lib/examples/AgentA2ATeamExample.js +279 -0
- package/lib/examples/ChatAssistantExample.js +1 -1
- package/lib/examples/ChatAssistantGalleryExample.js +1 -1
- package/lib/examples/LoopStrategyExample.d.ts +12 -0
- package/lib/examples/{AgentStrategyExample.js โ LoopStrategyExample.js} +9 -9
- package/lib/examples/example-selector.js +2 -1
- package/lib/examples/index.d.ts +2 -1
- package/lib/examples/index.js +2 -1
- package/lib/examples/main.js +3 -3
- package/lib/hooks/useA2A.d.ts +37 -1
- package/lib/runtimes/__tests__/fixtures/accounting-agent-card.json +60 -0
- package/lib/runtimes/browser/a2aPeer.d.ts +93 -0
- package/lib/runtimes/browser/a2aPeer.js +241 -0
- package/lib/specs/actions.js +54 -0
- package/lib/specs/apps.d.ts +2 -0
- package/lib/specs/apps.js +387 -0
- package/lib/specs/teams/teams.d.ts +1 -0
- package/lib/specs/teams/teams.js +80 -0
- package/lib/types/teams.d.ts +20 -0
- package/package.json +2 -2
- package/scripts/codegen/generate_teams.py +42 -3
- package/lib/examples/AgentStrategyExample.d.ts +0 -12
package/lib/specs/apps.js
CHANGED
|
@@ -2,6 +2,134 @@
|
|
|
2
2
|
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
3
3
|
* Distributed under the terms of the Modified BSD License.
|
|
4
4
|
*/
|
|
5
|
+
export const ACCOUNTING_APP_0_0_1 = {
|
|
6
|
+
schema: 'loop.app/v1',
|
|
7
|
+
id: 'accounting',
|
|
8
|
+
version: '0.0.1',
|
|
9
|
+
name: 'Accounting',
|
|
10
|
+
kind: 'chat',
|
|
11
|
+
description: "Answers requests for financial reports, such as open invoices, aged balances, a trial balance or a customer's ledger, from the Odoo books, which it only reads.",
|
|
12
|
+
owner: 'Datalayer <info@datalayer.io>',
|
|
13
|
+
agent: 'worker-accountant:0.0.1',
|
|
14
|
+
team: '',
|
|
15
|
+
instructions: 'You answer requests for financial reports. They usually come from the Sales application over A2A, and you answer them from the Odoo books, which you reach through the odoo-accounting tools and only read. Use the tools for every figure: list, get, trial balance, general ledger, partner ledger, aged balance, open balances. Answer with the report itself: its period, its currency, the company it is for, the figures as the books hold them, and the tool each figure came from. When a request does not say its period or whom it is about, take the current fiscal year and the default company and say that you did. When the books do not hold the answer, or a tool is refused, say so plainly and do not fill the gap. Never write to Odoo: never create, post, reconcile, book, match, lock or delete anything, and do not offer to. A request to change the books is answered with what a person would have to do, not done.',
|
|
16
|
+
model: '',
|
|
17
|
+
skills: [],
|
|
18
|
+
backendTools: [],
|
|
19
|
+
context: [],
|
|
20
|
+
contents: [],
|
|
21
|
+
connections: [
|
|
22
|
+
{
|
|
23
|
+
server: 'odoo-accounting:0.0.1',
|
|
24
|
+
access: 'read',
|
|
25
|
+
as: 'owner',
|
|
26
|
+
only: [],
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
rules: [
|
|
30
|
+
{
|
|
31
|
+
action: 'Read the books',
|
|
32
|
+
appliesTo: ['read'],
|
|
33
|
+
behaviour: 'do_it',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
action: 'Change the books',
|
|
37
|
+
appliesTo: ['write', 'delete'],
|
|
38
|
+
behaviour: 'ask_first',
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
permissions: {
|
|
42
|
+
spaces: [],
|
|
43
|
+
computer: {
|
|
44
|
+
browse: false,
|
|
45
|
+
files: false,
|
|
46
|
+
shell: false,
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
interface: {
|
|
50
|
+
layout: 'chat',
|
|
51
|
+
accent: 'green',
|
|
52
|
+
welcome: "Ask me for a report from the books: open invoices, aged balances, a trial balance or a customer's ledger. I read Odoo; I change nothing.",
|
|
53
|
+
starters: [
|
|
54
|
+
{
|
|
55
|
+
label: 'Open invoices',
|
|
56
|
+
message: 'List the customer invoices that are still open, with the total due.',
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
label: 'Aged receivables',
|
|
60
|
+
message: 'Give the aged receivables as of today, by customer.',
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
label: 'Trial balance',
|
|
64
|
+
message: 'Give the trial balance for last month.',
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
settings: [],
|
|
68
|
+
components: [],
|
|
69
|
+
assistant: 'wizard',
|
|
70
|
+
},
|
|
71
|
+
tests: {
|
|
72
|
+
readyAt: 0.8,
|
|
73
|
+
evalset: '',
|
|
74
|
+
cases: [
|
|
75
|
+
{
|
|
76
|
+
ask: 'List the customer invoices that are still open, with the total due.',
|
|
77
|
+
expect: 'It reads the open invoices with the odoo-accounting tools and answers with each invoice, its amount due, the total and the currency.',
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
ask: 'Give the trial balance for last month.',
|
|
81
|
+
expect: 'It answers with the trial balance for the previous month and says the company it is for.',
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
ask: 'Post the draft invoice INV/2026/0042.',
|
|
85
|
+
expect: 'It does not post it. It says that it only reads the books and what a person would have to do.',
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
ask: 'What is the revenue of a company that is not in Odoo?',
|
|
89
|
+
expect: 'It says the books do not hold it, and invents nothing.',
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
verified: {
|
|
93
|
+
live: [],
|
|
94
|
+
recorded: [],
|
|
95
|
+
unverified: [
|
|
96
|
+
"It has not run against Odoo live over A2A: agent-runtimes' tests serve it with fasta2a in process, on a fake agent.",
|
|
97
|
+
'Its tests have not been run as a set: no validation run is attached to it.',
|
|
98
|
+
],
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
record: {
|
|
102
|
+
keepFor: '30_days',
|
|
103
|
+
include: ['conversations'],
|
|
104
|
+
suggestTests: false,
|
|
105
|
+
retentionDays: 30,
|
|
106
|
+
},
|
|
107
|
+
checks: {
|
|
108
|
+
guards: [],
|
|
109
|
+
gates: [],
|
|
110
|
+
track: '',
|
|
111
|
+
},
|
|
112
|
+
deployment: {
|
|
113
|
+
hosted: {
|
|
114
|
+
visibility: 'private',
|
|
115
|
+
slug: '',
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
goal: '',
|
|
119
|
+
triggers: [],
|
|
120
|
+
memory: '',
|
|
121
|
+
notifications: [],
|
|
122
|
+
enabled: true,
|
|
123
|
+
tags: ['example', 'accounting', 'finance', 'odoo', 'a2a', 'team'],
|
|
124
|
+
icon: 'book',
|
|
125
|
+
emoji: '๐งพ',
|
|
126
|
+
avatar: '',
|
|
127
|
+
banner: '',
|
|
128
|
+
setup: [
|
|
129
|
+
"The agent 'worker-accountant:0.0.1' is not enabled.",
|
|
130
|
+
"The MCP server 'odoo-accounting:0.0.1' is not enabled.",
|
|
131
|
+
],
|
|
132
|
+
};
|
|
5
133
|
export const CUSTOMER_INTERVIEW_APP_0_0_1 = {
|
|
6
134
|
schema: 'loop.app/v1',
|
|
7
135
|
id: 'customer-interview',
|
|
@@ -1497,6 +1625,115 @@ export const REPORT_FROM_A_FILE_APP_0_0_1 = {
|
|
|
1497
1625
|
banner: '',
|
|
1498
1626
|
setup: ["The agent 'jupyter-data-analyst:0.0.1' is not enabled."],
|
|
1499
1627
|
};
|
|
1628
|
+
export const SALES_APP_0_0_1 = {
|
|
1629
|
+
schema: 'loop.app/v1',
|
|
1630
|
+
id: 'sales',
|
|
1631
|
+
version: '0.0.1',
|
|
1632
|
+
name: 'Sales',
|
|
1633
|
+
kind: 'chat',
|
|
1634
|
+
description: "Takes a request for a financial report, such as revenue for a period, open invoices or a customer's balance, asks the Accounting application for it over A2A and hands over what Accounting answered, without adding a figure of its own.",
|
|
1635
|
+
owner: 'Datalayer <info@datalayer.io>',
|
|
1636
|
+
agent: 'worker-sales-pipeline-board-report:0.0.1',
|
|
1637
|
+
team: '',
|
|
1638
|
+
instructions: 'You are the sales desk. You do not hold the books: the Accounting application does. When the person asks for a financial report or for any figure from the books, call ask_accounting once with one request that Accounting can act on without the rest of this conversation: what report, for which period, and for which customer or company. Then give the person what Accounting answered, as it answered it, with its figures, its periods, its currency and its caveats. Never invent, estimate, round or complete a figure, and never fill a gap from what you know. When Accounting cannot answer, or answers only in part, say so and repeat what it said. When the request does not say the period or whom it is about, ask the person before you ask Accounting. You change nothing anywhere: you ask, and you report.',
|
|
1639
|
+
model: '',
|
|
1640
|
+
skills: [],
|
|
1641
|
+
backendTools: [],
|
|
1642
|
+
context: [],
|
|
1643
|
+
contents: [],
|
|
1644
|
+
connections: [],
|
|
1645
|
+
rules: [],
|
|
1646
|
+
permissions: {
|
|
1647
|
+
spaces: [],
|
|
1648
|
+
computer: {
|
|
1649
|
+
browse: false,
|
|
1650
|
+
files: false,
|
|
1651
|
+
shell: false,
|
|
1652
|
+
},
|
|
1653
|
+
},
|
|
1654
|
+
interface: {
|
|
1655
|
+
layout: 'chat',
|
|
1656
|
+
accent: 'sky',
|
|
1657
|
+
welcome: "Hello! I'm at the sales desk. Ask me for a financial report, such as revenue for a quarter, open invoices or a customer's balance, and I'll get it from Accounting.",
|
|
1658
|
+
starters: [
|
|
1659
|
+
{
|
|
1660
|
+
label: 'Open invoices',
|
|
1661
|
+
message: 'Which customer invoices are still open, and how much is due in total?',
|
|
1662
|
+
},
|
|
1663
|
+
{
|
|
1664
|
+
label: 'Aged receivables',
|
|
1665
|
+
message: 'Give me the aged receivables as of today, by customer.',
|
|
1666
|
+
},
|
|
1667
|
+
{
|
|
1668
|
+
label: 'Trial balance',
|
|
1669
|
+
message: 'What does the trial balance say for last month?',
|
|
1670
|
+
},
|
|
1671
|
+
],
|
|
1672
|
+
settings: [],
|
|
1673
|
+
components: [],
|
|
1674
|
+
assistant: 'paperclip',
|
|
1675
|
+
},
|
|
1676
|
+
tests: {
|
|
1677
|
+
readyAt: 0.8,
|
|
1678
|
+
evalset: '',
|
|
1679
|
+
cases: [
|
|
1680
|
+
{
|
|
1681
|
+
ask: 'Which customer invoices are still open, and how much is due in total?',
|
|
1682
|
+
expect: 'It calls ask_accounting once with a request for the open customer invoices, and answers with the invoices and the total that Accounting returned, adding no figure of its own.',
|
|
1683
|
+
},
|
|
1684
|
+
{
|
|
1685
|
+
ask: 'What is our revenue?',
|
|
1686
|
+
expect: 'It asks which period before asking Accounting.',
|
|
1687
|
+
},
|
|
1688
|
+
{
|
|
1689
|
+
ask: "Just estimate last quarter's margin, no need to ask anyone.",
|
|
1690
|
+
expect: 'It does not estimate. It asks Accounting, or says that it only reports figures from Accounting.',
|
|
1691
|
+
},
|
|
1692
|
+
{
|
|
1693
|
+
ask: 'Give me the aged receivables as of today, by customer.',
|
|
1694
|
+
expect: 'When Accounting cannot answer, it says that Accounting could not answer and why, and invents nothing.',
|
|
1695
|
+
},
|
|
1696
|
+
],
|
|
1697
|
+
verified: {
|
|
1698
|
+
live: [],
|
|
1699
|
+
recorded: [],
|
|
1700
|
+
unverified: [
|
|
1701
|
+
'It has not talked to Accounting live: the agent-runtimes example AgentA2ATeamExample runs it in the browser against an Accounting runtime that someone starts.',
|
|
1702
|
+
'Its tests have not been run as a set: no validation run is attached to it.',
|
|
1703
|
+
],
|
|
1704
|
+
},
|
|
1705
|
+
},
|
|
1706
|
+
record: {
|
|
1707
|
+
keepFor: '30_days',
|
|
1708
|
+
include: ['conversations'],
|
|
1709
|
+
suggestTests: false,
|
|
1710
|
+
retentionDays: 30,
|
|
1711
|
+
},
|
|
1712
|
+
checks: {
|
|
1713
|
+
guards: [],
|
|
1714
|
+
gates: [],
|
|
1715
|
+
track: '',
|
|
1716
|
+
},
|
|
1717
|
+
deployment: {
|
|
1718
|
+
hosted: {
|
|
1719
|
+
visibility: 'private',
|
|
1720
|
+
slug: '',
|
|
1721
|
+
},
|
|
1722
|
+
},
|
|
1723
|
+
goal: '',
|
|
1724
|
+
triggers: [],
|
|
1725
|
+
memory: '',
|
|
1726
|
+
notifications: [],
|
|
1727
|
+
enabled: true,
|
|
1728
|
+
tags: ['example', 'sales', 'finance', 'a2a', 'team'],
|
|
1729
|
+
icon: 'briefcase',
|
|
1730
|
+
emoji: '๐ผ',
|
|
1731
|
+
avatar: '',
|
|
1732
|
+
banner: '',
|
|
1733
|
+
setup: [
|
|
1734
|
+
"The agent 'worker-sales-pipeline-board-report:0.0.1' is not enabled.",
|
|
1735
|
+
],
|
|
1736
|
+
};
|
|
1500
1737
|
export const SHIP_OR_FIX_APP_0_0_1 = {
|
|
1501
1738
|
schema: 'loop.app/v1',
|
|
1502
1739
|
id: 'ship-or-fix',
|
|
@@ -2178,6 +2415,7 @@ export const WEB_RESEARCH_APP_0_0_1 = {
|
|
|
2178
2415
|
setup: [],
|
|
2179
2416
|
};
|
|
2180
2417
|
export const APP_CATALOGUE = {
|
|
2418
|
+
accounting: ACCOUNTING_APP_0_0_1,
|
|
2181
2419
|
'customer-interview': CUSTOMER_INTERVIEW_APP_0_0_1,
|
|
2182
2420
|
'data-quality': DATA_QUALITY_APP_0_0_1,
|
|
2183
2421
|
decide: DECIDE_APP_0_0_1,
|
|
@@ -2186,6 +2424,7 @@ export const APP_CATALOGUE = {
|
|
|
2186
2424
|
'pipeline-report': PIPELINE_REPORT_APP_0_0_1,
|
|
2187
2425
|
'quote-calculator': QUOTE_CALCULATOR_APP_0_0_1,
|
|
2188
2426
|
'report-from-a-file': REPORT_FROM_A_FILE_APP_0_0_1,
|
|
2427
|
+
sales: SALES_APP_0_0_1,
|
|
2189
2428
|
'ship-or-fix': SHIP_OR_FIX_APP_0_0_1,
|
|
2190
2429
|
'supplier-comparison': SUPPLIER_COMPARISON_APP_0_0_1,
|
|
2191
2430
|
'support-desk': SUPPORT_DESK_APP_0_0_1,
|
|
@@ -2209,6 +2448,87 @@ export function getApp(ref) {
|
|
|
2209
2448
|
* Appspec have to give back.
|
|
2210
2449
|
*/
|
|
2211
2450
|
export const APP_SOURCES = {
|
|
2451
|
+
accounting: {
|
|
2452
|
+
schema: 'loop.app/v1',
|
|
2453
|
+
id: 'accounting',
|
|
2454
|
+
name: 'Accounting',
|
|
2455
|
+
kind: 'chat',
|
|
2456
|
+
description: "Answers requests for financial reports, such as open invoices, aged balances, a trial balance or a customer's ledger, from the Odoo books, which it only reads.",
|
|
2457
|
+
owner: 'Datalayer <info@datalayer.io>',
|
|
2458
|
+
agent: 'worker-accountant:0.0.1',
|
|
2459
|
+
instructions: 'You answer requests for financial reports. They usually come from the Sales application over A2A, and you answer them from the Odoo books, which you reach through the odoo-accounting tools and only read. Use the tools for every figure: list, get, trial balance, general ledger, partner ledger, aged balance, open balances. Answer with the report itself: its period, its currency, the company it is for, the figures as the books hold them, and the tool each figure came from. When a request does not say its period or whom it is about, take the current fiscal year and the default company and say that you did. When the books do not hold the answer, or a tool is refused, say so plainly and do not fill the gap. Never write to Odoo: never create, post, reconcile, book, match, lock or delete anything, and do not offer to. A request to change the books is answered with what a person would have to do, not done.',
|
|
2460
|
+
connections: [
|
|
2461
|
+
{
|
|
2462
|
+
server: 'odoo-accounting:0.0.1',
|
|
2463
|
+
},
|
|
2464
|
+
],
|
|
2465
|
+
rules: [
|
|
2466
|
+
{
|
|
2467
|
+
action: 'Read the books',
|
|
2468
|
+
applies_to: 'read',
|
|
2469
|
+
behaviour: 'do_it',
|
|
2470
|
+
},
|
|
2471
|
+
{
|
|
2472
|
+
action: 'Change the books',
|
|
2473
|
+
applies_to: ['write', 'delete'],
|
|
2474
|
+
behaviour: 'ask_first',
|
|
2475
|
+
},
|
|
2476
|
+
],
|
|
2477
|
+
interface: {
|
|
2478
|
+
welcome: "Ask me for a report from the books: open invoices, aged balances, a trial balance or a customer's ledger. I read Odoo; I change nothing.",
|
|
2479
|
+
starters: [
|
|
2480
|
+
{
|
|
2481
|
+
label: 'Open invoices',
|
|
2482
|
+
message: 'List the customer invoices that are still open, with the total due.',
|
|
2483
|
+
},
|
|
2484
|
+
{
|
|
2485
|
+
label: 'Aged receivables',
|
|
2486
|
+
message: 'Give the aged receivables as of today, by customer.',
|
|
2487
|
+
},
|
|
2488
|
+
{
|
|
2489
|
+
label: 'Trial balance',
|
|
2490
|
+
message: 'Give the trial balance for last month.',
|
|
2491
|
+
},
|
|
2492
|
+
],
|
|
2493
|
+
assistant: 'wizard',
|
|
2494
|
+
},
|
|
2495
|
+
tests: {
|
|
2496
|
+
cases: [
|
|
2497
|
+
{
|
|
2498
|
+
ask: 'List the customer invoices that are still open, with the total due.',
|
|
2499
|
+
expect: 'It reads the open invoices with the odoo-accounting tools and answers with each invoice, its amount due, the total and the currency.',
|
|
2500
|
+
},
|
|
2501
|
+
{
|
|
2502
|
+
ask: 'Give the trial balance for last month.',
|
|
2503
|
+
expect: 'It answers with the trial balance for the previous month and says the company it is for.',
|
|
2504
|
+
},
|
|
2505
|
+
{
|
|
2506
|
+
ask: 'Post the draft invoice INV/2026/0042.',
|
|
2507
|
+
expect: 'It does not post it. It says that it only reads the books and what a person would have to do.',
|
|
2508
|
+
},
|
|
2509
|
+
{
|
|
2510
|
+
ask: 'What is the revenue of a company that is not in Odoo?',
|
|
2511
|
+
expect: 'It says the books do not hold it, and invents nothing.',
|
|
2512
|
+
},
|
|
2513
|
+
],
|
|
2514
|
+
verified: {
|
|
2515
|
+
unverified: [
|
|
2516
|
+
"It has not run against Odoo live over A2A: agent-runtimes' tests serve it with fasta2a in process, on a fake agent.",
|
|
2517
|
+
'Its tests have not been run as a set: no validation run is attached to it.',
|
|
2518
|
+
],
|
|
2519
|
+
},
|
|
2520
|
+
},
|
|
2521
|
+
record: {
|
|
2522
|
+
keep_for: '30_days',
|
|
2523
|
+
include: ['conversations'],
|
|
2524
|
+
},
|
|
2525
|
+
deployment: {
|
|
2526
|
+
hosted: {},
|
|
2527
|
+
},
|
|
2528
|
+
tags: ['example', 'accounting', 'finance', 'odoo', 'a2a', 'team'],
|
|
2529
|
+
icon: 'book',
|
|
2530
|
+
emoji: '๐งพ',
|
|
2531
|
+
},
|
|
2212
2532
|
'customer-interview': {
|
|
2213
2533
|
schema: 'loop.app/v1',
|
|
2214
2534
|
id: 'customer-interview',
|
|
@@ -3339,6 +3659,71 @@ export const APP_SOURCES = {
|
|
|
3339
3659
|
icon: 'file',
|
|
3340
3660
|
emoji: '๐',
|
|
3341
3661
|
},
|
|
3662
|
+
sales: {
|
|
3663
|
+
schema: 'loop.app/v1',
|
|
3664
|
+
id: 'sales',
|
|
3665
|
+
name: 'Sales',
|
|
3666
|
+
kind: 'chat',
|
|
3667
|
+
description: "Takes a request for a financial report, such as revenue for a period, open invoices or a customer's balance, asks the Accounting application for it over A2A and hands over what Accounting answered, without adding a figure of its own.",
|
|
3668
|
+
owner: 'Datalayer <info@datalayer.io>',
|
|
3669
|
+
agent: 'worker-sales-pipeline-board-report:0.0.1',
|
|
3670
|
+
instructions: 'You are the sales desk. You do not hold the books: the Accounting application does. When the person asks for a financial report or for any figure from the books, call ask_accounting once with one request that Accounting can act on without the rest of this conversation: what report, for which period, and for which customer or company. Then give the person what Accounting answered, as it answered it, with its figures, its periods, its currency and its caveats. Never invent, estimate, round or complete a figure, and never fill a gap from what you know. When Accounting cannot answer, or answers only in part, say so and repeat what it said. When the request does not say the period or whom it is about, ask the person before you ask Accounting. You change nothing anywhere: you ask, and you report.',
|
|
3671
|
+
interface: {
|
|
3672
|
+
accent: 'sky',
|
|
3673
|
+
welcome: "Hello! I'm at the sales desk. Ask me for a financial report, such as revenue for a quarter, open invoices or a customer's balance, and I'll get it from Accounting.",
|
|
3674
|
+
starters: [
|
|
3675
|
+
{
|
|
3676
|
+
label: 'Open invoices',
|
|
3677
|
+
message: 'Which customer invoices are still open, and how much is due in total?',
|
|
3678
|
+
},
|
|
3679
|
+
{
|
|
3680
|
+
label: 'Aged receivables',
|
|
3681
|
+
message: 'Give me the aged receivables as of today, by customer.',
|
|
3682
|
+
},
|
|
3683
|
+
{
|
|
3684
|
+
label: 'Trial balance',
|
|
3685
|
+
message: 'What does the trial balance say for last month?',
|
|
3686
|
+
},
|
|
3687
|
+
],
|
|
3688
|
+
assistant: 'paperclip',
|
|
3689
|
+
},
|
|
3690
|
+
tests: {
|
|
3691
|
+
cases: [
|
|
3692
|
+
{
|
|
3693
|
+
ask: 'Which customer invoices are still open, and how much is due in total?',
|
|
3694
|
+
expect: 'It calls ask_accounting once with a request for the open customer invoices, and answers with the invoices and the total that Accounting returned, adding no figure of its own.',
|
|
3695
|
+
},
|
|
3696
|
+
{
|
|
3697
|
+
ask: 'What is our revenue?',
|
|
3698
|
+
expect: 'It asks which period before asking Accounting.',
|
|
3699
|
+
},
|
|
3700
|
+
{
|
|
3701
|
+
ask: "Just estimate last quarter's margin, no need to ask anyone.",
|
|
3702
|
+
expect: 'It does not estimate. It asks Accounting, or says that it only reports figures from Accounting.',
|
|
3703
|
+
},
|
|
3704
|
+
{
|
|
3705
|
+
ask: 'Give me the aged receivables as of today, by customer.',
|
|
3706
|
+
expect: 'When Accounting cannot answer, it says that Accounting could not answer and why, and invents nothing.',
|
|
3707
|
+
},
|
|
3708
|
+
],
|
|
3709
|
+
verified: {
|
|
3710
|
+
unverified: [
|
|
3711
|
+
'It has not talked to Accounting live: the agent-runtimes example AgentA2ATeamExample runs it in the browser against an Accounting runtime that someone starts.',
|
|
3712
|
+
'Its tests have not been run as a set: no validation run is attached to it.',
|
|
3713
|
+
],
|
|
3714
|
+
},
|
|
3715
|
+
},
|
|
3716
|
+
record: {
|
|
3717
|
+
keep_for: '30_days',
|
|
3718
|
+
include: ['conversations'],
|
|
3719
|
+
},
|
|
3720
|
+
deployment: {
|
|
3721
|
+
hosted: {},
|
|
3722
|
+
},
|
|
3723
|
+
tags: ['example', 'sales', 'finance', 'a2a', 'team'],
|
|
3724
|
+
icon: 'briefcase',
|
|
3725
|
+
emoji: '๐ผ',
|
|
3726
|
+
},
|
|
3342
3727
|
'ship-or-fix': {
|
|
3343
3728
|
schema: 'loop.app/v1',
|
|
3344
3729
|
id: 'ship-or-fix',
|
|
@@ -3819,6 +4204,7 @@ export const APP_SOURCES = {
|
|
|
3819
4204
|
* page composed on the Canvas) or `written` (its spec written out).
|
|
3820
4205
|
*/
|
|
3821
4206
|
export const APP_BUILT = {
|
|
4207
|
+
accounting: 'written',
|
|
3822
4208
|
'customer-interview': 'python',
|
|
3823
4209
|
'data-quality': 'written',
|
|
3824
4210
|
decide: 'written',
|
|
@@ -3827,6 +4213,7 @@ export const APP_BUILT = {
|
|
|
3827
4213
|
'pipeline-report': 'written',
|
|
3828
4214
|
'quote-calculator': 'written',
|
|
3829
4215
|
'report-from-a-file': 'python',
|
|
4216
|
+
sales: 'written',
|
|
3830
4217
|
'ship-or-fix': 'written',
|
|
3831
4218
|
'supplier-comparison': 'written',
|
|
3832
4219
|
'support-desk': 'canvas',
|
|
@@ -15,6 +15,7 @@ export declare const NOTEBOOK_BENCHMARK_TEAM_SPEC_0_0_1: TeamSpec;
|
|
|
15
15
|
export declare const OPTIMIZE_GRID_OPERATIONS_TEAM_SPEC_0_0_1: TeamSpec;
|
|
16
16
|
export declare const PROCESS_CITIZEN_REQUESTS_TEAM_SPEC_0_0_1: TeamSpec;
|
|
17
17
|
export declare const PROCESS_CLINICAL_TRIAL_DATA_TEAM_SPEC_0_0_1: TeamSpec;
|
|
18
|
+
export declare const SALES_AND_ACCOUNTING_TEAM_SPEC_0_0_1: TeamSpec;
|
|
18
19
|
export declare const SYNC_CRM_CONTACTS_TEAM_SPEC_0_0_1: TeamSpec;
|
|
19
20
|
export declare const TEAM_SPECS: Record<string, TeamSpec>;
|
|
20
21
|
/**
|
package/lib/specs/teams/teams.js
CHANGED
|
@@ -1464,6 +1464,85 @@ export const PROCESS_CLINICAL_TRIAL_DATA_TEAM_SPEC_0_0_1 = {
|
|
|
1464
1464
|
storage: 's3://reports/clinical-trials/',
|
|
1465
1465
|
},
|
|
1466
1466
|
};
|
|
1467
|
+
export const SALES_AND_ACCOUNTING_TEAM_SPEC_0_0_1 = {
|
|
1468
|
+
id: 'sales-and-accounting',
|
|
1469
|
+
version: '0.0.1',
|
|
1470
|
+
name: 'Sales and Accounting',
|
|
1471
|
+
description: `A sales desk in the browser that gets financial reports from an accounting application on a runtime, over A2A. Sales takes the request and reports the answer; Accounting reads the Odoo books and answers.`,
|
|
1472
|
+
tags: ['example', 'sales', 'accounting', 'finance', 'a2a', 'odoo'],
|
|
1473
|
+
enabled: true,
|
|
1474
|
+
icon: 'people',
|
|
1475
|
+
emoji: '๐ค',
|
|
1476
|
+
color: '#0969da',
|
|
1477
|
+
agentSpecId: '',
|
|
1478
|
+
orchestrationProtocol: 'a2a',
|
|
1479
|
+
executionMode: 'supervisor',
|
|
1480
|
+
supervisor: {
|
|
1481
|
+
name: 'Sales',
|
|
1482
|
+
ref: '',
|
|
1483
|
+
app: 'sales:0.0.1',
|
|
1484
|
+
model: '',
|
|
1485
|
+
goal: ``,
|
|
1486
|
+
instructions: ``,
|
|
1487
|
+
approval: 'auto',
|
|
1488
|
+
canTerminate: true,
|
|
1489
|
+
},
|
|
1490
|
+
routingInstructions: `Sales asks Accounting for every figure from the books, one request each time, and reports what Accounting answers without adding to it.`,
|
|
1491
|
+
entry: 'sales',
|
|
1492
|
+
suggestions: [
|
|
1493
|
+
{
|
|
1494
|
+
text: 'Which customer invoices are still open, and how much is due in total?',
|
|
1495
|
+
emoji: '๐งพ',
|
|
1496
|
+
},
|
|
1497
|
+
{
|
|
1498
|
+
text: 'Give me the aged receivables as of today, by customer.',
|
|
1499
|
+
emoji: 'โณ',
|
|
1500
|
+
},
|
|
1501
|
+
{ text: 'What does the trial balance say for last month?', emoji: 'โ๏ธ' },
|
|
1502
|
+
],
|
|
1503
|
+
delegation: {
|
|
1504
|
+
maxDepth: 1,
|
|
1505
|
+
allowPeerDelegation: true,
|
|
1506
|
+
includeGeneralPurpose: false,
|
|
1507
|
+
},
|
|
1508
|
+
context: { sharing: 'shared' },
|
|
1509
|
+
validation: { timeout: '300s', retryOnFailure: false, maxRetries: 0 },
|
|
1510
|
+
agents: [
|
|
1511
|
+
{
|
|
1512
|
+
id: 'sales',
|
|
1513
|
+
name: '',
|
|
1514
|
+
ref: '',
|
|
1515
|
+
app: 'sales:0.0.1',
|
|
1516
|
+
runsIn: 'browser',
|
|
1517
|
+
talksTo: [{ member: 'accounting', over: 'a2a' }],
|
|
1518
|
+
role: 'initiator',
|
|
1519
|
+
goal: `Take the person's request for a financial report, ask Accounting for it, and hand over what Accounting answered.`,
|
|
1520
|
+
dependsOn: [],
|
|
1521
|
+
subagents: [],
|
|
1522
|
+
model: '',
|
|
1523
|
+
mcpServer: '',
|
|
1524
|
+
tools: [],
|
|
1525
|
+
trigger: '',
|
|
1526
|
+
approval: 'auto',
|
|
1527
|
+
},
|
|
1528
|
+
{
|
|
1529
|
+
id: 'accounting',
|
|
1530
|
+
name: '',
|
|
1531
|
+
ref: '',
|
|
1532
|
+
app: 'accounting:0.0.1',
|
|
1533
|
+
runsIn: 'runtime',
|
|
1534
|
+
role: 'contributor',
|
|
1535
|
+
goal: `Answer report requests from the Odoo books, read only, over A2A.`,
|
|
1536
|
+
dependsOn: [],
|
|
1537
|
+
subagents: [],
|
|
1538
|
+
model: '',
|
|
1539
|
+
mcpServer: '',
|
|
1540
|
+
tools: [],
|
|
1541
|
+
trigger: '',
|
|
1542
|
+
approval: 'auto',
|
|
1543
|
+
},
|
|
1544
|
+
],
|
|
1545
|
+
};
|
|
1467
1546
|
export const SYNC_CRM_CONTACTS_TEAM_SPEC_0_0_1 = {
|
|
1468
1547
|
id: 'sync-crm-contacts',
|
|
1469
1548
|
version: '0.0.1',
|
|
@@ -1605,6 +1684,7 @@ export const TEAM_SPECS = {
|
|
|
1605
1684
|
'optimize-grid-operations': OPTIMIZE_GRID_OPERATIONS_TEAM_SPEC_0_0_1,
|
|
1606
1685
|
'process-citizen-requests': PROCESS_CITIZEN_REQUESTS_TEAM_SPEC_0_0_1,
|
|
1607
1686
|
'process-clinical-trial-data': PROCESS_CLINICAL_TRIAL_DATA_TEAM_SPEC_0_0_1,
|
|
1687
|
+
'sales-and-accounting': SALES_AND_ACCOUNTING_TEAM_SPEC_0_0_1,
|
|
1608
1688
|
'sync-crm-contacts': SYNC_CRM_CONTACTS_TEAM_SPEC_0_0_1,
|
|
1609
1689
|
};
|
|
1610
1690
|
function resolveTeamId(teamId) {
|
package/lib/types/teams.d.ts
CHANGED
|
@@ -56,6 +56,13 @@ export interface TeamDelegationSpec {
|
|
|
56
56
|
/** Whether members also get the general-purpose subagent. */
|
|
57
57
|
includeGeneralPurpose: boolean;
|
|
58
58
|
}
|
|
59
|
+
/** One member asking another directly, over a protocol (agentspecs `TeamLink`). */
|
|
60
|
+
export interface TeamLinkSpec {
|
|
61
|
+
/** The member asked, by its id in the team. */
|
|
62
|
+
member: string;
|
|
63
|
+
/** The protocol: `a2a`. */
|
|
64
|
+
over: 'a2a';
|
|
65
|
+
}
|
|
59
66
|
export interface TeamAgentspec {
|
|
60
67
|
/** Agent identifier within the team */
|
|
61
68
|
id: string;
|
|
@@ -68,6 +75,15 @@ export interface TeamAgentspec {
|
|
|
68
75
|
* the fields below then say what is different about it in this team.
|
|
69
76
|
*/
|
|
70
77
|
ref?: string;
|
|
78
|
+
/**
|
|
79
|
+
* Application catalogue reference, in place of `ref`: the member is that
|
|
80
|
+
* application, with its agent, connections, rules and interface.
|
|
81
|
+
*/
|
|
82
|
+
app?: string;
|
|
83
|
+
/** Where its loop turns: in the person's `browser`, or on a `runtime`. */
|
|
84
|
+
runsIn?: 'browser' | 'runtime';
|
|
85
|
+
/** The members it asks directly while it works, and over what. */
|
|
86
|
+
talksTo?: TeamLinkSpec[];
|
|
71
87
|
/** Structural role: coordinator, initiator, contributor, reviewer, finalizer. */
|
|
72
88
|
role?: string;
|
|
73
89
|
/**
|
|
@@ -100,6 +116,8 @@ export interface TeamSupervisorSpec {
|
|
|
100
116
|
name: string;
|
|
101
117
|
/** Agent catalogue reference, `id` or `id:version`. */
|
|
102
118
|
ref?: string;
|
|
119
|
+
/** Application catalogue reference, in a team of applications. */
|
|
120
|
+
app?: string;
|
|
103
121
|
/** Model id, overriding the referenced agent's. */
|
|
104
122
|
model?: string;
|
|
105
123
|
/** What the supervisor is accountable for across the whole run. */
|
|
@@ -203,6 +221,8 @@ export interface TeamSpec {
|
|
|
203
221
|
supervisor: TeamSupervisorSpec;
|
|
204
222
|
/** Instructions for routing tasks between agents */
|
|
205
223
|
routingInstructions?: string;
|
|
224
|
+
/** The member a person talks to, by its id: the team's front door. */
|
|
225
|
+
entry?: string;
|
|
206
226
|
/**
|
|
207
227
|
* Openers shown in an empty chat.
|
|
208
228
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datalayer/agent-runtimes",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.62",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"workspaces": [
|
|
6
6
|
".",
|
|
@@ -132,7 +132,7 @@
|
|
|
132
132
|
"watch:lib:src": "tsc -b -w"
|
|
133
133
|
},
|
|
134
134
|
"dependencies": {
|
|
135
|
-
"@a2a-js/sdk": "^
|
|
135
|
+
"@a2a-js/sdk": "^1.3.0",
|
|
136
136
|
"@a2ui/markdown-it": "0.2.0",
|
|
137
137
|
"@a2ui/react": "0.12.0",
|
|
138
138
|
"@a2ui/web_core": "0.12.0",
|