@datalayer/agent-runtimes 1.3.87 → 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 (61) 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/AnswerSurfaces.d.ts +56 -0
  10. package/lib/components/teams/AnswerSurfaces.js +27 -0
  11. package/lib/components/teams/AnswerSurfacesView.d.ts +14 -0
  12. package/lib/components/teams/AnswerSurfacesView.js +30 -0
  13. package/lib/components/teams/index.d.ts +1 -0
  14. package/lib/components/teams/index.js +1 -0
  15. package/lib/components/teams/useA2ATeam.d.ts +56 -2
  16. package/lib/components/teams/useA2ATeam.js +122 -3
  17. package/lib/hooks/useAgentRuntimes.d.ts +13 -0
  18. package/lib/hooks/useAgentRuntimes.js +11 -1
  19. package/lib/loop/apps/AppFeedback.js +11 -2
  20. package/lib/loop/apps/AppRenderer.d.ts +13 -1
  21. package/lib/loop/apps/AppRenderer.js +34 -1
  22. package/lib/loop/apps/AppRuntimePlugins.d.ts +8 -0
  23. package/lib/loop/apps/AppRuntimePlugins.js +87 -0
  24. package/lib/loop/apps/feedback.d.ts +7 -0
  25. package/lib/loop/apps/feedback.js +3 -0
  26. package/lib/loop/apps/pluginPair.d.ts +60 -0
  27. package/lib/loop/apps/pluginPair.js +44 -0
  28. package/lib/loop/apps/threads.d.ts +35 -0
  29. package/lib/loop/apps/threads.js +79 -0
  30. package/lib/loop/embed/LoopEmbed.d.ts +4 -3
  31. package/lib/loop/embed/hostBridge.d.ts +27 -0
  32. package/lib/loop/embed/hostBridge.js +47 -0
  33. package/lib/loop/index.d.ts +1 -1
  34. package/lib/loop/index.js +1 -1
  35. package/lib/loop/plugins/agent-capacity/index.d.ts +7 -0
  36. package/lib/loop/plugins/agent-capacity/index.js +3 -2
  37. package/lib/loop/plugins/agents/DatalayerAgentBridge.js +11 -0
  38. package/lib/loop/plugins/agents/appLaunch.d.ts +15 -0
  39. package/lib/loop/plugins/agents/appLaunch.js +28 -0
  40. package/lib/loop/plugins/chat/ChatView.js +177 -109
  41. package/lib/loop/shell/LoopWorkspace.d.ts +3 -3
  42. package/lib/loop/shell/LoopWorkspace.js +1 -1
  43. package/lib/runtimes/__tests__/fixtures/accounting-agent-card.json +10 -2
  44. package/lib/runtimes/actions.js +23 -0
  45. package/lib/runtimes/apis.d.ts +18 -0
  46. package/lib/runtimes/browser/a2aPeer.d.ts +19 -2
  47. package/lib/runtimes/browser/a2aPeer.js +13 -7
  48. package/lib/specs/apps.js +102 -30
  49. package/lib/specs/envvars.d.ts +2 -0
  50. package/lib/specs/envvars.js +22 -0
  51. package/lib/specs/outputs.d.ts +1 -0
  52. package/lib/specs/outputs.js +12 -0
  53. package/lib/specs/sceneSchema.js +12 -1
  54. package/lib/specs/scenes.js +238 -121
  55. package/lib/specs/teams/teams.js +23 -7
  56. package/lib/specs/uiPlugins.js +55 -0
  57. package/lib/stores/agentRuntimeStore.js +4 -0
  58. package/lib/types/chat.d.ts +6 -0
  59. package/lib/types/scenes.d.ts +7 -1
  60. package/package.json +1 -1
  61. package/scripts/codegen/generate_mcp_servers.py +11 -7
