@datalayer/agent-runtimes 1.3.81 → 1.3.83

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 (72) hide show
  1. package/lib/chat/assistant/SpeechBalloon.js +16 -1
  2. package/lib/chat/base/ChatBase.js +40 -4
  3. package/lib/chat/indicators/McpStatusIndicator.d.ts +1 -1
  4. package/lib/chat/indicators/McpStatusIndicator.js +13 -6
  5. package/lib/chat/indicators/SkillsStatusIndicator.d.ts +1 -1
  6. package/lib/chat/indicators/SkillsStatusIndicator.js +7 -3
  7. package/lib/chat/prompt/InputPrompt.d.ts +4 -1
  8. package/lib/chat/prompt/InputPrompt.js +2 -2
  9. package/lib/chat/prompt/InputPromptBase.d.ts +4 -1
  10. package/lib/chat/prompt/InputPromptBase.js +2 -2
  11. package/lib/chat/prompt/InputPromptLexical.d.ts +7 -1
  12. package/lib/chat/prompt/InputPromptLexical.js +5 -3
  13. package/lib/components/a2ui/datalayer/Form.js +19 -2
  14. package/lib/components/teams/index.d.ts +1 -0
  15. package/lib/components/teams/index.js +1 -0
  16. package/lib/components/teams/usePeerSandbox.d.ts +13 -0
  17. package/lib/components/teams/usePeerSandbox.js +59 -0
  18. package/lib/examples/AgentA2ATeamExample.js +7 -2
  19. package/lib/loop/apps/AppComposer.d.ts +31 -0
  20. package/lib/loop/apps/AppComposer.js +67 -0
  21. package/lib/loop/apps/AppRenderer.d.ts +16 -5
  22. package/lib/loop/apps/AppRenderer.js +49 -16
  23. package/lib/loop/apps/appspec.d.ts +8 -1
  24. package/lib/loop/apps/appspec.js +88 -23
  25. package/lib/loop/apps/checks.js +125 -8
  26. package/lib/loop/apps/composer.d.ts +37 -0
  27. package/lib/loop/apps/composer.js +61 -0
  28. package/lib/loop/apps/index.d.ts +2 -0
  29. package/lib/loop/apps/index.js +2 -0
  30. package/lib/loop/core/index.d.ts +31 -0
  31. package/lib/loop/core/index.js +22 -0
  32. package/lib/loop/embed/AppEmbed.d.ts +46 -7
  33. package/lib/loop/embed/AppEmbed.js +108 -26
  34. package/lib/loop/embed/LoopEmbed.js +2 -0
  35. package/lib/loop/embed/element.js +19 -5
  36. package/lib/loop/embed/embedConfig.d.ts +10 -1
  37. package/lib/loop/embed/embedConfig.js +12 -1
  38. package/lib/loop/embed/embedSession.d.ts +79 -0
  39. package/lib/loop/embed/embedSession.js +136 -0
  40. package/lib/loop/embed/embedTheme.d.ts +12 -9
  41. package/lib/loop/embed/embedTheme.js +32 -22
  42. package/lib/loop/index.d.ts +4 -3
  43. package/lib/loop/index.js +4 -3
  44. package/lib/loop/plugins/agent-capacity/index.d.ts +3 -1
  45. package/lib/loop/plugins/agent-capacity/index.js +2 -1
  46. package/lib/loop/plugins/app-page/appPageModel.d.ts +14 -5
  47. package/lib/loop/plugins/app-page/appPageModel.js +80 -88
  48. package/lib/loop/plugins/chat/ChatView.js +31 -4
  49. package/lib/loop/plugins/chat/index.d.ts +6 -1
  50. package/lib/loop/presets.d.ts +3 -1
  51. package/lib/loop/presets.js +2 -1
  52. package/lib/loop/shell/LoopWorkspace.js +3 -0
  53. package/lib/protocols/BrowserAgentAdapter.d.ts +18 -0
  54. package/lib/protocols/BrowserAgentAdapter.js +35 -2
  55. package/lib/runtimes/__tests__/fixtures/accounting-agent-card.json +8 -0
  56. package/lib/runtimes/browser/a2aPeer.d.ts +11 -0
  57. package/lib/runtimes/browser/a2aPeer.js +15 -1
  58. package/lib/runtimes/browser/protocol.d.ts +3 -0
  59. package/lib/runtimes/browser/protocol.js +2 -1
  60. package/lib/specs/agents/agents.js +6 -3
  61. package/lib/specs/apps.js +216 -176
  62. package/lib/specs/appspecSchema.js +205 -84
  63. package/lib/specs/cogs.js +3 -2
  64. package/lib/types/agentspecs.d.ts +92 -7
  65. package/lib/types/chat.d.ts +29 -1
  66. package/package.json +1 -1
  67. package/scripts/codegen/generate_agents.py +4 -2
  68. package/scripts/codegen/generate_apps.py +0 -1
  69. package/scripts/codegen/generate_backend_tools.py +4 -12
  70. package/scripts/codegen/generate_cogs.py +3 -1
  71. package/scripts/codegen/generate_ui_plugins.py +22 -9
  72. package/scripts/voice/transcribe.mjs +29 -21
