@datalayer/agent-runtimes 1.3.86 → 1.3.88

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.
Files changed (66) hide show
  1. package/lib/components/a2ui/datalayer/Download.d.ts +21 -0
  2. package/lib/components/a2ui/datalayer/Download.js +66 -0
  3. package/lib/components/a2ui/datalayer/drawn.d.ts +1 -1
  4. package/lib/components/a2ui/datalayer/drawn.js +1 -0
  5. package/lib/components/a2ui/datalayer/index.d.ts +2 -1
  6. package/lib/components/a2ui/datalayer/index.js +3 -0
  7. package/lib/components/inspector/a2aSpans.d.ts +9 -0
  8. package/lib/components/inspector/a2aSpans.js +11 -1
  9. package/lib/components/teams/A2ATeamGraph.d.ts +2 -2
  10. package/lib/components/teams/A2ATeamGraph.js +39 -22
  11. package/lib/components/teams/AnswerSurfaces.d.ts +56 -0
  12. package/lib/components/teams/AnswerSurfaces.js +27 -0
  13. package/lib/components/teams/AnswerSurfacesView.d.ts +14 -0
  14. package/lib/components/teams/AnswerSurfacesView.js +30 -0
  15. package/lib/components/teams/index.d.ts +1 -0
  16. package/lib/components/teams/index.js +1 -0
  17. package/lib/components/teams/useA2ATeam.d.ts +56 -2
  18. package/lib/components/teams/useA2ATeam.js +122 -3
  19. package/lib/hooks/useAgentRuntimes.d.ts +13 -0
  20. package/lib/hooks/useAgentRuntimes.js +11 -1
  21. package/lib/loop/apps/AppFeedback.js +11 -2
  22. package/lib/loop/apps/AppRenderer.d.ts +13 -1
  23. package/lib/loop/apps/AppRenderer.js +34 -1
  24. package/lib/loop/apps/AppRuntimePlugins.d.ts +8 -0
  25. package/lib/loop/apps/AppRuntimePlugins.js +87 -0
  26. package/lib/loop/apps/feedback.d.ts +7 -0
  27. package/lib/loop/apps/feedback.js +3 -0
  28. package/lib/loop/apps/pluginPair.d.ts +60 -0
  29. package/lib/loop/apps/pluginPair.js +44 -0
  30. package/lib/loop/apps/threads.d.ts +35 -0
  31. package/lib/loop/apps/threads.js +79 -0
  32. package/lib/loop/embed/LoopEmbed.d.ts +4 -3
  33. package/lib/loop/embed/hostBridge.d.ts +27 -0
  34. package/lib/loop/embed/hostBridge.js +47 -0
  35. package/lib/loop/index.d.ts +1 -1
  36. package/lib/loop/index.js +1 -1
  37. package/lib/loop/plugins/agent-capacity/index.d.ts +7 -0
  38. package/lib/loop/plugins/agent-capacity/index.js +3 -2
  39. package/lib/loop/plugins/agents/DatalayerAgentBridge.js +11 -0
  40. package/lib/loop/plugins/agents/appLaunch.d.ts +15 -0
  41. package/lib/loop/plugins/agents/appLaunch.js +28 -0
  42. package/lib/loop/plugins/chat/ChatView.js +177 -109
  43. package/lib/loop/shell/LoopWorkspace.d.ts +3 -3
  44. package/lib/loop/shell/LoopWorkspace.js +1 -1
  45. package/lib/runtimes/__tests__/fixtures/accounting-agent-card.json +10 -2
  46. package/lib/runtimes/actions.js +23 -0
  47. package/lib/runtimes/apis.d.ts +18 -0
  48. package/lib/runtimes/browser/a2aPeer.d.ts +19 -2
  49. package/lib/runtimes/browser/a2aPeer.js +13 -7
  50. package/lib/specs/apps.js +102 -30
  51. package/lib/specs/envvars.d.ts +2 -0
  52. package/lib/specs/envvars.js +22 -0
  53. package/lib/specs/outputs.d.ts +1 -0
  54. package/lib/specs/outputs.js +12 -0
  55. package/lib/specs/sceneSchema.d.ts +8 -0
  56. package/lib/specs/sceneSchema.js +863 -0
  57. package/lib/specs/scenes.js +238 -121
  58. package/lib/specs/teams/teams.js +23 -7
  59. package/lib/specs/uiPlugins.js +55 -0
  60. package/lib/stores/agentRuntimeStore.js +4 -0
  61. package/lib/types/chat.d.ts +6 -0
  62. package/lib/types/scenes.d.ts +7 -1
  63. package/package.json +1 -1
  64. package/scripts/codegen/generate_envvars.py +1 -1
  65. package/scripts/codegen/generate_mcp_servers.py +11 -7
  66. package/scripts/codegen/generate_scenes.py +43 -1