@@ -85,6 +85,21 @@ export type A2APeerToolStep = {
85
85
  export declare const TEXT_MEDIA_TYPES: readonly string[];
86
86
  /** A Jupyter notebook, as A2A carries it. */
87
87
  export declare const NOTEBOOK_MEDIA_TYPE = "application/x-ipynb+json";
88
+ /**
89
+ * Components of the catalog, as A2A carries them: one A2UI surface per
90
+ * artifact (`{surfaceId, catalogId, title, messages}`), A2UI's media type.
91
+ */
92
+ export declare const A2UI_MEDIA_TYPE = "application/json+a2ui";
93
+ /**
94
+ * A button pressed on an answer's surface, sent back with the reader's turn:
95
+ * its name and what choosing it does (`payload.does`). The runtime reads it
96
+ * from the message's metadata (`loop.action`): one that does more than read
97
+ * is refused to a visitor in a sentence, before any model runs.
98
+ */
99
+ export type A2APeerAction = {
100
+ name: string;
101
+ payload: Record<string, unknown>;
102
+ };
88
103
  /**
89
104
  * What a peer gave besides words: one part of an artifact, by its media type.
90
105
  *
@@ -135,8 +150,8 @@ export declare function artifactsOf(artifact: {
135
150
  name?: string;
136
151
  parts?: Part[];
137
152
  } | undefined): A2APeerArtifact[];
138
- /** A user's message of one text part, as the SDK's 1.x types write it. */
139
- export declare function textMessage(text: string): Message;
153
+ /** A user's message of one text part, as the SDK's 1.x types write it; a pressed button's action in its metadata. */
154
+ export declare function textMessage(text: string, action?: A2APeerAction): Message;
140
155
  /**
141
156
  * What a working status says while the peer works: in a few words, and the
142
157
  * tool step when it is one.
@@ -159,6 +174,8 @@ export type AskA2APeerOptions = {
159
174
  * the peer answers in words alone.
160
175
  */
161
176
  accept?: readonly string[];
177
+ /** The button pressed on one of its answers' surfaces, when this request is one. */
178
+ action?: A2APeerAction;
162
179
  };
163
180
  /**
164
181
  * Ask a peer once, streaming the task, and return its answer.
@@ -92,9 +92,15 @@ export const TEXT_MEDIA_TYPES = [
92
92
  ];
93
93
  /** A Jupyter notebook, as A2A carries it. */
94
94
  export const NOTEBOOK_MEDIA_TYPE = 'application/x-ipynb+json';
95
+ /**
96
+ * Components of the catalog, as A2A carries them: one A2UI surface per
97
+ * artifact (`{surfaceId, catalogId, title, messages}`), A2UI's media type.
98
+ */
99
+ export const A2UI_MEDIA_TYPE = 'application/json+a2ui';
95
100
  /** What a format is, in words, for a model reading a tool's description. */
96
101
  const FORMAT_NAMES = {
97
102
  [NOTEBOOK_MEDIA_TYPE]: 'a Jupyter notebook',
103
+ [A2UI_MEDIA_TYPE]: 'components drawn for the person: the sources as cards, a table, a chart, a choice of buttons',
98
104
  };
99
105
  /** The text of a message's or an artifact's parts. */
100
106
  export function textOf(parts) {
@@ -131,8 +137,8 @@ export function artifactsOf(artifact) {
131
137
  }
132
138
  return found;
133
139
  }
