@datalayer/agent-runtimes 1.3.81 → 1.3.82
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/chat/assistant/SpeechBalloon.js +16 -1
- package/lib/chat/base/ChatBase.js +40 -4
- package/lib/chat/indicators/McpStatusIndicator.d.ts +1 -1
- package/lib/chat/indicators/McpStatusIndicator.js +13 -6
- package/lib/chat/indicators/SkillsStatusIndicator.d.ts +1 -1
- package/lib/chat/indicators/SkillsStatusIndicator.js +7 -3
- package/lib/chat/prompt/InputPrompt.d.ts +4 -1
- package/lib/chat/prompt/InputPrompt.js +2 -2
- package/lib/chat/prompt/InputPromptBase.d.ts +4 -1
- package/lib/chat/prompt/InputPromptBase.js +2 -2
- package/lib/chat/prompt/InputPromptLexical.d.ts +7 -1
- package/lib/chat/prompt/InputPromptLexical.js +5 -3
- package/lib/components/teams/index.d.ts +1 -0
- package/lib/components/teams/index.js +1 -0
- package/lib/components/teams/usePeerSandbox.d.ts +13 -0
- package/lib/components/teams/usePeerSandbox.js +59 -0
- package/lib/examples/AgentA2ATeamExample.js +7 -2
- package/lib/loop/apps/AppComposer.d.ts +31 -0
- package/lib/loop/apps/AppComposer.js +67 -0
- package/lib/loop/apps/AppRenderer.d.ts +16 -5
- package/lib/loop/apps/AppRenderer.js +49 -16
- package/lib/loop/apps/appspec.d.ts +8 -1
- package/lib/loop/apps/appspec.js +87 -0
- package/lib/loop/apps/checks.js +108 -1
- package/lib/loop/apps/composer.d.ts +37 -0
- package/lib/loop/apps/composer.js +61 -0
- package/lib/loop/apps/index.d.ts +2 -0
- package/lib/loop/apps/index.js +2 -0
- package/lib/loop/core/index.d.ts +31 -0
- package/lib/loop/core/index.js +22 -0
- package/lib/loop/embed/AppEmbed.d.ts +46 -7
- package/lib/loop/embed/AppEmbed.js +108 -26
- package/lib/loop/embed/LoopEmbed.js +2 -0
- package/lib/loop/embed/element.js +19 -5
- package/lib/loop/embed/embedConfig.d.ts +10 -1
- package/lib/loop/embed/embedConfig.js +12 -1
- package/lib/loop/embed/embedSession.d.ts +79 -0
- package/lib/loop/embed/embedSession.js +136 -0
- package/lib/loop/embed/embedTheme.d.ts +12 -9
- package/lib/loop/embed/embedTheme.js +32 -22
- package/lib/loop/index.d.ts +4 -3
- package/lib/loop/index.js +4 -3
- package/lib/loop/plugins/agent-capacity/index.d.ts +3 -1
- package/lib/loop/plugins/agent-capacity/index.js +2 -1
- package/lib/loop/plugins/chat/ChatView.js +31 -4
- package/lib/loop/plugins/chat/index.d.ts +6 -1
- package/lib/loop/presets.d.ts +3 -1
- package/lib/loop/presets.js +2 -1
- package/lib/loop/shell/LoopWorkspace.js +3 -0
- package/lib/protocols/BrowserAgentAdapter.d.ts +18 -0
- package/lib/protocols/BrowserAgentAdapter.js +35 -2
- package/lib/runtimes/__tests__/fixtures/accounting-agent-card.json +8 -0
- package/lib/runtimes/browser/a2aPeer.d.ts +11 -0
- package/lib/runtimes/browser/a2aPeer.js +15 -1
- package/lib/runtimes/browser/protocol.d.ts +3 -0
- package/lib/runtimes/browser/protocol.js +2 -1
- package/lib/specs/apps.js +28 -0
- package/lib/specs/appspecSchema.js +191 -0
- package/lib/types/agentspecs.d.ts +58 -0
- package/lib/types/chat.d.ts +29 -1
- package/package.json +1 -1
- package/scripts/codegen/generate_agents.py +4 -2
- package/scripts/codegen/generate_backend_tools.py +4 -12
- package/scripts/codegen/generate_cogs.py +3 -1
- package/scripts/codegen/generate_ui_plugins.py +22 -9
- package/scripts/voice/transcribe.mjs +29 -21
|
@@ -36,6 +36,19 @@ import { ClientFactory, ClientFactoryOptions, DefaultAgentCardResolver, JsonRpcT
|
|
|
36
36
|
import { jsonSchema, tool } from 'ai';
|
|
37
37
|
/** Where an A2A agent's card is, under the address it is served at. */
|
|
38
38
|
export const AGENT_CARD_PATH = '.well-known/agent-card.json';
|
|
39
|
+
/** The extension an agent card carries its face in: its name stays plain. */
|
|
40
|
+
export const A2A_FACE_EXTENSION_URI = 'https://datalayer.ai/extensions/face/v1';
|
|
41
|
+
/** The face an agent card carries, if it carries one. */
|
|
42
|
+
export function faceOfCard(card) {
|
|
43
|
+
const extension = card.capabilities?.extensions?.find(candidate => candidate.uri === A2A_FACE_EXTENSION_URI);
|
|
44
|
+
const params = (extension?.params ?? {});
|
|
45
|
+
if (typeof params.emoji !== 'string' || !params.emoji) {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
return typeof params.avatar === 'string' && params.avatar
|
|
49
|
+
? { emoji: params.emoji, avatar: params.avatar }
|
|
50
|
+
: { emoji: params.emoji };
|
|
51
|
+
}
|
|
39
52
|
/** A fetch that sends the key as a bearer token, beside the caller's headers. */
|
|
40
53
|
function withKey(base, key) {
|
|
41
54
|
if (!key) {
|
|
@@ -69,7 +82,8 @@ export async function connectA2APeer(options) {
|
|
|
69
82
|
if (!skill) {
|
|
70
83
|
throw new Error(`${card.name || root} offers no skill on its agent card: there is nothing to ask it.`);
|
|
71
84
|
}
|
|
72
|
-
|
|
85
|
+
const face = faceOfCard(card);
|
|
86
|
+
return face ? { client, card, skill, face } : { client, card, skill };
|
|
73
87
|
}
|
|
74
88
|
/** The media types an answer in words comes in: the answer itself, never an artifact of its own. */
|
|
75
89
|
export const TEXT_MEDIA_TYPES = [
|
|
@@ -12,6 +12,7 @@ import type { ProtocolConfig } from '../../types/protocol';
|
|
|
12
12
|
import type { AgentStreamSubagentPayload } from '../../types/stream';
|
|
13
13
|
import type { FrontendToolDefinition } from '../../types/tools';
|
|
14
14
|
import type { TeamContextSharing } from '../../types/teams';
|
|
15
|
+
import type { AppModeEffect } from '../../types/agentspecs';
|
|
15
16
|
import type { BrowserModelOptions } from './model';
|
|
16
17
|
import type { BrowserSubagent } from './subagents';
|
|
17
18
|
export type BrowserProtocolOptions = {
|
|
@@ -37,6 +38,8 @@ export type BrowserProtocolOptions = {
|
|
|
37
38
|
sharing?: TeamContextSharing;
|
|
38
39
|
/** Told what a delegated run does, as it does it — see `subagentTools`. */
|
|
39
40
|
onSubagentEvent?: (event: AgentStreamSubagentPayload) => void;
|
|
41
|
+
/** What the modes a run is sent in tell it (LOOP P-19); none when unsaid. */
|
|
42
|
+
modeEffect?: (chosen: Record<string, string>) => AppModeEffect;
|
|
40
43
|
};
|
|
41
44
|
/**
|
|
42
45
|
* The protocol config for an agent whose loop runs in this page.
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* keystroke, so an omitted flag reads as a chat that silently ignores typing.
|
|
17
17
|
*/
|
|
18
18
|
export function browserProtocolConfig(options) {
|
|
19
|
-
const { agentId, instructions, model, frontendTools, inference, subagents, sharing, onSubagentEvent, } = options;
|
|
19
|
+
const { agentId, instructions, model, frontendTools, inference, subagents, sharing, onSubagentEvent, modeEffect, } = options;
|
|
20
20
|
return {
|
|
21
21
|
type: 'browser-vercel-ai',
|
|
22
22
|
endpoint: '',
|
|
@@ -30,6 +30,7 @@ export function browserProtocolConfig(options) {
|
|
|
30
30
|
subagents,
|
|
31
31
|
sharing,
|
|
32
32
|
onSubagentEvent,
|
|
33
|
+
modeEffect,
|
|
33
34
|
},
|
|
34
35
|
};
|
|
35
36
|
}
|
package/lib/specs/apps.js
CHANGED
|
@@ -64,6 +64,8 @@ export const ACCOUNTING_APP_0_0_1 = {
|
|
|
64
64
|
message: 'Give the trial balance for last month.',
|
|
65
65
|
},
|
|
66
66
|
],
|
|
67
|
+
commands: [],
|
|
68
|
+
modes: [],
|
|
67
69
|
settings: [],
|
|
68
70
|
components: [],
|
|
69
71
|
assistant: 'wizard',
|
|
@@ -186,6 +188,8 @@ export const CUSTOMER_INTERVIEW_APP_0_0_1 = {
|
|
|
186
188
|
message: 'Interview me about my first week with the product.',
|
|
187
189
|
},
|
|
188
190
|
],
|
|
191
|
+
commands: [],
|
|
192
|
+
modes: [],
|
|
189
193
|
settings: [
|
|
190
194
|
{
|
|
191
195
|
id: 'language',
|
|
@@ -309,6 +313,8 @@ export const DATA_QUALITY_APP_0_0_1 = {
|
|
|
309
313
|
accent: 'green',
|
|
310
314
|
welcome: '',
|
|
311
315
|
starters: [],
|
|
316
|
+
commands: [],
|
|
317
|
+
modes: [],
|
|
312
318
|
settings: [],
|
|
313
319
|
components: [
|
|
314
320
|
'Card',
|
|
@@ -475,6 +481,8 @@ export const DECIDE_APP_0_0_1 = {
|
|
|
475
481
|
message: "Score how positive this review is from 1 to 5: 'Setup took an hour, but support answered fast and it works.'",
|
|
476
482
|
},
|
|
477
483
|
],
|
|
484
|
+
commands: [],
|
|
485
|
+
modes: [],
|
|
478
486
|
settings: [],
|
|
479
487
|
components: [],
|
|
480
488
|
assistant: 'wizard',
|
|
@@ -628,6 +636,8 @@ export const INBOX_TRIAGE_APP_0_0_1 = {
|
|
|
628
636
|
message: 'What arrived since yesterday, and what did you do with it?',
|
|
629
637
|
},
|
|
630
638
|
],
|
|
639
|
+
commands: [],
|
|
640
|
+
modes: [],
|
|
631
641
|
settings: [],
|
|
632
642
|
components: [],
|
|
633
643
|
voice: {
|
|
@@ -761,6 +771,8 @@ export const MODEL_CHOICE_APP_0_0_1 = {
|
|
|
761
771
|
accent: 'green',
|
|
762
772
|
welcome: '',
|
|
763
773
|
starters: [],
|
|
774
|
+
commands: [],
|
|
775
|
+
modes: [],
|
|
764
776
|
settings: [],
|
|
765
777
|
components: [
|
|
766
778
|
'Card',
|
|
@@ -989,6 +1001,8 @@ export const PIPELINE_REPORT_APP_0_0_1 = {
|
|
|
989
1001
|
message: "What changed in the pipeline since last week's report?",
|
|
990
1002
|
},
|
|
991
1003
|
],
|
|
1004
|
+
commands: [],
|
|
1005
|
+
modes: [],
|
|
992
1006
|
settings: [],
|
|
993
1007
|
components: [
|
|
994
1008
|
'Card',
|
|
@@ -1247,6 +1261,8 @@ export const QUOTE_CALCULATOR_APP_0_0_1 = {
|
|
|
1247
1261
|
accent: 'sun',
|
|
1248
1262
|
welcome: '',
|
|
1249
1263
|
starters: [],
|
|
1264
|
+
commands: [],
|
|
1265
|
+
modes: [],
|
|
1250
1266
|
settings: [
|
|
1251
1267
|
{
|
|
1252
1268
|
id: 'seats',
|
|
@@ -1506,6 +1522,8 @@ export const REPORT_FROM_A_FILE_APP_0_0_1 = {
|
|
|
1506
1522
|
accent: 'sky',
|
|
1507
1523
|
welcome: '',
|
|
1508
1524
|
starters: [],
|
|
1525
|
+
commands: [],
|
|
1526
|
+
modes: [],
|
|
1509
1527
|
settings: [
|
|
1510
1528
|
{
|
|
1511
1529
|
id: 'report',
|
|
@@ -1757,6 +1775,8 @@ export const SALES_APP_0_0_1 = {
|
|
|
1757
1775
|
message: 'What does the trial balance say for last month?',
|
|
1758
1776
|
},
|
|
1759
1777
|
],
|
|
1778
|
+
commands: [],
|
|
1779
|
+
modes: [],
|
|
1760
1780
|
settings: [],
|
|
1761
1781
|
components: [],
|
|
1762
1782
|
assistant: 'paperclip',
|
|
@@ -1862,6 +1882,8 @@ export const SHIP_OR_FIX_APP_0_0_1 = {
|
|
|
1862
1882
|
accent: 'green',
|
|
1863
1883
|
welcome: '',
|
|
1864
1884
|
starters: [],
|
|
1885
|
+
commands: [],
|
|
1886
|
+
modes: [],
|
|
1865
1887
|
settings: [],
|
|
1866
1888
|
components: [
|
|
1867
1889
|
'Card',
|
|
@@ -2038,6 +2060,8 @@ export const SUPPLIER_COMPARISON_APP_0_0_1 = {
|
|
|
2038
2060
|
accent: 'green',
|
|
2039
2061
|
welcome: '',
|
|
2040
2062
|
starters: [],
|
|
2063
|
+
commands: [],
|
|
2064
|
+
modes: [],
|
|
2041
2065
|
settings: [],
|
|
2042
2066
|
components: [
|
|
2043
2067
|
'Card',
|
|
@@ -2214,6 +2238,8 @@ export const SUPPORT_DESK_APP_0_0_1 = {
|
|
|
2214
2238
|
message: 'What is the difference between the Team and the Business plan?',
|
|
2215
2239
|
},
|
|
2216
2240
|
],
|
|
2241
|
+
commands: [],
|
|
2242
|
+
modes: [],
|
|
2217
2243
|
settings: [
|
|
2218
2244
|
{
|
|
2219
2245
|
id: 'product',
|
|
@@ -2470,6 +2496,8 @@ export const WEB_RESEARCH_APP_0_0_1 = {
|
|
|
2470
2496
|
message: 'Is it true that most data science projects never reach production? Find the primary source.',
|
|
2471
2497
|
},
|
|
2472
2498
|
],
|
|
2499
|
+
commands: [],
|
|
2500
|
+
modes: [],
|
|
2473
2501
|
settings: [
|
|
2474
2502
|
{
|
|
2475
2503
|
id: 'depth',
|
|
@@ -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,6 +322,22 @@ export const APPSPEC_SCHEMA = {
|
|
|
283
322
|
title: 'Starters',
|
|
284
323
|
type: 'array',
|
|
285
324
|
},
|
|
325
|
+
commands: {
|
|
326
|
+
description: 'Slash commands the user picks in the composer: typing `/` lists them (LOOP P-19)',
|
|
327
|
+
items: {
|
|
328
|
+
$ref: '#/$defs/AppCommand',
|
|
329
|
+
},
|
|
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',
|
|
339
|
+
type: 'array',
|
|
340
|
+
},
|
|
286
341
|
settings: {
|
|
287
342
|
description: 'What the user may set',
|
|
288
343
|
items: {
|
|
@@ -362,6 +417,95 @@ export const APPSPEC_SCHEMA = {
|
|
|
362
417
|
title: 'AppKind',
|
|
363
418
|
type: 'string',
|
|
364
419
|
},
|
|
420
|
+
AppMode: {
|
|
421
|
+
additionalProperties: false,
|
|
422
|
+
description: 'A mode switch in the composer (LOOP P-19): the person picks one of its options.',
|
|
423
|
+
properties: {
|
|
424
|
+
id: {
|
|
425
|
+
description: 'Its id, the key a run says its option under',
|
|
426
|
+
pattern: '^[a-z][a-z0-9_-]{0,39}$',
|
|
427
|
+
title: 'Id',
|
|
428
|
+
type: 'string',
|
|
429
|
+
},
|
|
430
|
+
label: {
|
|
431
|
+
description: 'What the switch is called',
|
|
432
|
+
minLength: 1,
|
|
433
|
+
title: 'Label',
|
|
434
|
+
type: 'string',
|
|
435
|
+
},
|
|
436
|
+
options: {
|
|
437
|
+
description: 'Its positions, two at least',
|
|
438
|
+
items: {
|
|
439
|
+
$ref: '#/$defs/AppModeOption',
|
|
440
|
+
},
|
|
441
|
+
minItems: 2,
|
|
442
|
+
title: 'Options',
|
|
443
|
+
type: 'array',
|
|
444
|
+
},
|
|
445
|
+
default: {
|
|
446
|
+
anyOf: [
|
|
447
|
+
{
|
|
448
|
+
type: 'string',
|
|
449
|
+
},
|
|
450
|
+
{
|
|
451
|
+
type: 'null',
|
|
452
|
+
},
|
|
453
|
+
],
|
|
454
|
+
default: null,
|
|
455
|
+
description: 'The option it starts on; the first when unsaid',
|
|
456
|
+
title: 'Default',
|
|
457
|
+
},
|
|
458
|
+
},
|
|
459
|
+
required: ['id', 'label', 'options'],
|
|
460
|
+
title: 'AppMode',
|
|
461
|
+
type: 'object',
|
|
462
|
+
},
|
|
463
|
+
AppModeOption: {
|
|
464
|
+
additionalProperties: false,
|
|
465
|
+
description: 'One position of a mode switch (LOOP P-19): what the agent is told, the model it runs on.',
|
|
466
|
+
properties: {
|
|
467
|
+
id: {
|
|
468
|
+
description: 'Its id, what a run says it is in',
|
|
469
|
+
pattern: '^[a-z][a-z0-9_-]{0,39}$',
|
|
470
|
+
title: 'Id',
|
|
471
|
+
type: 'string',
|
|
472
|
+
},
|
|
473
|
+
label: {
|
|
474
|
+
description: 'What the switch says',
|
|
475
|
+
minLength: 1,
|
|
476
|
+
title: 'Label',
|
|
477
|
+
type: 'string',
|
|
478
|
+
},
|
|
479
|
+
description: {
|
|
480
|
+
default: '',
|
|
481
|
+
description: 'What it changes, in a sentence',
|
|
482
|
+
title: 'Description',
|
|
483
|
+
type: 'string',
|
|
484
|
+
},
|
|
485
|
+
instructions: {
|
|
486
|
+
default: '',
|
|
487
|
+
description: 'What the agent is told besides its instructions, in every run in this mode',
|
|
488
|
+
title: 'Instructions',
|
|
489
|
+
type: 'string',
|
|
490
|
+
},
|
|
491
|
+
model: {
|
|
492
|
+
anyOf: [
|
|
493
|
+
{
|
|
494
|
+
type: 'string',
|
|
495
|
+
},
|
|
496
|
+
{
|
|
497
|
+
type: 'null',
|
|
498
|
+
},
|
|
499
|
+
],
|
|
500
|
+
default: null,
|
|
501
|
+
description: "The model a run in this mode runs on, in place of the application's",
|
|
502
|
+
title: 'Model',
|
|
503
|
+
},
|
|
504
|
+
},
|
|
505
|
+
required: ['id', 'label'],
|
|
506
|
+
title: 'AppModeOption',
|
|
507
|
+
type: 'object',
|
|
508
|
+
},
|
|
365
509
|
AppPermissions: {
|
|
366
510
|
additionalProperties: false,
|
|
367
511
|
description: 'What the application may reach beside its connections. Nothing, unless said.',
|
|
@@ -667,6 +811,31 @@ export const APPSPEC_SCHEMA = {
|
|
|
667
811
|
title: 'AppTests',
|
|
668
812
|
type: 'object',
|
|
669
813
|
},
|
|
814
|
+
AppTheme: {
|
|
815
|
+
additionalProperties: false,
|
|
816
|
+
description: 'The theme an application runs in by default (LOOP T-30).',
|
|
817
|
+
properties: {
|
|
818
|
+
variant: {
|
|
819
|
+
$ref: '#/$defs/ThemeVariant',
|
|
820
|
+
description: 'The theme: `datalayer`, `spatial`, `lovely`, `matrix`, `earth`, `sand`, `ivory`, `sun` or `loop`',
|
|
821
|
+
},
|
|
822
|
+
mode: {
|
|
823
|
+
anyOf: [
|
|
824
|
+
{
|
|
825
|
+
$ref: '#/$defs/ThemeMode',
|
|
826
|
+
},
|
|
827
|
+
{
|
|
828
|
+
type: 'null',
|
|
829
|
+
},
|
|
830
|
+
],
|
|
831
|
+
default: null,
|
|
832
|
+
description: "`light`, `dark` or `auto` (the device's); the person's own when unsaid",
|
|
833
|
+
},
|
|
834
|
+
},
|
|
835
|
+
required: ['variant'],
|
|
836
|
+
title: 'AppTheme',
|
|
837
|
+
type: 'object',
|
|
838
|
+
},
|
|
670
839
|
AppTrigger: {
|
|
671
840
|
additionalProperties: false,
|
|
672
841
|
description: "What starts a worker's work.",
|
|
@@ -943,6 +1112,28 @@ export const APPSPEC_SCHEMA = {
|
|
|
943
1112
|
title: 'SettingType',
|
|
944
1113
|
type: 'string',
|
|
945
1114
|
},
|
|
1115
|
+
ThemeMode: {
|
|
1116
|
+
description: 'The colour mode a theme is worn in: `auto` follows the device.',
|
|
1117
|
+
enum: ['light', 'dark', 'auto'],
|
|
1118
|
+
title: 'ThemeMode',
|
|
1119
|
+
type: 'string',
|
|
1120
|
+
},
|
|
1121
|
+
ThemeVariant: {
|
|
1122
|
+
description: "A theme of Datalayer's, as Appearance names it (LOOP T-30).",
|
|
1123
|
+
enum: [
|
|
1124
|
+
'datalayer',
|
|
1125
|
+
'spatial',
|
|
1126
|
+
'lovely',
|
|
1127
|
+
'matrix',
|
|
1128
|
+
'earth',
|
|
1129
|
+
'sand',
|
|
1130
|
+
'ivory',
|
|
1131
|
+
'sun',
|
|
1132
|
+
'loop',
|
|
1133
|
+
],
|
|
1134
|
+
title: 'ThemeVariant',
|
|
1135
|
+
type: 'string',
|
|
1136
|
+
},
|
|
946
1137
|
TriggerType: {
|
|
947
1138
|
description: 'What starts a worker: the trigger kinds of the catalogue.',
|
|
948
1139
|
enum: ['schedule', 'event', 'once'],
|
|
@@ -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,6 +447,44 @@ export interface AppStarterSpec {
|
|
|
434
447
|
label: string;
|
|
435
448
|
message: string;
|
|
436
449
|
}
|
|
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 {
|
|
461
|
+
id: string;
|
|
462
|
+
label: string;
|
|
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;
|
|
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
|
+
}
|
|
437
488
|
export interface AppSettingSpec {
|
|
438
489
|
id: string;
|
|
439
490
|
type: 'select' | 'text' | 'toggle' | 'slider' | 'number';
|
|
@@ -471,9 +522,16 @@ export interface AppVoiceSpec {
|
|
|
471
522
|
/** What the user of an application sees. */
|
|
472
523
|
export interface AppInterfaceSpec {
|
|
473
524
|
layout: AppLayout;
|
|
525
|
+
/** Its one colour, over the `loop` theme only. */
|
|
474
526
|
accent: AppAccent;
|
|
527
|
+
/** The theme it runs in by default; the person's own when unsaid (T-30). */
|
|
528
|
+
theme?: AppThemeSpec;
|
|
475
529
|
welcome: string;
|
|
476
530
|
starters: AppStarterSpec[];
|
|
531
|
+
/** Slash commands picked in the composer: typing `/` lists them (P-19). */
|
|
532
|
+
commands: AppCommandSpec[];
|
|
533
|
+
/** Mode switches in the composer, the option picked going with every run (P-19). */
|
|
534
|
+
modes: AppModeSpec[];
|
|
477
535
|
settings: AppSettingSpec[];
|
|
478
536
|
/** The components of the catalog the surface may use. */
|
|
479
537
|
components: string[];
|
package/lib/types/chat.d.ts
CHANGED
|
@@ -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
|
|
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
|
@@ -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))
|
|
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))
|
|
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)
|
|
@@ -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)'",
|
|
211
|
+
r"from '\.\./(mcpServers|skills|backendTools|frontendTools)'",
|
|
212
|
+
r"from './\1'",
|
|
213
|
+
head,
|
|
212
214
|
)
|
|
213
215
|
|
|
214
216
|
lines = [
|