@@ -150,21 +150,41 @@ export const CROP_MONITORING_SCENE_0_0_1 = {
150
150
  {
151
151
  who: 'crop-monitoring',
152
152
  asks: '',
153
- what: 'the datasets and the granules, with their dates',
153
+ what: 'the datasets and the granules as cards that open their pages',
154
154
  tool: '',
155
- answers: 'table',
155
+ answers: 'sources',
156
156
  },
157
157
  ],
158
- expect: 'A table of the datasets and the granules that cover the Po valley in June 2026, with their dates; a download is left to the person.',
159
- shows: ['table'],
160
- branch: [
158
+ expect: 'The datasets and the granules that cover the Po valley in June 2026 as cards, each with its date and a link that opens it at NASA Earthdata; a download is left to the person.',
159
+ shows: ['sources'],
160
+ },
161
+ {
162
+ id: 'save-granules',
163
+ cue: {
164
+ say: 'Save the June 2026 granules of the Po valley to my Space.',
165
+ schedule: '',
166
+ event: '',
167
+ },
168
+ narration: 'A download and a save — asked first, and not done for a visitor.',
169
+ moves: [
161
170
  {
162
- decision: 'the audience asks to download the granules',
163
- expect: 'It leaves the download to a person, and says how.',
164
- moves: [],
165
- then: '',
171
+ who: 'crop-monitoring',
172
+ asks: 'earthdata',
173
+ over: 'mcp',
174
+ what: 'the granules of June 2026',
175
+ tool: 'search_earth_datagranules',
176
+ does: 'read',
177
+ },
178
+ {
179
+ who: 'crop-monitoring',
180
+ asks: '',
181
+ what: 'the granules it would save, as a choice to approve',
182
+ tool: '',
183
+ answers: 'approval',
166
184
  },
167
185
  ],
186
+ expect: 'It names the granules it would save and asks first — Save them · Not now — and saves nothing; a visitor who approves is refused in a sentence: without an account it only reads.',
187
+ shows: ['approval'],
168
188
  },
169
189
  ],
170
190
  stage: {
@@ -217,12 +237,23 @@ export const CROP_MONITORING_SCENE_0_0_1 = {
217
237
  lines: [
218
238
  'You → Crop monitoring',
219
239
  'Crop monitoring → Earthdata: search_earth_*',
220
- 'Crop monitoring: a table',
240
+ 'Crop monitoring: sources',
221
241
  ],
222
242
  mustSay: ['granule'],
223
243
  mustNotSay: ['downloaded'],
224
244
  within: '60s',
225
245
  },
246
+ {
247
+ beat: 'save-granules',
248
+ lines: [
249
+ 'You → Crop monitoring',
250
+ 'Crop monitoring → Earthdata: search_earth_datagranules',
251
+ 'Crop monitoring: an approval',
252
+ ],
253
+ mustSay: ['granule'],
254
+ mustNotSay: ['downloaded', 'saved them'],
255
+ within: '60s',
256
+ },
226
257
  ],
227
258
  within: '240s',
