@datalayer/agent-runtimes 1.5.26 → 1.5.28
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/dist-embed/chunks/{ChatView-CUWE6I5M.js → ChatView-C0PWJ_wj.js} +4 -4
- package/dist-embed/datalayer-app-main.js +111 -101
- package/lib/apps/apps/AppKept.js +5 -1
- package/lib/apps/embed/element.js +10 -4
- package/lib/apps/embed/embedConfig.d.ts +10 -1
- package/lib/apps/embed/embedConfig.js +25 -1
- package/lib/apps/plugins/chat/ChatView.js +2 -2
- package/lib/chat/assistant/AssistantStage.js +17 -0
- package/lib/chat/assistant/clearance.d.ts +10 -0
- package/lib/chat/assistant/clearance.js +14 -0
- package/lib/chat/base/ChatBase.js +375 -437
- package/lib/chat/base/conversationItems.d.ts +55 -0
- package/lib/chat/base/conversationItems.js +126 -0
- package/lib/portable/adapterEvents.d.ts +107 -0
- package/lib/portable/adapterEvents.js +239 -0
- package/lib/portable/approvalCard.d.ts +56 -0
- package/lib/portable/approvalCard.js +56 -0
- package/lib/portable/conversation.d.ts +71 -18
- package/lib/portable/conversation.js +330 -74
- package/lib/portable/fixtures.js +12 -0
- package/lib/portable/index.d.ts +4 -1
- package/lib/portable/index.js +7 -1
- package/lib/portable/presence.js +4 -1
- package/lib/portable/runMeasures.d.ts +46 -0
- package/lib/portable/runMeasures.js +156 -0
- package/lib/protocols/ACPAdapter.js +13 -8
- package/lib/specs/voices.js +47 -0
- package/lib/utils/utils.d.ts +2 -8
- package/lib/utils/utils.js +3 -26
- package/lib/voice/ComposerVoice.js +25 -3
- package/lib/voice/VoiceInput.d.ts +2 -2
- package/lib/voice/VoiceInput.js +6 -4
- package/lib/voice/VoiceMenu.js +2 -1
- package/lib/voice/chatVoice.d.ts +4 -3
- package/lib/voice/chatVoice.js +6 -9
- package/lib/voice/consent.d.ts +8 -0
- package/lib/voice/consent.js +10 -0
- package/lib/voice/hearing.d.ts +23 -1
- package/lib/voice/hearing.js +18 -3
- package/lib/voice/index.d.ts +11 -6
- package/lib/voice/index.js +1 -0
- package/lib/voice/serverHearing.d.ts +58 -0
- package/lib/voice/serverHearing.js +136 -0
- package/lib/voice/settings.d.ts +5 -0
- package/lib/voice/settings.js +8 -0
- package/lib/voice/speaker.d.ts +4 -3
- package/lib/voice/speaker.js +1 -2
- package/lib/voice/useVoiceSpeaker.js +0 -3
- package/package.json +2 -2
package/lib/apps/apps/AppKept.js
CHANGED
|
@@ -4,6 +4,7 @@ import { contribution, definePlugin, signal } from '@datalayer/reactor';
|
|
|
4
4
|
import { useContributions, useSignalValue } from '@datalayer/reactor/react';
|
|
5
5
|
import { LoopChatTurn, LoopPromptPanel } from '../core';
|
|
6
6
|
import { beforeFirstMessage } from './kept';
|
|
7
|
+
import { ASSISTANT_CLEARANCE_VAR } from '../../chat/assistant/clearance';
|
|
7
8
|
export const APP_KEPT_PLUGIN_NAME = '@datalayer/loop-plugin-app-kept';
|
|
8
9
|
/* A signal to read when no chat contributed a turn: the hook needs one. */
|
|
9
10
|
const NO_TURN = signal({ id: 0, status: 'idle' });
|
|
@@ -13,7 +14,10 @@ export function AppKept({ says }) {
|
|
|
13
14
|
if (!beforeFirstMessage(turn)) {
|
|
14
15
|
return null;
|
|
15
16
|
}
|
|
16
|
-
return (
|
|
17
|
+
return (
|
|
18
|
+
// Clear of the floating assistant in its corner, at a phone's width too
|
|
19
|
+
// (REVIEWS Q-08).
|
|
20
|
+
_jsx("div", { role: "note", style: { padding: `4px var(${ASSISTANT_CLEARANCE_VAR}, 8px) 4px 8px` }, children: _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: says }) }));
|
|
17
21
|
}
|
|
18
22
|
/**
|
|
19
23
|
* The plugin, for one application: what it keeps, under its prompt. Made
|
|
@@ -70,7 +70,7 @@ import { parseAppspec } from '../apps/appspec';
|
|
|
70
70
|
import { readAppspecYaml } from '../apps/yaml';
|
|
71
71
|
import { AppEmbed, embedAssistantCharacter } from './AppEmbed';
|
|
72
72
|
import { WINDOW_NOT_YET } from './embedSession';
|
|
73
|
-
import { EMBED_HOST_VARIABLES, EMBED_OBSERVED_ATTRIBUTES, EMBED_TAG, EmbedAttributeError, adoptPropertiesSetEarly, embedLookOf, inlineHeightOf, languageOf, resumeOf, runnable, } from './embedConfig';
|
|
73
|
+
import { EMBED_HOST_VARIABLES, EMBED_OBSERVED_ATTRIBUTES, EMBED_TAG, EMBED_TOKEN_NAMES_NO_DEPLOYMENT, EmbedAttributeError, adoptPropertiesSetEarly, embedLookOf, embedTokenDeployment, inlineHeightOf, languageOf, resumeOf, runnable, } from './embedConfig';
|
|
74
74
|
import { embedShadowCss } from './embedTheme';
|
|
75
75
|
import { DEFAULT_API, readVisitorApp } from './visitorApp';
|
|
76
76
|
export { runnable };
|
|
@@ -164,9 +164,15 @@ export async function readEmbeddedApp({ api, origin, app, token, fetcher = fetch
|
|
|
164
164
|
return { kind: 'frame', src: frameSrcOf(origin, app, token) };
|
|
165
165
|
}
|
|
166
166
|
const spec = runnable(parseAppspec(definition.spec));
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
167
|
+
if (spec.kind === 'decision') {
|
|
168
|
+
return { kind: 'frame', src: frameSrcOf(origin, app, token) };
|
|
169
|
+
}
|
|
170
|
+
// The visit runs the deployment its token names, and no other (VOICE.md
|
|
171
|
+
// decision 16): a token naming none is refused before anything is drawn.
|
|
172
|
+
if (!embedTokenDeployment(token)) {
|
|
173
|
+
return { kind: 'said', text: EMBED_TOKEN_NAMES_NO_DEPLOYMENT };
|
|
174
|
+
}
|
|
175
|
+
return { kind: 'spec', app: spec };
|
|
170
176
|
}
|
|
171
177
|
/** The script that is running, when it is a script tag. */
|
|
172
178
|
function currentScriptUrl() {
|
|
@@ -25,7 +25,7 @@ export declare const EMBED_STYLESHEET_PATH = "/embed/datalayer-app.css";
|
|
|
25
25
|
export declare const EMBED_ATTRIBUTES: {
|
|
26
26
|
readonly app: "The application’s id on Datalayer.";
|
|
27
27
|
readonly origin: "Where Datalayer is; the origin the script was loaded from by default.";
|
|
28
|
-
readonly token: "An embed token for an application that is not public, issued to your server for each visit.";
|
|
28
|
+
readonly token: "An embed token for an application that is not public, issued to your server for each visit; it names the embedded deployment the visit runs, which nothing else on the page names.";
|
|
29
29
|
readonly spec: "The address of an Appspec (YAML or JSON) to run, in place of `app`.";
|
|
30
30
|
readonly mode: "inline, bubble, panel or assistant; the Appspec’s `deployment.embedded.mode` by default, then inline.";
|
|
31
31
|
readonly accent: "green, rose, sky, lime, sun or violet; the Appspec’s `interface.accent` by default, else the theme’s own colours.";
|
|
@@ -39,6 +39,15 @@ export declare const EMBED_ATTRIBUTES: {
|
|
|
39
39
|
readonly 'user-token': "A token your server signed with the deployment’s secret, naming your user (HS256: sub, name, exp at most an hour away): what an application that says user: signed opens its session with.";
|
|
40
40
|
};
|
|
41
41
|
export type EmbedAttribute = keyof typeof EMBED_ATTRIBUTES;
|
|
42
|
+
/**
|
|
43
|
+
* The deployment an embed token names (VOICE.md decision 16): the embedded
|
|
44
|
+
* deployment its owner's server asked it for. Read without vouching for it —
|
|
45
|
+
* the services that take the token verify it — and the only place the
|
|
46
|
+
* element learns its deployment: it takes no attribute for one.
|
|
47
|
+
*/
|
|
48
|
+
export declare function embedTokenDeployment(token: string): string | undefined;
|
|
49
|
+
/** What an embed token naming no deployment is told (VOICE.md decision 16). */
|
|
50
|
+
export declare const EMBED_TOKEN_NAMES_NO_DEPLOYMENT = "datalayer-app: the embed token names no deployment. Your server asks for one naming the application\u2019s embedded deployment: POST \u2026/api/spacer/v1/apps/<id>/embed-token with {\"deployment\": \"<its uid>\"}.";
|
|
42
51
|
/** Every attribute the element watches. */
|
|
43
52
|
export declare const EMBED_OBSERVED_ATTRIBUTES: EmbedAttribute[];
|
|
44
53
|
/**
|
|
@@ -16,7 +16,7 @@ export const EMBED_STYLESHEET_PATH = '/embed/datalayer-app.css';
|
|
|
16
16
|
export const EMBED_ATTRIBUTES = {
|
|
17
17
|
app: 'The application’s id on Datalayer.',
|
|
18
18
|
origin: 'Where Datalayer is; the origin the script was loaded from by default.',
|
|
19
|
-
token: 'An embed token for an application that is not public, issued to your server for each visit.',
|
|
19
|
+
token: 'An embed token for an application that is not public, issued to your server for each visit; it names the embedded deployment the visit runs, which nothing else on the page names.',
|
|
20
20
|
spec: 'The address of an Appspec (YAML or JSON) to run, in place of `app`.',
|
|
21
21
|
mode: 'inline, bubble, panel or assistant; the Appspec’s `deployment.embedded.mode` by default, then inline.',
|
|
22
22
|
accent: 'green, rose, sky, lime, sun or violet; the Appspec’s `interface.accent` by default, else the theme’s own colours.',
|
|
@@ -29,6 +29,30 @@ export const EMBED_ATTRIBUTES = {
|
|
|
29
29
|
language: 'The language the visitor reads the application in, as BCP 47 tags it (fr, pt-BR): its translation into it, and the chat’s own words; the visitor’s browser’s by default.',
|
|
30
30
|
'user-token': 'A token your server signed with the deployment’s secret, naming your user (HS256: sub, name, exp at most an hour away): what an application that says user: signed opens its session with.',
|
|
31
31
|
};
|
|
32
|
+
/**
|
|
33
|
+
* The deployment an embed token names (VOICE.md decision 16): the embedded
|
|
34
|
+
* deployment its owner's server asked it for. Read without vouching for it —
|
|
35
|
+
* the services that take the token verify it — and the only place the
|
|
36
|
+
* element learns its deployment: it takes no attribute for one.
|
|
37
|
+
*/
|
|
38
|
+
export function embedTokenDeployment(token) {
|
|
39
|
+
const payload = token.split('.')[1];
|
|
40
|
+
if (!payload) {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
const base64 = payload.replace(/-/g, '+').replace(/_/g, '/');
|
|
45
|
+
const claims = JSON.parse(atob(base64.padEnd(base64.length + ((4 - (base64.length % 4)) % 4), '=')));
|
|
46
|
+
return typeof claims.deployment_uid === 'string' && claims.deployment_uid
|
|
47
|
+
? claims.deployment_uid
|
|
48
|
+
: undefined;
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/** What an embed token naming no deployment is told (VOICE.md decision 16). */
|
|
55
|
+
export const EMBED_TOKEN_NAMES_NO_DEPLOYMENT = 'datalayer-app: the embed token names no deployment. Your server asks for one naming the application’s embedded deployment: POST …/api/spacer/v1/apps/<id>/embed-token with {"deployment": "<its uid>"}.';
|
|
32
56
|
/** Every attribute the element watches. */
|
|
33
57
|
export const EMBED_OBSERVED_ATTRIBUTES = Object.keys(EMBED_ATTRIBUTES);
|
|
34
58
|
/**
|
|
@@ -1321,9 +1321,9 @@ export default function ChatView({ workspace }) {
|
|
|
1321
1321
|
/*
|
|
1322
1322
|
* Its voice asked of the speech service as this chat speaks to its runtime
|
|
1323
1323
|
* (VOICE.md VO-37, VO-19): the host's token, else this one — a visitor's,
|
|
1324
|
-
* an embed's or the person's
|
|
1324
|
+
* an embed's or the person's; an embed's names its deployment (decision 16).
|
|
1325
1325
|
*/
|
|
1326
|
-
const askedVoice = useMemo(() => voiceAskedAs(config?.voice, iamToken || undefined
|
|
1326
|
+
const askedVoice = useMemo(() => voiceAskedAs(config?.voice, iamToken || undefined), [config?.voice, iamToken]);
|
|
1327
1327
|
/*
|
|
1328
1328
|
* A deployment's runtime, and the visitors', answer only the application's
|
|
1329
1329
|
* own routes (OwnRoutesOnly, PAP_DATALAYER's release gates): its chat calls
|
|
@@ -7,6 +7,7 @@ import { Dialog, Text } from '@primer/react';
|
|
|
7
7
|
import { assistantCharacter } from './characters';
|
|
8
8
|
import { BalloonHistoryLarge, SpeechBalloon, } from './SpeechBalloon';
|
|
9
9
|
import { conversationHeaderText } from './BalloonParts';
|
|
10
|
+
import { ASSISTANT_CLEARANCE_VAR } from './clearance';
|
|
10
11
|
import { AssistantContextMenu, LONG_PRESS_MS, opensContextMenu, } from './AssistantContextMenu';
|
|
11
12
|
import { BalloonExpandContext, ExpandedVisual, focusExpanded, } from './BalloonVisual';
|
|
12
13
|
import { SpriteCharacter } from './SpriteCharacter';
|
|
@@ -405,6 +406,22 @@ export function AssistantStage({ character, state, size = 88, place, stageRef, o
|
|
|
405
406
|
telling ||
|
|
406
407
|
detailing !== null ||
|
|
407
408
|
stayPut);
|
|
409
|
+
// What it covers in its corner, for a line written under a prompt there
|
|
410
|
+
// (REVIEWS Q-08).
|
|
411
|
+
const cornerRight = place.left === undefined && place.top === undefined
|
|
412
|
+
? pixels(place.right)
|
|
413
|
+
: undefined;
|
|
414
|
+
const cornerBottom = pixels(place.bottom);
|
|
415
|
+
useEffect(() => {
|
|
416
|
+
if (aside || cornerRight === undefined || cornerBottom === undefined) {
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
const root = document.documentElement;
|
|
420
|
+
root.style.setProperty(ASSISTANT_CLEARANCE_VAR, `${cornerRight + size}px`);
|
|
421
|
+
return () => {
|
|
422
|
+
root.style.removeProperty(ASSISTANT_CLEARANCE_VAR);
|
|
423
|
+
};
|
|
424
|
+
}, [aside, cornerRight, cornerBottom, size]);
|
|
408
425
|
useMouth(stageRef, mouthLevel, state === 'speaking');
|
|
409
426
|
// A decision being asked, or its answer, keeps the balloon up.
|
|
410
427
|
const [deciding, setDeciding] = useState(false);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the floating assistant covers from the right edge of the window while
|
|
3
|
+
* it stands in a bottom corner, as a CSS length on the document: a line
|
|
4
|
+
* written under a prompt there (what an application keeps, R-31) leaves it
|
|
5
|
+
* free, so that the character never stands over its words at a phone's width
|
|
6
|
+
* (REVIEWS Q-08). Unset when it stands anywhere else, steps aside or is gone.
|
|
7
|
+
*
|
|
8
|
+
* @module chat/assistant/clearance
|
|
9
|
+
*/
|
|
10
|
+
export declare const ASSISTANT_CLEARANCE_VAR = "--assistant-clearance";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* What the floating assistant covers from the right edge of the window while
|
|
7
|
+
* it stands in a bottom corner, as a CSS length on the document: a line
|
|
8
|
+
* written under a prompt there (what an application keeps, R-31) leaves it
|
|
9
|
+
* free, so that the character never stands over its words at a phone's width
|
|
10
|
+
* (REVIEWS Q-08). Unset when it stands anywhere else, steps aside or is gone.
|
|
11
|
+
*
|
|
12
|
+
* @module chat/assistant/clearance
|
|
13
|
+
*/
|
|
14
|
+
export const ASSISTANT_CLEARANCE_VAR = '--assistant-clearance';
|