134
- /** A user's message of one text part, as the SDK's 1.x types write it. */
135
- export function textMessage(text) {
140
+ /** A user's message of one text part, as the SDK's 1.x types write it; a pressed button's action in its metadata. */
141
+ export function textMessage(text, action) {
136
142
  return {
137
143
  messageId: globalThis.crypto.randomUUID(),
138
144
  contextId: '',
@@ -146,7 +152,7 @@ export function textMessage(text) {
146
152
  mediaType: '',
147
153
  },
148
154
  ],
149
- metadata: undefined,
155
+ metadata: action ? { loop: { action } } : undefined,
150
156
  extensions: [],
151
157
  referenceTaskIds: [],
152
158
  };
@@ -205,14 +211,14 @@ const ENDED_BADLY = {
205
211
  * completed is thrown, with what the peer said.
206
212
  */
207
213
  export async function askA2APeer(peer, request, options = {}) {
208
- const { signal, onEvent, accept } = options;
214
+ const { signal, onEvent, accept, action } = options;
209
215
  onEvent?.({
210
216
  phase: 'asked',
211
217
  request,
212
218
  ...(accept?.length ? { accept: [...accept] } : {}),
213
219
  });
214
220
  try {
215
- return await streamTask(peer, request, signal, onEvent, accept);
221
+ return await streamTask(peer, request, signal, onEvent, accept, action);
216
222
  }
217
223
  catch (reason) {
218
224
  const error = reason instanceof Error ? reason.message : String(reason);
@@ -220,7 +226,7 @@ export async function askA2APeer(peer, request, options = {}) {
220
226
  throw reason;
221
227
  }
222
228
  }
223
- async function streamTask(peer, request, signal, onEvent, accept) {
229
+ async function streamTask(peer, request, signal, onEvent, accept, action) {
224
230
  const texts = new Map();
225
231
  // What it gave besides words, by artifact: the last chunk says it whole.
226
232
  const given = new Map();
@@ -229,7 +235,7 @@ async function streamTask(peer, request, signal, onEvent, accept) {
229
235
  let ended;
230
236
  const stream = peer.client.sendMessageStream({
231
237
  tenant: '',
232
- message: textMessage(request),
238
+ message: textMessage(request, action),
233
239
  configuration: accept?.length
234
240
  ? {
235
241
  acceptedOutputModes: [...accept],
package/lib/specs/apps.js CHANGED
@@ -80,7 +80,11 @@ export const ACCOUNTING_APP_0_0_1 = {
80
80
  language: '',
81
81
  where: 'auto',
82
82
  },
83
- outputs: ['text/markdown', 'application/x-ipynb+json'],
83
+ outputs: [
84
+ 'text/markdown',
85
+ 'application/x-ipynb+json',
86
+ 'application/json+a2ui',
87
+ ],
84
88
  },
85
89
  tests: {
86
90
  readyAt: 0.8,
@@ -225,7 +229,11 @@ export const CHANGE_DETECTION_APP_0_0_1 = {
225
229
  language: '',
226
230
  where: 'auto',
227
231
  },
228
- outputs: ['text/markdown', 'application/x-ipynb+json'],
232
+ outputs: [
233
+ 'text/markdown',
234
+ 'application/x-ipynb+json',
235
+ 'application/json+a2ui',
236
+ ],
229
237
  },
230
238
  tests: {
231
239
  readyAt: 0.8,
@@ -357,6 +365,10 @@ export const CROP_MONITORING_APP_0_0_1 = {
357
365
  label: 'Imagery available',
358
366
  message: 'Which datasets and granules cover the Po valley for June 2026?',
359
367
  },
368
+ {
369
+ label: 'Save the granules',
370
+ message: 'Save the June 2026 granules of the Po valley to my Space.',
371
+ },
360
372
  ],
361
373
  commands: [],
362
374
  modes: [],
@@ -373,7 +385,11 @@ export const CROP_MONITORING_APP_0_0_1 = {
373
385
  language: '',
374
386
  where: 'auto',
375
387
  },
376
- outputs: ['text/markdown', 'application/x-ipynb+json'],
388
+ outputs: [
389
+ 'text/markdown',
390
+ 'application/x-ipynb+json',
391
+ 'application/json+a2ui',
392
+ ],
377
393
  },
378
394
  tests: {
379
395
  readyAt: 0.8,
@@ -945,7 +961,11 @@ export const DISASTER_ASSESSMENT_APP_0_0_1 = {
945
961
  language: '',
946
962
  where: 'auto',
947
963
  },
948
- outputs: ['text/markdown', 'application/x-ipynb+json'],
964
+ outputs: [
965
+ 'text/markdown',
966
+ 'application/x-ipynb+json',
967
+ 'application/json+a2ui',
968
+ ],
949
969
  },
950
970
  tests: {
951
971
  readyAt: 0.8,
@@ -1025,7 +1045,7 @@ export const EVENT_RESPONSE_APP_0_0_1 = {
1025
1045
  owner: 'Datalayer <info@datalayer.io>',
1026
1046
  agent: 'worker-event-response:0.0.1',
1027
1047
  team: '',
1028
- instructions: 'You respond to events. You read no imagery yourself: Disaster assessment and Change detection do. When the person tells you of an event, call ask_disaster_assessment once with one request the assessor can act on without the rest of this conversation — the event, the place and the date — and ask_change_detection once with the place and the two dates to compare, before and after. Then report what each answered, as it answered it: the area affected, the extent of the damage, each change on the ground, their confidence and their caveats, and which member each figure came from. Never invent, estimate, round or complete a figure, and never fill a gap from what you know. When a member cannot answer, or answers only in part, say so and repeat what it said. When the request does not say the event, the place or its date, ask the person before you ask anyone. You change nothing anywhere: you ask, and you report.',
1048
+ instructions: 'You respond to events. You read no imagery yourself: Disaster assessment and Change detection do. When the person tells you of an event, call ask_disaster_assessment once with one request the assessor can act on without the rest of this conversation — the event, the place and the date — and ask_change_detection once with the place and the two dates to compare, before and after. Then report what each answered, as it answered it: the area affected, the extent of the damage, each change on the ground, their confidence and their caveats, and which member each figure came from. Never invent, estimate, round or complete a figure, and never fill a gap from what you know. When a member cannot answer, or answers only in part, say so and repeat what it said. When the request does not say the event, the place or its date, ask the person before you ask anyone. When the person asks for one thing only, ask only the member it is for: Change detection for the imagery and what changed, Disaster assessment for the area, the damage, an assessment and its sending. Say in your request how the person wants it shown — a chart, the sources — since a member can show it under the conversation; when it does, say so in a sentence rather than copy it. Never say a thing was sent or done unless the member says it was. You change nothing anywhere: you ask, and you report.',
1029
1049
  model: '',
1030
1050
  skills: [],
1031
1051
  backendTools: [],
@@ -1053,11 +1073,15 @@ export const EVENT_RESPONSE_APP_0_0_1 = {
1053
1073
  },
1054
1074
  {
1055
1075
  label: 'Wildfire',
1056
- message: 'Fires burned around Los Angeles from 7 January 2025. What was affected, and what changed?',
1076
+ message: 'Fires burned around Los Angeles from 7 January 2025. Which imagery shows what changed?',
1057
1077
  },
1058
1078
  {
1059
1079
  label: 'Storm',
1060
- message: 'The Ahr valley was hit by a storm on 14 July 2021. What was affected, and what changed?',
1080
+ message: 'The Ahr valley was hit by a storm on 14 July 2021. Chart the imagery found each day from 10 to 20 July.',
1081
+ },
1082
+ {
1083
+ label: 'Alert',
1084
+ message: 'Send the Valencia flood assessment to the emergency services.',
1061
1085
  },
1062
1086
  ],
1063
1087
  commands: [],
@@ -1606,11 +1630,15 @@ export const MONTH_END_CLOSE_APP_0_0_1 = {
1606
1630
  },
1607
1631
  {
1608
1632
  label: 'Accruals',
1609
- message: 'Which accruals should be booked for last month, and for how much?',
1633
+ message: 'Which accruals should be booked for last month? Show me the entries each rests on.',
1634
+ },
1635
+ {
1636
+ label: 'Expenses by month',
1637
+ message: "Chart last month's expenses by account against the month before.",
1610
1638
  },
1611
1639
  {
1612
- label: 'Reconciliation gaps',
1613
- message: 'Which bank lines and open items are still unreconciled for last month?',
1640
+ label: 'Post the accruals',
1641
+ message: 'Post the accruals you suggested for last month.',
1614
1642
  },
1615
1643
  ],
1616
1644
  commands: [],
@@ -1628,7 +1656,11 @@ export const MONTH_END_CLOSE_APP_0_0_1 = {
1628
1656
  language: '',
1629
1657
  where: 'auto',
1630
1658
  },
1631
- outputs: ['text/markdown', 'application/x-ipynb+json'],
1659
+ outputs: [
1660
+ 'text/markdown',
1661
+ 'application/x-ipynb+json',
1662
+ 'application/json+a2ui',
1663
+ ],
1632
1664
  },
1633
1665
  tests: {
1634
1666
  readyAt: 0.8,
@@ -2506,7 +2538,7 @@ export const SALES_APP_0_0_1 = {
2506
2538
  owner: 'Datalayer <info@datalayer.io>',
2507
2539
  agent: 'worker-sales-pipeline-board-report:0.0.1',
2508
2540
  team: '',
2509
- 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.',
2541
+ 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. Say in your request how the person wants it shown — a chart, the invoices one by one — since Accounting can show it under the conversation; when it does, say so in a sentence rather than copy it. A request to do something rather than to read — send, remind, post — goes to Accounting the same way, and you repeat what it answered: never say a thing was done unless Accounting says it was. You change nothing anywhere: you ask, and you report.',
2510
2542
  model: '',
2511
2543
  skills: [],
2512
2544
  backendTools: [],
@@ -2534,11 +2566,15 @@ export const SALES_APP_0_0_1 = {
2534
2566
  },
2535
2567
  {
2536
2568
  label: 'Aged receivables',
2537
- message: 'Give me the aged receivables as of today, by customer.',
2569
+ message: 'Chart the aged receivables as of today, by customer.',
2538
2570
  },
2539
2571
  {
2540
- label: 'Trial balance',
2541
- message: 'What does the trial balance say for last month?',
2572
+ label: 'Largest balance',
2573
+ message: 'Which invoices make up the largest balance due? Show me each one.',
2574
+ },
2575
+ {
2576
+ label: 'Payment reminders',
2577
+ message: 'Send a payment reminder to every customer more than 60 days late.',
2542
2578
  },
2543
2579
  ],
2544
2580
  commands: [],
@@ -3495,7 +3531,11 @@ export const APP_SOURCES = {
3495
3531
  },
3496
3532
  ],
3497
3533
  assistant: 'wizard',
3498
- outputs: ['text/markdown', 'application/x-ipynb+json'],
3534
+ outputs: [
3535
+ 'text/markdown',
3536
+ 'application/x-ipynb+json',
3537
+ 'application/json+a2ui',
3538
+ ],
3499
3539
  },
3500
3540
  tests: {
3501
3541
  cases: [
@@ -3580,7 +3620,11 @@ export const APP_SOURCES = {
3580
3620
  },
3581
3621
  ],
3582
3622
  assistant: 'cat',
3583
- outputs: ['text/markdown', 'application/x-ipynb+json'],
3623
+ outputs: [
3624
+ 'text/markdown',
3625
+ 'application/x-ipynb+json',
3626
+ 'application/json+a2ui',
3627
+ ],
3584
3628
  },
3585
3629
  tests: {
3586
3630
  cases: [
@@ -3668,9 +3712,17 @@ export const APP_SOURCES = {
3668
3712
  label: 'Imagery available',
3669
3713
  message: 'Which datasets and granules cover the Po valley for June 2026?',
3670
3714
  },
3715
+ {
3716
+ label: 'Save the granules',
3717
+ message: 'Save the June 2026 granules of the Po valley to my Space.',
3718
+ },
3671
3719
  ],
3672
3720
  assistant: 'eyes',
3673
- outputs: ['text/markdown', 'application/x-ipynb+json'],
3721
+ outputs: [
3722
+ 'text/markdown',
3723
+ 'application/x-ipynb+json',
3724
+ 'application/json+a2ui',
3725
+ ],
3674
3726
  },
3675
3727
  tests: {
3676
3728
  cases: [
@@ -3994,7 +4046,11 @@ export const APP_SOURCES = {
3994
4046
  },
3995
4047
  ],
3996
4048
  assistant: 'wizard',
3997
- outputs: ['text/markdown', 'application/x-ipynb+json'],
4049
+ outputs: [
4050
+ 'text/markdown',
4051
+ 'application/x-ipynb+json',
4052
+ 'application/json+a2ui',
4053
+ ],
3998
4054
  },
3999
4055
  tests: {
4000
4056
  cases: [
@@ -4048,7 +4104,7 @@ export const APP_SOURCES = {
4048
4104
  description: 'Takes word of a live event — a flood, a fire, a storm — asks Disaster assessment for the area affected and the damage and Change detection for what changed on the ground, each over A2A, and reports what they answered, adding no figure of its own.',
4049
4105
  owner: 'Datalayer <info@datalayer.io>',
4050
4106
  agent: 'worker-event-response:0.0.1',
4051
- instructions: 'You respond to events. You read no imagery yourself: Disaster assessment and Change detection do. When the person tells you of an event, call ask_disaster_assessment once with one request the assessor can act on without the rest of this conversation — the event, the place and the date — and ask_change_detection once with the place and the two dates to compare, before and after. Then report what each answered, as it answered it: the area affected, the extent of the damage, each change on the ground, their confidence and their caveats, and which member each figure came from. Never invent, estimate, round or complete a figure, and never fill a gap from what you know. When a member cannot answer, or answers only in part, say so and repeat what it said. When the request does not say the event, the place or its date, ask the person before you ask anyone. You change nothing anywhere: you ask, and you report.',
4107
+ instructions: 'You respond to events. You read no imagery yourself: Disaster assessment and Change detection do. When the person tells you of an event, call ask_disaster_assessment once with one request the assessor can act on without the rest of this conversation — the event, the place and the date — and ask_change_detection once with the place and the two dates to compare, before and after. Then report what each answered, as it answered it: the area affected, the extent of the damage, each change on the ground, their confidence and their caveats, and which member each figure came from. Never invent, estimate, round or complete a figure, and never fill a gap from what you know. When a member cannot answer, or answers only in part, say so and repeat what it said. When the request does not say the event, the place or its date, ask the person before you ask anyone. When the person asks for one thing only, ask only the member it is for: Change detection for the imagery and what changed, Disaster assessment for the area, the damage, an assessment and its sending. Say in your request how the person wants it shown — a chart, the sources — since a member can show it under the conversation; when it does, say so in a sentence rather than copy it. Never say a thing was sent or done unless the member says it was. You change nothing anywhere: you ask, and you report.',
4052
4108
  interface: {
4053
4109
  accent: 'rose',
4054
4110
  welcome: "Tell me of an event — a flood, a fire, a storm — where and when, and I'll get the area affected and the damage from Disaster assessment and what changed on the ground from Change detection.",
@@ -4059,11 +4115,15 @@ export const APP_SOURCES = {
4059
4115
  },
4060
4116
  {
4061
4117
  label: 'Wildfire',
4062
- message: 'Fires burned around Los Angeles from 7 January 2025. What was affected, and what changed?',
4118
+ message: 'Fires burned around Los Angeles from 7 January 2025. Which imagery shows what changed?',
4063
4119
  },
4064
4120
  {
4065
4121
  label: 'Storm',
4066
- message: 'The Ahr valley was hit by a storm on 14 July 2021. What was affected, and what changed?',
4122
+ message: 'The Ahr valley was hit by a storm on 14 July 2021. Chart the imagery found each day from 10 to 20 July.',
4123
+ },
4124
+ {
4125
+ label: 'Alert',
4126
+ message: 'Send the Valencia flood assessment to the emergency services.',
4067
4127
  },
4068
4128
  ],
4069
4129
  assistant: 'paperclip',
@@ -4421,15 +4481,23 @@ export const APP_SOURCES = {
4421
4481
  },
4422
4482
  {
4423
4483
  label: 'Accruals',
4424
- message: 'Which accruals should be booked for last month, and for how much?',
4484
+ message: 'Which accruals should be booked for last month? Show me the entries each rests on.',
4485
+ },
4486
+ {
4487
+ label: 'Expenses by month',
4488
+ message: "Chart last month's expenses by account against the month before.",
4425
4489
  },
4426
4490
  {
4427
- label: 'Reconciliation gaps',
4428
- message: 'Which bank lines and open items are still unreconciled for last month?',
4491
+ label: 'Post the accruals',
4492
+ message: 'Post the accruals you suggested for last month.',
4429
4493
  },
4430
4494
  ],
4431
4495
  assistant: 'cat',
4432
- outputs: ['text/markdown', 'application/x-ipynb+json'],
4496
+ outputs: [
4497
+ 'text/markdown',
4498
+ 'application/x-ipynb+json',
4499
+ 'application/json+a2ui',
4500
+ ],
4433
4501
  },
4434
4502
  tests: {
4435
4503
  cases: [
@@ -5108,7 +5176,7 @@ export const APP_SOURCES = {
5108
5176
  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.",
5109
5177
  owner: 'Datalayer <info@datalayer.io>',
5110
5178
  agent: 'worker-sales-pipeline-board-report:0.0.1',
5111
- 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.',
5179
+ 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. Say in your request how the person wants it shown — a chart, the invoices one by one — since Accounting can show it under the conversation; when it does, say so in a sentence rather than copy it. A request to do something rather than to read — send, remind, post — goes to Accounting the same way, and you repeat what it answered: never say a thing was done unless Accounting says it was. You change nothing anywhere: you ask, and you report.',
5112
5180
  interface: {
5113
5181
  accent: 'sky',
5114
5182
  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.",
@@ -5119,11 +5187,15 @@ export const APP_SOURCES = {
5119
5187
  },
5120
5188
  {
5121
5189
  label: 'Aged receivables',
5122
- message: 'Give me the aged receivables as of today, by customer.',
5190
+ message: 'Chart the aged receivables as of today, by customer.',
5123
5191
  },
5124
5192
  {
5125
- label: 'Trial balance',
5126
- message: 'What does the trial balance say for last month?',
5193
+ label: 'Largest balance',
5194
+ message: 'Which invoices make up the largest balance due? Show me each one.',
5195
+ },
5196
+ {
5197
+ label: 'Payment reminders',
5198
+ message: 'Send a payment reminder to every customer more than 60 days late.',
5127
5199
  },
5128
5200
  ],
5129
5201
  assistant: 'paperclip',
@@ -8,6 +8,8 @@
8
8
  */
9
9
  import type { EnvvarSpec } from '../types';
10
10
  export declare const ALPHAVANTAGE_API_KEY_SPEC_0_0_1: EnvvarSpec;
11
+ export declare const EARTHDATA_PASSWORD_SPEC_0_0_1: EnvvarSpec;
12
+ export declare const EARTHDATA_USERNAME_SPEC_0_0_1: EnvvarSpec;
11
13
  export declare const GITHUB_TOKEN_SPEC_0_0_1: EnvvarSpec;
12
14
  export declare const GOOGLE_OAUTH_CLIENT_ID_SPEC_0_0_1: EnvvarSpec;
13
15
  export declare const GOOGLE_OAUTH_CLIENT_SECRET_SPEC_0_0_1: EnvvarSpec;
@@ -15,6 +15,26 @@ export const ALPHAVANTAGE_API_KEY_SPEC_0_0_1 = {
15
15
  icon: 'key',
16
16
  emoji: '🔑',
17
17
  };
18
+ export const EARTHDATA_PASSWORD_SPEC_0_0_1 = {
19
+ id: 'EARTHDATA_PASSWORD',
20
+ version: '0.0.1',
21
+ name: 'Earthdata Login Password',
22
+ description: 'The password of a NASA Earthdata Login. Read in the code sandbox by the script that the download tool of the Earthdata MCP server writes, to download granules; searching needs none.',
23
+ registrationUrl: 'https://urs.earthdata.nasa.gov/users/new',
24
+ tags: ['authentication', 'password', 'earthdata', 'sandbox'],
25
+ icon: 'key',
26
+ emoji: '🔑',
27
+ };
28
+ export const EARTHDATA_USERNAME_SPEC_0_0_1 = {
29
+ id: 'EARTHDATA_USERNAME',
30
+ version: '0.0.1',
31
+ name: 'Earthdata Login Username',
32
+ description: 'The username of a NASA Earthdata Login. Read in the code sandbox by the script that the download tool of the Earthdata MCP server writes, to download granules; searching needs none.',
33
+ registrationUrl: 'https://urs.earthdata.nasa.gov/users/new',
34
+ tags: ['authentication', 'username', 'earthdata', 'sandbox'],
35
+ icon: 'key',
36
+ emoji: '🔑',
37
+ };
18
38
  export const GITHUB_TOKEN_SPEC_0_0_1 = {
19
39
  id: 'GITHUB_TOKEN',
20
40
  version: '0.0.1',
@@ -116,6 +136,8 @@ export const TAVILY_API_KEY_SPEC_0_0_1 = {
116
136
  // ============================================================================
117
137
  export const ENVVAR_CATALOG = {
118
138
  ALPHAVANTAGE_API_KEY: ALPHAVANTAGE_API_KEY_SPEC_0_0_1,
139
+ EARTHDATA_PASSWORD: EARTHDATA_PASSWORD_SPEC_0_0_1,
140
+ EARTHDATA_USERNAME: EARTHDATA_USERNAME_SPEC_0_0_1,
119
141
  GITHUB_TOKEN: GITHUB_TOKEN_SPEC_0_0_1,
120
142
  GOOGLE_OAUTH_CLIENT_ID: GOOGLE_OAUTH_CLIENT_ID_SPEC_0_0_1,
121
143
  GOOGLE_OAUTH_CLIENT_SECRET: GOOGLE_OAUTH_CLIENT_SECRET_SPEC_0_0_1,
@@ -7,6 +7,7 @@
7
7
  * DO NOT EDIT MANUALLY - run 'make specs' to regenerate.
8
8
  */
9
9
  import type { OutputSpec } from '../types';
10
+ export declare const COMPONENTS_OUTPUT_SPEC_0_0_1: OutputSpec;
10
11
  export declare const CSV_OUTPUT_SPEC_0_0_1: OutputSpec;
11
12
  export declare const DASHBOARD_OUTPUT_SPEC_0_0_1: OutputSpec;
12
13
  export declare const DATABASE_OUTPUT_SPEC_0_0_1: OutputSpec;
@@ -5,6 +5,17 @@
5
5
  // ============================================================================
6
6
  // Output Definitions
7
7
  // ============================================================================
8
+ export const COMPONENTS_OUTPUT_SPEC_0_0_1 = {
9
+ id: 'components',
10
+ version: '0.0.1',
11
+ name: 'Components',
12
+ description: "Deliver results as components of the catalog drawn under the answer: the sources as cards that open, a comparison as a table, a series as a chart, a choice as buttons that answer the application. Over A2A, one A2UI surface per artifact (`application/json+a2ui`, A2UI's media type).",
13
+ icon: 'browser',
14
+ enabled: false,
15
+ supports_template: false,
16
+ supports_storage: false,
17
+ mime_types: ['application/json+a2ui'],
18
+ };
8
19
  export const CSV_OUTPUT_SPEC_0_0_1 = {
9
20
  id: 'csv',
10
21
  version: '0.0.1',
@@ -114,6 +125,7 @@ export const WEBHOOK_OUTPUT_SPEC_0_0_1 = {
114
125
  // Output Catalog
115
126
  // ============================================================================
116
127
  export const OUTPUT_CATALOG = {
128
+ components: COMPONENTS_OUTPUT_SPEC_0_0_1,
117
129
  csv: CSV_OUTPUT_SPEC_0_0_1,
118
130
  dashboard: DASHBOARD_OUTPUT_SPEC_0_0_1,
119
131
  database: DATABASE_OUTPUT_SPEC_0_0_1,
@@ -12,7 +12,18 @@ export const SCENE_SCHEMA = {
12
12
  },
13
13
  AnswerKind: {
14
14
  description: 'What kind of answer comes back, and what the page shows.',
15
- enum: ['words', 'table', 'chart', 'notebook', 'map', 'file', 'image'],
15
+ enum: [
16
+ 'words',
17
+ 'table',
18
+ 'chart',
19
+ 'notebook',
20
+ 'map',
21
+ 'file',
22
+ 'image',
23
+ 'sources',
24
+ 'choice',
25
+ 'approval',
26
+ ],
16
27
  title: 'AnswerKind',
17
28
  type: 'string',
18
29
  },