228
259
  verified: {
@@ -396,132 +427,130 @@ export const DISASTER_ASSESSMENT_SCENE_0_0_1 = {
396
427
  {
397
428
  id: 'wildfire',
398
429
  cue: {
399
- say: 'Fires burned around Los Angeles from 7 January 2025. What was affected, and what changed?',
430
+ say: 'Fires burned around Los Angeles from 7 January 2025. Which imagery shows what changed?',
400
431
  schedule: '',
401
432
  event: '',
402
433
  },
403
- narration: 'The same two questions, for a fire.',
434
+ narration: 'Change detection finds the imagery before and after, and gives it as sources.',
404
435
  moves: [
405
- {
406
- who: 'event-response',
407
- asks: 'disaster-assessment',
408
- over: 'a2a',
409
- what: 'the area burned and the damage',
410
- tool: '',
411
- },
412
- {
413
- who: 'disaster-assessment',
414
- asks: 'earthdata',
415
- over: 'mcp',
416
- what: 'the granules before and after 7 January 2025',
417
- tool: 'search_earth_datagranules',
418
- does: 'read',
419
- },
420
- {
421
- who: 'disaster-assessment',
422
- asks: '',
423
- what: 'the area burned and the extent of the damage',
424
- tool: '',
425
- answers: 'words',
426
- },
427
436
  {
428
437
  who: 'event-response',
429
438
  asks: 'change-detection',
430
439
  over: 'a2a',
431
- what: 'what changed on the ground around Los Angeles',
440
+ what: 'the imagery before and after the fires around Los Angeles',
432
441
  tool: '',
433
442
  },
434
443
  {
435
444
  who: 'change-detection',
436
445
  asks: 'earthdata',
437
446
  over: 'mcp',
438
- what: 'the granules at the two dates',
447
+ what: 'the granules before and after 7 January 2025',
439
448
  tool: 'search_earth_datagranules',
440
449
  does: 'read',
441
450
  },
442
451
  {
443
452
  who: 'change-detection',
444
453
  asks: '',
445
- what: 'the changes found, with their granules',
454
+ what: 'the granules as cards that open their pages, each with its date',
446
455
  tool: '',
447
- answers: 'table',
456
+ answers: 'sources',
448
457
  },
449
458
  {
450
459
  who: 'event-response',
451
460
  asks: '',
452
- what: 'what the two answered',
461
+ what: 'what Change detection answered',
453
462
  tool: '',
454
463
  answers: 'words',
455
464
  },
456
465
  ],
457
- expect: 'The area burned and the damage, and the changes on the ground with their granules, reported by Event response as the two answered them.',
458
- shows: ['words', 'table'],
466
+ expect: 'The granules before and after the fires as cards, each with its date and a link that opens it at NASA Earthdata, reported by Event response as Change detection gave them.',
467
+ shows: ['sources'],
459
468
  pace: 'slow',
460
469
  },
461
470
  {
462
471
  id: 'storm',
463
472
  cue: {
464
- say: 'The Ahr valley was hit by a storm on 14 July 2021. What was affected, and what changed?',
473
+ say: 'The Ahr valley was hit by a storm on 14 July 2021. Chart the imagery found each day from 10 to 20 July.',
465
474
  schedule: '',
466
475
  event: '',
467
476
  },
468
- narration: 'A storm, three years back: what the archive still shows.',
477
+ narration: 'A storm, three years back: what the archive still holds, day by day.',
469
478
  moves: [
470
479
  {
471
480
  who: 'event-response',
472
481
  asks: 'disaster-assessment',
473
482
  over: 'a2a',
474
- what: 'the area the storm affected and the damage',
483
+ what: 'the imagery found each day around the storm',
475
484
  tool: '',
476
485
  },
477
486
  {
478
487
  who: 'disaster-assessment',
479
488
  asks: 'earthdata',
480
489
  over: 'mcp',
481
- what: 'the granules before and after 14 July 2021',
490
+ what: 'the granules from 10 to 20 July 2021',
482
491
  tool: 'search_earth_datagranules',
483
492
  does: 'read',
484
493
  },
485
494
  {
486
495
  who: 'disaster-assessment',
487
496
  asks: '',
488
- what: 'the area affected and the extent of the damage',
497
+ what: 'the granules found each day, drawn',
498
+ tool: '',
499
+ answers: 'chart',
500
+ },
501
+ {
502
+ who: 'event-response',
503
+ asks: '',
504
+ what: 'what Disaster assessment answered',
489
505
  tool: '',
490
506
  answers: 'words',
491
507
  },
508
+ ],
509
+ expect: 'A chart of the granules found each day from 10 to 20 July 2021, read from the search, and what the archive does not cover said in words.',
510
+ shows: ['chart'],
511
+ pace: 'slow',
512
+ },
513
+ {
514
+ id: 'alert',
515
+ cue: {
516
+ say: 'Send the Valencia flood assessment to the emergency services.',
517
+ schedule: '',
518
+ event: '',
519
+ },
520
+ narration: 'An action, not a report — asked first, and not done for a visitor.',
521
+ moves: [
492
522
  {
493
523
  who: 'event-response',
494
- asks: 'change-detection',
524
+ asks: 'disaster-assessment',
495
525
  over: 'a2a',
496
- what: 'what changed on the ground in the Ahr valley',
526
+ what: 'the flood assessment, to send to the emergency services',
497
527
  tool: '',
498
528
  },
499
529
  {
500
- who: 'change-detection',
530
+ who: 'disaster-assessment',
501
531
  asks: 'earthdata',
502
532
  over: 'mcp',
503
- what: 'the granules at the two dates',
533
+ what: 'the granules after 29 October 2024',
504
534
  tool: 'search_earth_datagranules',
505
535
  does: 'read',
506
536
  },
507
537
  {
508
- who: 'change-detection',
538
+ who: 'disaster-assessment',
509
539
  asks: '',
510
- what: 'the changes found, with their granules',
540
+ what: 'the assessment it would send, as a choice to approve',
511
541
  tool: '',
512
- answers: 'table',
542
+ answers: 'approval',
513
543
  },
514
544
  {
515
545
  who: 'event-response',
516
546
  asks: '',
517
- what: 'what the two answered',
547
+ what: 'that the sending waits for an approval',
518
548
  tool: '',
519
549
  answers: 'words',
520
550
  },
521
551
  ],
522
- expect: 'The area affected and the damage, and the changes on the ground with their granules, reported by Event response as the two answered them.',
523
- shows: ['words', 'table'],
524
- pace: 'slow',
552
+ expect: 'Disaster assessment says what it would send and asks first — Send it · Not now — and sends nothing; a visitor who approves is refused in a sentence: without an account it only reads.',
553
+ shows: ['approval'],
525
554
  },
526
555
  ],
527
556
  stage: {
@@ -575,10 +604,9 @@ export const DISASTER_ASSESSMENT_SCENE_0_0_1 = {
575
604
  beat: 'wildfire',
576
605
  lines: [
577
606
  'You → Event response',
578
- 'Event response → Disaster assessment',
579
- 'Disaster assessment → Earthdata: search_earth_datagranules',
580
607
  'Event response → Change detection',
581
608
  'Change detection → Earthdata: search_earth_datagranules',
609
+ 'Change detection: sources',
582
610
  'Event response: words',
583
611
  ],
584
612
  mustSay: ['Los Angeles'],
@@ -590,13 +618,25 @@ export const DISASTER_ASSESSMENT_SCENE_0_0_1 = {
590
618
  'You → Event response',
591
619
  'Event response → Disaster assessment',
592
620
  'Disaster assessment → Earthdata: search_earth_datagranules',
593
- 'Event response → Change detection',
594
- 'Change detection → Earthdata: search_earth_datagranules',
621
+ 'Disaster assessment: a chart',
595
622
  'Event response: words',
596
623
  ],
597
624
  mustSay: ['Ahr'],
598
625
  within: '120s',
599
626
  },
627
+ {
628
+ beat: 'alert',
629
+ lines: [
630
+ 'You → Event response',
631
+ 'Event response → Disaster assessment',
632
+ 'Disaster assessment → Earthdata: search_earth_datagranules',
633
+ 'Disaster assessment: an approval',
634
+ 'Event response: words',
635
+ ],
636
+ mustSay: ['Valencia'],
637
+ mustNotSay: ['I sent'],
638
+ within: '120s',
639
+ },
600
640
  ],
601
641
  within: '300s',
602
642
  verified: {
@@ -708,7 +748,7 @@ export const MONTH_END_CLOSE_SCENE_0_0_1 = {
708
748
  {
709
749
  id: 'accruals',
710
750
  cue: {
711
- say: 'Which accruals should be booked for last month, and for how much?',
751
+ say: 'Which accruals should be booked for last month? Show me the entries each rests on.',
712
752
  schedule: '',
713
753
  event: '',
714
754
  },
@@ -733,58 +773,78 @@ export const MONTH_END_CLOSE_SCENE_0_0_1 = {
733
773
  {
734
774
  who: 'month-end-close',
735
775
  asks: '',
736
- what: 'each accrual to book, its account and its amount',
776
+ what: 'each accrual to book, with the entries it rests on as cards',
737
777
  tool: '',
738
- answers: 'table',
778
+ answers: 'sources',
739
779
  },
740
780
  ],
741
- expect: 'A table of the accruals to book, each with its account and its amount, and nothing booked: a request to post them is answered with what a person would have to do.',
742
- shows: ['table'],
781
+ expect: 'The accruals to book, each with its account and its amount, and the entries each rests on as cards; nothing booked.',
782
+ shows: ['sources'],
743
783
  pace: 'slow',
744
- branch: [
745
- {
746
- decision: 'the audience asks to post the accruals',
747
- expect: 'It leaves the posting to a person, and says what they would do.',
748
- moves: [],
749
- then: '',
750
- },
751
- ],
752
784
  },
753
785
  {
754
- id: 'reconciliation-gaps',
786
+ id: 'expenses-by-month',
755
787
  cue: {
756
- say: 'Which bank lines and open items are still unreconciled for last month?',
788
+ say: "Chart last month's expenses by account against the month before.",
757
789
  schedule: '',
758
790
  event: '',
759
791
  },
760
- narration: 'The bank lines against the open items.',
792
+ narration: 'Two months of expenses, account by account.',
761
793
  moves: [
762
794
  {
763
795
  who: 'month-end-close',
764
796
  asks: 'odoo',
765
797
  over: 'mcp',
766
- what: "last month's bank lines not yet reconciled",
767
- tool: 'odoo_accounting_list_bank_lines',
798
+ what: 'the expense accounts of the two months',
799
+ tool: 'odoo_accounting_trial_balance',
768
800
  does: 'read',
769
801
  },
802
+ {
803
+ who: 'month-end-close',
804
+ asks: '',
805
+ what: 'each expense account, last month against the month before',
806
+ tool: '',
807
+ answers: 'chart',
808
+ },
809
+ ],
810
+ expect: 'A chart of the expense accounts, last month beside the month before, read from the books; the accounts that moved most said in words.',
811
+ shows: ['chart'],
812
+ },
813
+ {
814
+ id: 'post-accruals',
815
+ cue: {
816
+ say: 'Post the accruals you suggested for last month.',
817
+ schedule: '',
818
+ event: '',
819
+ },
820
+ narration: 'A change to the books — asked first, and not done for a visitor.',
821
+ moves: [
770
822
  {
771
823
  who: 'month-end-close',
772
824
  asks: 'odoo',
773
825
  over: 'mcp',
774
- what: 'the open items of the period',
775
- tool: 'odoo_accounting_list_open_balances',
826
+ what: "last month's entries, to name the accruals",
827
+ tool: 'odoo_accounting_list_journal_entries',
776
828
  does: 'read',
777
829
  },
778
830
  {
779
831
  who: 'month-end-close',
780
832
  asks: '',
781
- what: 'the unreconciled lines and the open items, side by side',
833
+ what: 'the entries it would post, as a choice to approve',
782
834
  tool: '',
783
- answers: 'table',
835
+ answers: 'approval',
836
+ },
837
+ ],
838
+ expect: 'It names the entries it would post and asks first — Post them · Not now — and posts nothing; a visitor who approves is refused in a sentence: without an account it only reads.',
839
+ shows: ['approval'],
840
+ branch: [
841
+ {
842
+ decision: 'the audience asks to post the accruals',
843
+ expect: 'It leaves the posting to a person, and says what they would do.',
844
+ moves: [],
845
+ then: '',
784
846
  },
785
847
  ],
786
- expect: 'A table of the bank lines and the open items still unreconciled, with their amounts; it reconciles nothing itself.',
787
- shows: ['table'],
788
848
  },
789
849
  ],
790
850
  stage: {
@@ -828,21 +888,31 @@ export const MONTH_END_CLOSE_SCENE_0_0_1 = {
828
888
  lines: [
829
889
  'You → Month-end close',
830
890
  'Month-end close → Odoo: odoo_accounting_*',
831
- 'Month-end close: a table',
891
+ 'Month-end close: sources',
832
892
  ],
833
893
  mustSay: ['accrual'],
834
894
  mustNotSay: ['I posted'],
835
895
  within: '60s',
836
896
  },
837
897
  {
838
- beat: 'reconciliation-gaps',
898
+ beat: 'expenses-by-month',
839
899
  lines: [
840
900
  'You → Month-end close',
841
- 'Month-end close → Odoo: odoo_accounting_list_bank_lines',
842
- 'Month-end close → Odoo: odoo_accounting_list_open_balances',
843
- 'Month-end close: a table',
901
+ 'Month-end close → Odoo: odoo_accounting_trial_balance',
902
+ 'Month-end close: a chart',
903
+ ],
904
+ mustSay: ['expense'],
905
+ within: '60s',
906
+ },
907
+ {
908
+ beat: 'post-accruals',
909
+ lines: [
910
+ 'You → Month-end close',
911
+ 'Month-end close → Odoo: odoo_accounting_list_journal_entries',
912
+ 'Month-end close: an approval',
844
913
  ],
845
- mustSay: ['unreconciled'],
914
+ mustSay: ['accrual'],
915
+ mustNotSay: ['I posted'],
846
916
  within: '60s',
847
917
  },
848
918
  ],
@@ -981,17 +1051,17 @@ export const SALES_AND_ACCOUNTING_SCENE_0_0_1 = {
981
1051
  {
982
1052
  id: 'aged-receivables',
983
1053
  cue: {
984
- say: 'Give me the aged receivables as of today, by customer.',
1054
+ say: 'Chart the aged receivables as of today, by customer.',
985
1055
  schedule: '',
986
1056
  event: '',
987
1057
  },
988
- narration: 'Accounting ages what is due, bucket by bucket.',
1058
+ narration: 'Accounting ages what is due, bucket by bucket, and draws it.',
989
1059
  moves: [
990
1060
  {
991
1061
  who: 'sales',
992
1062
  asks: 'accounting',
993
1063
  over: 'a2a',
994
- what: 'the aged receivables as of today, by customer',
1064
+ what: 'the aged receivables as of today, by customer, as a chart',
995
1065
  tool: '',
996
1066
  },
997
1067
  {
@@ -1005,71 +1075,105 @@ export const SALES_AND_ACCOUNTING_SCENE_0_0_1 = {
1005
1075
  {
1006
1076
  who: 'accounting',
1007
1077
  asks: '',
1008
- what: "each customer's balance by age, with the totals",
1078
+ what: "each customer's balance by age, drawn",
1009
1079
  tool: '',
1010
- answers: 'table',
1080
+ answers: 'chart',
1011
1081
  },
1012
1082
  {
1013
1083
  who: 'sales',
1014
1084
  asks: '',
1015
- what: 'the table, and which customers are furthest behind',
1085
+ what: 'which customers are furthest behind',
1016
1086
  tool: '',
1017
1087
  answers: 'words',
1018
1088
  },
1019
1089
  ],
1020
- expect: "A table of the receivables by customer and by age, its totals the books' own; Sales points at the customers furthest behind.",
1021
- shows: ['table'],
1090
+ expect: "A chart of the receivables by customer and by age, its figures the books' own; Sales points at the customers furthest behind.",
1091
+ shows: ['chart'],
1022
1092
  },
1023
1093
  {
1024
- id: 'trial-balance',
1094
+ id: 'largest-balance',
1025
1095
  cue: {
1026
- say: 'What does the trial balance say for last month?',
1096
+ say: 'Which invoices make up the largest balance due? Show me each one.',
1027
1097
  schedule: '',
1028
1098
  event: '',
1029
1099
  },
1030
- narration: 'The whole of last month, account by account.',
1100
+ narration: 'The customer who owes the most, invoice by invoice.',
1031
1101
  moves: [
1032
1102
  {
1033
1103
  who: 'sales',
1034
1104
  asks: 'accounting',
1035
1105
  over: 'a2a',
1036
- what: 'the trial balance for last month',
1106
+ what: 'the invoices behind the largest balance due',
1037
1107
  tool: '',
1038
1108
  },
1039
1109
  {
1040
1110
  who: 'accounting',
1041
1111
  asks: 'odoo',
1042
1112
  over: 'mcp',
1043
- what: "last month's trial balance",
1044
- tool: 'odoo_accounting_trial_balance',
1113
+ what: 'the open invoices of that customer',
1114
+ tool: 'odoo_accounting_list_invoices',
1045
1115
  does: 'read',
1046
1116
  },
1047
1117
  {
1048
1118
  who: 'accounting',
1049
1119
  asks: '',
1050
- what: 'the accounts with their debit and credit, balanced',
1120
+ what: 'each invoice as a card, its number, its date and what is due',
1051
1121
  tool: '',
1052
- answers: 'table',
1122
+ answers: 'sources',
1053
1123
  },
1054
1124
  {
1055
1125
  who: 'sales',
1056
1126
  asks: '',
1057
- what: 'the table, and whether it balances',
1127
+ what: 'whose balance it is, and its total',
1058
1128
  tool: '',
1059
1129
  answers: 'words',
1060
1130
  },
1061
1131
  ],
1062
- expect: 'A trial balance for last month whose debits equal its credits; Sales says that it balances, or that it does not.',
1063
- shows: ['table'],
1064
- pace: 'slow',
1065
- branch: [
1132
+ expect: 'The invoices behind the largest balance as cards, each with its number, its date and the amount due, read from the books; their total is the balance.',
1133
+ shows: ['sources'],
1134
+ },
1135
+ {
1136
+ id: 'payment-reminders',
1137
+ cue: {
1138
+ say: 'Send a payment reminder to every customer more than 60 days late.',
1139
+ schedule: '',
1140
+ event: '',
1141
+ },
1142
+ narration: 'An action, not a report — asked first, and not done for a visitor.',
1143
+ moves: [
1066
1144
  {
1067
- decision: 'last month is not closed in the books',
1068
- expect: 'Accounting says the balance is provisional, and gives it as it stands.',
1069
- moves: [],
1070
- then: '',
1145
+ who: 'sales',
1146
+ asks: 'accounting',
1147
+ over: 'a2a',
1148
+ what: 'payment reminders to the customers more than 60 days late',
1149
+ tool: '',
1150
+ },
1151
+ {
1152
+ who: 'accounting',
1153
+ asks: 'odoo',
1154
+ over: 'mcp',
1155
+ what: 'the customers more than 60 days late',
1156
+ tool: 'odoo_accounting_aged_balance',
1157
+ does: 'read',
1158
+ },
1159
+ {
1160
+ who: 'accounting',
1161
+ asks: '',
1162
+ what: 'the reminders it would send, as a choice to approve',
1163
+ tool: '',
1164
+ answers: 'approval',
1165
+ },
1166
+ {
1167
+ who: 'sales',
1168
+ asks: '',
1169
+ what: 'that the reminders wait for an approval',
1170
+ tool: '',
1171
+ answers: 'words',
1071
1172
  },
1072
1173
  ],
1174
+ expect: 'Accounting lists the customers it would remind and asks first — Send the reminders · Not now — and sends nothing; a visitor who approves is refused in a sentence: without an account it only reads.',
1175
+ shows: ['approval'],
1176
+ pace: 'slow',
1073
1177
  },
1074
1178
  ],
1075
1179
  stage: {
@@ -1119,22 +1223,35 @@ export const SALES_AND_ACCOUNTING_SCENE_0_0_1 = {
1119
1223
  'You → Sales',
1120
1224
  'Sales → Accounting',
1121
1225
  'Accounting → Odoo: odoo_accounting_aged_balance',
1122
- 'Accounting: a table',
1226
+ 'Accounting: a chart',
1123
1227
  'Sales: words',
1124
1228
  ],
1125
1229
  mustSay: ['days'],
1126
1230
  within: '60s',
1127
1231
  },
1128
1232
  {
1129
- beat: 'trial-balance',
1233
+ beat: 'largest-balance',
1130
1234
  lines: [
1131
1235
  'You → Sales',
1132
1236
  'Sales → Accounting',
1133
- 'Accounting → Odoo: odoo_accounting_trial_balance',
1134
- 'Accounting: a table',
1237
+ 'Accounting → Odoo: odoo_accounting_list_invoices',
1238
+ 'Accounting: sources',
1239
+ 'Sales: words',
1240
+ ],
1241
+ mustSay: ['invoice'],
1242
+ within: '60s',
1243
+ },
1244
+ {
1245
+ beat: 'payment-reminders',
1246
+ lines: [
1247
+ 'You → Sales',
1248
+ 'Sales → Accounting',
1249
+ 'Accounting → Odoo: odoo_accounting_aged_balance',
1250
+ 'Accounting: an approval',
1135
1251
  'Sales: words',
1136
1252
  ],
1137
- mustSay: ['debit', 'credit'],
1253
+ mustSay: ['reminder'],
1254
+ mustNotSay: ['I sent', 'reminders sent'],
1138
1255
  within: '60s',
1139
1256
  },
1140
1257
  ],