@@ -52,6 +52,33 @@ export const APPSPEC_SCHEMA = {
52
52
  title: 'AppChecks',
53
53
  type: 'object',
54
54
  },
55
+ AppCommand: {
56
+ additionalProperties: false,
57
+ description: "A slash command the user picks in the composer (LOOP P-19).\n\nTyping `/` lists the application's commands; picking one sends its\n`prompt`, `{input}` replaced by the words typed after the command.",
58
+ properties: {
59
+ name: {
60
+ description: 'What follows the slash: lower-case letters, digits and hyphens, a letter first (`summarise`)',
61
+ pattern: '^[a-z](?:[a-z0-9-]{0,30}[a-z0-9])?$',
62
+ title: 'Name',
63
+ type: 'string',
64
+ },
65
+ description: {
66
+ description: "What the composer's menu says it does",
67
+ minLength: 1,
68
+ title: 'Description',
69
+ type: 'string',
70
+ },
71
+ prompt: {
72
+ description: "What is sent when it is picked: `{input}` stands for the words typed after it; without `{input}`, those words follow the prompt. An application's code answers `/<name> {input}` itself (`@app.command`)",
73
+ minLength: 1,
74
+ title: 'Prompt',
75
+ type: 'string',
76
+ },
77
+ },
78
+ required: ['name', 'description', 'prompt'],
79
+ title: 'AppCommand',
80
+ type: 'object',
81
+ },
55
82
  AppComputer: {
56
83
  additionalProperties: false,
57
84
  description: 'What the application may do on its own computer. Each is off until it is turned on.',
@@ -269,6 +296,18 @@ export const APPSPEC_SCHEMA = {
269
296
  default: 'green',
270
297
  description: "The application's one colour",
271
298
  },
299
+ theme: {
300
+ anyOf: [
301
+ {
302
+ $ref: '#/$defs/AppTheme',
303
+ },
304
+ {
305
+ type: 'null',
306
+ },
307
+ ],
308
+ default: null,
309
+ description: "The theme it runs in by default, at its address, embedded, in the Studio's Preview and as an example: a `variant` and, optionally, a colour `mode`. The person's own when unsaid. Its `accent` colours the `loop` theme only",
310
+ },
272
311
  welcome: {
273
312
  default: '',
274
313
  description: 'What the application says first',
@@ -283,14 +322,36 @@ export const APPSPEC_SCHEMA = {
283
322
  title: 'Starters',
284
323
  type: 'array',
285
324
  },
286
- settings: {
287
- description: 'What the user may set',
325
+ commands: {
326
+ description: 'Slash commands the user picks in the composer: typing `/` lists them (LOOP P-19)',
288
327
  items: {
289
- $ref: '#/$defs/AppSetting',
328
+ $ref: '#/$defs/AppCommand',
290
329
  },
291
- title: 'Settings',
330
+ title: 'Commands',
331
+ type: 'array',
332
+ },
333
+ modes: {
334
+ description: 'Mode switches in the composer: the option picked goes with every run, its instructions told to the agent and its model run on (LOOP P-19)',
335
+ items: {
336
+ $ref: '#/$defs/AppMode',
337
+ },
338
+ title: 'Modes',
292
339
  type: 'array',
293
340
  },
341
+ settings: {
342
+ anyOf: [
343
+ {
344
+ additionalProperties: true,
345
+ type: 'object',
346
+ },
347
+ {
348
+ type: 'null',
349
+ },
350
+ ],
351
+ default: null,
352
+ description: "What the user may set: the JSON Schema of a form, an object of named fields, each with its `title` and its `default` (LOOP C-16). Drawn with `@datalayer/primer-rjsf` beside the conversation and on a deployment's Ship card, its values go with every run and are checked by the runtime against the same schema. None when unsaid",
353
+ title: 'Settings',
354
+ },
294
355
  components: {
295
356
  description: "The components of the catalog the surface may use; the kind's own when empty",
296
357
  items: {
@@ -362,6 +423,95 @@ export const APPSPEC_SCHEMA = {
362
423
  title: 'AppKind',
363
424
  type: 'string',
364
425
  },
426
+ AppMode: {
427
+ additionalProperties: false,
428
+ description: 'A mode switch in the composer (LOOP P-19): the person picks one of its options.',
429
+ properties: {
430
+ id: {
431
+ description: 'Its id, the key a run says its option under',
432
+ pattern: '^[a-z][a-z0-9_-]{0,39}$',
433
+ title: 'Id',
434
+ type: 'string',
435
+ },
436
+ label: {
437
+ description: 'What the switch is called',
438
+ minLength: 1,
439
+ title: 'Label',
440
+ type: 'string',
441
+ },
442
+ options: {
443
+ description: 'Its positions, two at least',
444
+ items: {
445
+ $ref: '#/$defs/AppModeOption',
446
+ },
447
+ minItems: 2,
448
+ title: 'Options',
449
+ type: 'array',
450
+ },
451
+ default: {
452
+ anyOf: [
453
+ {
454
+ type: 'string',
455
+ },
456
+ {
457
+ type: 'null',
458
+ },
459
+ ],
460
+ default: null,
461
+ description: 'The option it starts on; the first when unsaid',
462
+ title: 'Default',
463
+ },
464
+ },
465
+ required: ['id', 'label', 'options'],
466
+ title: 'AppMode',
467
+ type: 'object',
468
+ },
469
+ AppModeOption: {
470
+ additionalProperties: false,
471
+ description: 'One position of a mode switch (LOOP P-19): what the agent is told, the model it runs on.',
472
+ properties: {
473
+ id: {
474
+ description: 'Its id, what a run says it is in',
475
+ pattern: '^[a-z][a-z0-9_-]{0,39}$',
476
+ title: 'Id',
477
+ type: 'string',
478
+ },
479
+ label: {
480
+ description: 'What the switch says',
481
+ minLength: 1,
482
+ title: 'Label',
483
+ type: 'string',
484
+ },
485
+ description: {
486
+ default: '',
487
+ description: 'What it changes, in a sentence',
488
+ title: 'Description',
489
+ type: 'string',
490
+ },
491
+ instructions: {
492
+ default: '',
493
+ description: 'What the agent is told besides its instructions, in every run in this mode',
494
+ title: 'Instructions',
495
+ type: 'string',
496
+ },
497
+ model: {
498
+ anyOf: [
499
+ {
500
+ type: 'string',
501
+ },
502
+ {
503
+ type: 'null',
504
+ },
505
+ ],
506
+ default: null,
507
+ description: "The model a run in this mode runs on, in place of the application's",
508
+ title: 'Model',
509
+ },
510
+ },
511
+ required: ['id', 'label'],
512
+ title: 'AppModeOption',
513
+ type: 'object',
514
+ },
365
515
  AppPermissions: {
366
516
  additionalProperties: false,
367
517
  description: 'What the application may reach beside its connections. Nothing, unless said.',
@@ -465,82 +615,6 @@ export const APPSPEC_SCHEMA = {
465
615
  title: 'AppScenario',
466
616
  type: 'object',
467
617
  },
468
- AppSetting: {
469
- additionalProperties: false,
470
- description: 'Something the user may set for their session.',
471
- properties: {
472
- id: {
473
- description: 'The name the application reads it by',
474
- title: 'Id',
475
- type: 'string',
476
- },
477
- type: {
478
- $ref: '#/$defs/SettingType',
479
- description: '`select`, `text`, `toggle`, `slider` or `number`',
480
- },
481
- label: {
482
- description: 'What the user reads',
483
- title: 'Label',
484
- type: 'string',
485
- },
486
- options: {
487
- description: 'For a select: its options',
488
- items: {
489
- type: 'string',
490
- },
491
- title: 'Options',
492
- type: 'array',
493
- },
494
- default: {
495
- anyOf: [
496
- {
497
- type: 'string',
498
- },
499
- {
500
- type: 'boolean',
501
- },
502
- {
503
- type: 'number',
504
- },
505
- {
506
- type: 'null',
507
- },
508
- ],
509
- default: null,
510
- description: 'Its value at the start',
511
- title: 'Default',
512
- },
513
- min: {
514
- anyOf: [
515
- {
516
- type: 'number',
517
- },
518
- {
519
- type: 'null',
520
- },
521
- ],
522
- default: null,
523
- description: 'For a slider or a number: the least',
524
- title: 'Min',
525
- },
526
- max: {
527
- anyOf: [
528
- {
529
- type: 'number',
530
- },
531
- {
532
- type: 'null',
533
- },
534
- ],
535
- default: null,
536
- description: 'For a slider or a number: the most',
537
- title: 'Max',
538
- },
539
- },
540
- required: ['id', 'type', 'label'],
541
- title: 'AppSetting',
542
- type: 'object',
543
- },
544
618
  AppSpaceGrant: {
545
619
  additionalProperties: false,
546
620
  description: 'A Space the application may reach.',
@@ -667,6 +741,31 @@ export const APPSPEC_SCHEMA = {
667
741
  title: 'AppTests',
668
742
  type: 'object',
669
743
  },
744
+ AppTheme: {
745
+ additionalProperties: false,
746
+ description: 'The theme an application runs in by default (LOOP T-30).',
747
+ properties: {
748
+ variant: {
749
+ $ref: '#/$defs/ThemeVariant',
750
+ description: 'The theme: `datalayer`, `spatial`, `lovely`, `matrix`, `earth`, `sand`, `ivory`, `sun` or `loop`',
751
+ },
752
+ mode: {
753
+ anyOf: [
754
+ {
755
+ $ref: '#/$defs/ThemeMode',
756
+ },
757
+ {
758
+ type: 'null',
759
+ },
760
+ ],
761
+ default: null,
762
+ description: "`light`, `dark` or `auto` (the device's); the person's own when unsaid",
763
+ },
764
+ },
765
+ required: ['variant'],
766
+ title: 'AppTheme',
767
+ type: 'object',
768
+ },
670
769
  AppTrigger: {
671
770
  additionalProperties: false,
672
771
  description: "What starts a worker's work.",
@@ -937,10 +1036,26 @@ export const APPSPEC_SCHEMA = {
937
1036
  title: 'RecordItem',
938
1037
  type: 'string',
939
1038
  },
940
- SettingType: {
941
- description: 'What a setting is set with.',
942
- enum: ['select', 'text', 'toggle', 'slider', 'number'],
943
- title: 'SettingType',
1039
+ ThemeMode: {
1040
+ description: 'The colour mode a theme is worn in: `auto` follows the device.',
1041
+ enum: ['light', 'dark', 'auto'],
1042
+ title: 'ThemeMode',
1043
+ type: 'string',
1044
+ },
1045
+ ThemeVariant: {
1046
+ description: "A theme of Datalayer's, as Appearance names it (LOOP T-30).",
1047
+ enum: [
1048
+ 'datalayer',
1049
+ 'spatial',
1050
+ 'lovely',
1051
+ 'matrix',
1052
+ 'earth',
1053
+ 'sand',
1054
+ 'ivory',
1055
+ 'sun',
1056
+ 'loop',
1057
+ ],
1058
+ title: 'ThemeVariant',
944
1059
  type: 'string',
945
1060
  },
946
1061
  TriggerType: {
@@ -1157,6 +1272,12 @@ export const APPSPEC_SCHEMA = {
1157
1272
  title: 'Enabled',
1158
1273
  type: 'boolean',
1159
1274
  },
1275
+ unavailable_because: {
1276
+ default: '',
1277
+ description: 'Why it is not offered today, in a sentence its page shows: said when `enabled` is false, and only then',
1278
+ title: 'Unavailable Because',
1279
+ type: 'string',
1280
+ },
1160
1281
  tags: {
1161
1282
  items: {
1162
1283
  type: 'string',
package/lib/specs/cogs.js CHANGED
@@ -242,8 +242,9 @@ const COG_CUSTOMER_INTERVIEWER_AGENTSPEC_0_0_1 = {
242
242
  description: `Conducts adaptive customer interviews under the Customer Research Frame: consent first, no leading question, and insights that each cite the interviewee's own words.`,
243
243
  tags: ['research', 'customer-support', 'analysis', 'cog'],
244
244
  domain: 'market-analyst',
245
- enabled: false,
245
+ enabled: true,
246
246
  model: 'bedrock:us.anthropic.claude-sonnet-4-6',
247
+ modelAdditionals: ['alibaba:qwen-max'],
247
248
  mcpServers: [],
248
249
  skills: [
249
250
  SKILL_MAP['text-summarizer:0.0.1']
@@ -625,7 +626,7 @@ export const COG_CUSTOMER_INTERVIEWER_0_0_1 = {
625
626
  frames: ['customer-research'],
626
627
  lineage: ['datalayer', 'customer-research'],
627
628
  kind: 'context',
628
- enabled: false,
629
+ enabled: true,
629
630
  guards: [
630
631
  {
631
632
  id: 'no-secrets',
@@ -386,6 +386,19 @@ export type AppBehaviour = 'do_it' | 'if_asked' | 'ask_first' | 'leave_to_me';
386
386
  export type AppLayout = 'chat' | 'page' | 'split';
387
387
  /** The one colour of an application; everything else is neutral. */
388
388
  export type AppAccent = 'green' | 'rose' | 'sky' | 'lime' | 'sun' | 'violet';
389
+ /** A theme of Appearance's, which an application may run in (LOOP T-30). */
390
+ export type AppThemeVariant = 'datalayer' | 'spatial' | 'lovely' | 'matrix' | 'earth' | 'sand' | 'ivory' | 'sun' | 'loop';
391
+ /** The colour mode it is worn in: `auto` follows the device. */
392
+ export type AppThemeMode = 'light' | 'dark' | 'auto';
393
+ /**
394
+ * The theme an application runs in by default (LOOP T-30): at its address,
395
+ * embedded, in the Studio's Preview and as an example. The person's own
396
+ * when unsaid; the mode, when unsaid, is the person's.
397
+ */
398
+ export interface AppThemeSpec {
399
+ variant: AppThemeVariant;
400
+ mode?: AppThemeMode;
401
+ }
389
402
  /**
390
403
  * The character an application's floating assistant shows (LOOP T-24): the id
391
404
  * an enabled plugin contributes it under to `loop.assistant.character` —
@@ -434,15 +447,71 @@ export interface AppStarterSpec {
434
447
  label: string;
435
448
  message: string;
436
449
  }
437
- export interface AppSettingSpec {
450
+ /** A slash command the user picks in the composer (LOOP P-19). */
451
+ export interface AppCommandSpec {
452
+ /** What follows the slash: lower-case letters, digits and hyphens. */
453
+ name: string;
454
+ /** What the composer's menu says it does. */
455
+ description: string;
456
+ /** What picking it sends: `{input}` the words typed after it. */
457
+ prompt: string;
458
+ }
459
+ /** One position of a mode switch (LOOP P-19). */
460
+ export interface AppModeOptionSpec {
438
461
  id: string;
439
- type: 'select' | 'text' | 'toggle' | 'slider' | 'number';
440
462
  label: string;
441
- options: string[];
442
- default?: string | boolean | number;
443
- min?: number;
444
- max?: number;
463
+ description?: string;
464
+ /** What the agent is told in every run in this mode. */
465
+ instructions?: string;
466
+ /** The model a run in this mode runs on, in place of the application's. */
467
+ model?: string | null;
445
468
  }
469
+ /** A mode switch in the composer (LOOP P-19). */
470
+ export interface AppModeSpec {
471
+ id: string;
472
+ label: string;
473
+ /** Its positions, two at least. */
474
+ options: AppModeOptionSpec[];
475
+ /** The option it starts on; the first when unsaid. */
476
+ default?: string | null;
477
+ }
478
+ /**
479
+ * What a run in the modes chosen is told, and the model it runs on (LOOP
480
+ * P-19): agentspecs' `ModeEffect`.
481
+ */
482
+ export interface AppModeEffect {
483
+ /** The instructions of the options chosen, in the order of the modes. */
484
+ instructions: string;
485
+ /** The model an option chosen names; the application's when unsaid. */
486
+ model?: string;
487
+ }
488
+ /**
489
+ * One field of a form (LOOP C-16): its JSON Schema — a `type`, the `title` a
490
+ * person reads, its `default`, and what it takes (`enum`, `minimum`,
491
+ * `maximum`…).
492
+ */
493
+ export type AppFormField = {
494
+ type?: string;
495
+ title?: string;
496
+ description?: string;
497
+ default?: unknown;
498
+ enum?: unknown[];
499
+ minimum?: number;
500
+ maximum?: number;
501
+ [keyword: string]: unknown;
502
+ };
503
+ /**
504
+ * The JSON Schema of a form (LOOP C-16): an object of named fields, drawn with
505
+ * `@datalayer/primer-rjsf` and checked by the runtime against the same schema.
506
+ * An application's settings are one (`interface.settings`), as a Form block's
507
+ * schema is.
508
+ */
509
+ export type AppFormSchema = {
510
+ type: 'object';
511
+ properties: Record<string, AppFormField>;
512
+ required?: string[];
513
+ [keyword: string]: unknown;
514
+ };
446
515
  /** The component tree a user meets, over the approved catalog (A2UI). */
447
516
  export interface AppSurfaceSpec {
448
517
  protocol: string;
@@ -471,10 +540,21 @@ export interface AppVoiceSpec {
471
540
  /** What the user of an application sees. */
472
541
  export interface AppInterfaceSpec {
473
542
  layout: AppLayout;
543
+ /** Its one colour, over the `loop` theme only. */
474
544
  accent: AppAccent;
545
+ /** The theme it runs in by default; the person's own when unsaid (T-30). */
546
+ theme?: AppThemeSpec;
475
547
  welcome: string;
476
548
  starters: AppStarterSpec[];
477
- settings: AppSettingSpec[];
549
+ /** Slash commands picked in the composer: typing `/` lists them (P-19). */
550
+ commands: AppCommandSpec[];
551
+ /** Mode switches in the composer, the option picked going with every run (P-19). */
552
+ modes: AppModeSpec[];
553
+ /**
554
+ * What a person may set: the JSON Schema of a form (C-16), drawn beside the
555
+ * conversation and on a deployment's Ship card; none when unsaid.
556
+ */
557
+ settings?: AppFormSchema;
478
558
  /** The components of the catalog the surface may use. */
479
559
  components: string[];
480
560
  surface?: AppSurfaceSpec;
@@ -652,6 +732,11 @@ export interface AppSpec {
652
732
  /** What it names that is not enabled today, in sentences. */
653
733
  setup: string[];
654
734
  enabled: boolean;
735
+ /**
736
+ * Why it is not offered today, in a sentence its page shows: said when
737
+ * `enabled` is false, and only then (empty otherwise).
738
+ */
739
+ unavailable_because: string;
655
740
  tags: string[];
656
741
  icon?: string;
657
742
  /** Its face: one emoji, shown wherever the application appears. */
@@ -15,6 +15,7 @@ import type { AgentRuntimeConfig } from './config';
15
15
  import type { ContextSnapshotData } from './context';
16
16
  import type { InputPromptVariant } from '../chat/prompt/InputPromptBase';
17
17
  import type { MentionableAgent } from '../chat/prompt/plugins/AgentMentionPlugin';
18
+ import type { PromptCommand } from '../chat/prompt/plugins/CommandPlugin';
18
19
  import type { Icon } from '@primer/octicons-react';
19
20
  /** One agent a chat may address, as its controls need it. */
20
21
  export interface FooterAgent {
@@ -652,6 +653,21 @@ export type ThemeOverrides = {
652
653
  light?: Record<string, string>;
653
654
  dark?: Record<string, string>;
654
655
  };
656
+ /**
657
+ * A conversation the chat goes on with (LOOP D-13): an embedded
658
+ * application's session, reattached after its page reloaded.
659
+ */
660
+ export type ResumedThread = {
661
+ /** Its id, AG-UI's `threadId`: the session's uid. */
662
+ id: string;
663
+ /** What it holds already; none for a new one. */
664
+ messages: ChatMessage[];
665
+ /**
666
+ * Told the thread a message is first sent on — this one, or a new one
667
+ * after the header's + — so that its host keeps it. A stable function.
668
+ */
669
+ onStarted?: (threadId: string) => void;
670
+ };
655
671
  export interface ChatBaseProps {
656
672
  /**
657
673
  * Hands an imperative send function to the host, once the chat is able to
@@ -722,7 +738,7 @@ export interface ChatBaseProps {
722
738
  /**
723
739
  * External MCP toolsets status data for the MCP indicator.
724
740
  * When provided, the data is forwarded to the McpStatusIndicator
725
- * so it shows live status instead of "No MCP Server defined".
741
+ * so it shows their live status; with none, it is not drawn.
726
742
  */
727
743
  mcpStatusData?: import('./mcp').McpToolsetsStatusResponse | null;
728
744
  /**
@@ -755,6 +771,11 @@ export interface ChatBaseProps {
755
771
  promptVariant?: InputPromptVariant;
756
772
  /** Agents the prompt may address by typing `@`. Lexical only. */
757
773
  mentionableAgents?: MentionableAgent[];
774
+ /**
775
+ * Commands the prompt lists while `/` is typed, before its own: an
776
+ * application's (LOOP P-19). Picking one writes `/<name> `. Lexical only.
777
+ */
778
+ promptCommands?: PromptCommand[];
758
779
  /**
759
780
  * Whether the prompt offers a chooser for who answers.
760
781
  *
@@ -1190,6 +1211,13 @@ export interface ChatBaseProps {
1190
1211
  userId?: string;
1191
1212
  accessToken?: string;
1192
1213
  }>;
1214
+ /**
1215
+ * The conversation to go on with (LOOP D-13): its AG-UI thread — an
1216
+ * application's session — and what it holds, drawn in place of the
1217
+ * runtime's history, which is its agent's and not one session's. Read
1218
+ * when the chat mounts; a new thread (the header's +) is the chat's own.
1219
+ */
1220
+ thread?: ResumedThread;
1193
1221
  /**
1194
1222
  * Runtime ID for conversation persistence.
1195
1223
  * When provided, messages are restored from websocket snapshot data on
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datalayer/agent-runtimes",
3
- "version": "1.3.81",
3
+ "version": "1.3.83",
4
4
  "type": "module",
5
5
  "workspaces": [
6
6
  ".",
@@ -410,7 +410,8 @@ from agent_runtimes.types import (
410
410
  for skill in spec.get("skills", [])
411
411
  ]
412
412
  tool_refs = [
413
- versioned_ref(*split_spec_ref(tool)) for tool in spec.get("backend_tools", [])
413
+ versioned_ref(*split_spec_ref(tool))
414
+ for tool in spec.get("backend_tools", [])
414
415
  ]
415
416
  frontend_tool_refs = [
416
417
  versioned_ref(*split_spec_ref(ft))
@@ -1032,7 +1033,8 @@ const FRONTEND_TOOL_MAP: Record<string, any> = {
1032
1033
 
1033
1034
  # Get backend tools - resolve to BackendToolSpec via TOOL_MAP
1034
1035
  tool_ids_list = [
1035
- versioned_ref(*split_spec_ref(sid)) for sid in spec.get("backend_tools", [])
1036
+ versioned_ref(*split_spec_ref(sid))
1037
+ for sid in spec.get("backend_tools", [])
1036
1038
  ]
1037
1039
  if has_tools and tool_ids_list:
1038
1040
  tools_str = ", ".join(f"TOOL_MAP['{tid}']" for tid in tool_ids_list)
@@ -216,7 +216,6 @@ def generate_python_code(specs: list[dict[str, Any]], built: dict[str, str]) ->
216
216
  "",
217
217
  "from agent_runtimes.types import AppSpec",
218
218
  "",
219
- "",
220
219
  "# " + "=" * 76,
221
220
  "# Application Definitions",
222
221
  "# " + "=" * 76,
@@ -110,9 +110,7 @@ def generate_python_code(specs: list[dict[str, Any]]) -> str:
110
110
  for spec in specs:
111
111
  tool_id = spec["id"]
112
112
  version = spec["version"]
113
- const_name = (
114
- f"{tool_id.upper().replace('-', '_')}_BACKEND_TOOL_SPEC{version_suffix(version)}"
115
- )
113
+ const_name = f"{tool_id.upper().replace('-', '_')}_BACKEND_TOOL_SPEC{version_suffix(version)}"
116
114
  runtime = _require_runtime(spec)
117
115
  requires_approval = _requires_approval(spec)
118
116
  timeout = _timeout_hms(spec)
@@ -157,9 +155,7 @@ def generate_python_code(specs: list[dict[str, Any]]) -> str:
157
155
  for spec in specs:
158
156
  tool_id = spec["id"]
159
157
  version = spec["version"]
160
- const_name = (
161
- f"{tool_id.upper().replace('-', '_')}_BACKEND_TOOL_SPEC{version_suffix(version)}"
162
- )
158
+ const_name = f"{tool_id.upper().replace('-', '_')}_BACKEND_TOOL_SPEC{version_suffix(version)}"
163
159
  lines.append(f' "{tool_id}": {const_name},')
164
160
 
165
161
  lines.extend(
@@ -215,9 +211,7 @@ def generate_typescript_code(specs: list[dict[str, Any]]) -> str:
215
211
  for spec in specs:
216
212
  tool_id = spec["id"]
217
213
  version = spec["version"]
218
- const_name = (
219
- f"{tool_id.upper().replace('-', '_')}_BACKEND_TOOL_SPEC{version_suffix(version)}"
220
- )
214
+ const_name = f"{tool_id.upper().replace('-', '_')}_BACKEND_TOOL_SPEC{version_suffix(version)}"
221
215
  runtime = _require_runtime(spec)
222
216
  requires_approval = _requires_approval(spec)
223
217
  timeout = _timeout_hms(spec)
@@ -264,9 +258,7 @@ def generate_typescript_code(specs: list[dict[str, Any]]) -> str:
264
258
  for spec in specs:
265
259
  tool_id = spec["id"]
266
260
  version = spec["version"]
267
- const_name = (
268
- f"{tool_id.upper().replace('-', '_')}_BACKEND_TOOL_SPEC{version_suffix(version)}"
269
- )
261
+ const_name = f"{tool_id.upper().replace('-', '_')}_BACKEND_TOOL_SPEC{version_suffix(version)}"
270
262
  lines.append(f" '{tool_id}': {const_name},")
271
263
 
272
264
  lines.extend(
@@ -208,7 +208,9 @@ def generate_typescript_code(specs: list[dict[str, Any]], specs_dir: Path) -> st
208
208
  # is one directory up, beside the catalogues it imports.
209
209
  head = head.replace("from '../../types'", "from '../types'")
210
210
  head = re.sub(
211
- r"from '\.\./(mcpServers|skills|backendTools|frontendTools)'", r"from './\1'", head
211
+ r"from '\.\./(mcpServers|skills|backendTools|frontendTools)'",
212
+ r"from './\1'",
213
+ head,
212
214
  )
213
215
 
214
216
  lines = [