@datalayer/agent-runtimes 1.5.13 → 1.5.15
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/datalayer-app-main.js +4 -4
- package/lib/apps/apps/records.d.ts +23 -0
- package/lib/apps/apps/records.js +48 -5
- package/lib/apps/embed/embedSession.js +9 -1
- package/lib/apps/plugins/app-activity/AppActivity.js +2 -2
- package/lib/apps/plugins/pap-sign-in/PapSignInCard.js +4 -0
- package/lib/components/teams/sceneTranscript.js +3 -2
- package/lib/specs/apps.js +10 -7
- package/package.json +1 -1
|
@@ -38,6 +38,29 @@ export type RecordsContext = {
|
|
|
38
38
|
export declare const RECORD_KIND_WORDS: Record<RecordKind, string>;
|
|
39
39
|
/** An entry as ai-agents answers with it. */
|
|
40
40
|
export declare function entryOf(raw: Record<string, unknown>): RecordEntry;
|
|
41
|
+
/**
|
|
42
|
+
* How a run ended, in the `output` entry every run ends with, kept whatever
|
|
43
|
+
* the application's `record.include` says (PAP_DATALAYER R-01): its words
|
|
44
|
+
* only when it keeps `outputs`.
|
|
45
|
+
*/
|
|
46
|
+
export declare const RUN_END_WORDS: Record<string, string>;
|
|
47
|
+
/** How the run an entry ends ended: `answered`, `stopped`, `gone`; `''` for any other entry. */
|
|
48
|
+
export declare function runEndOf(entry: RecordEntry): string;
|
|
49
|
+
/** An entry in words: its summary, or how its run ended when its words are not kept. */
|
|
50
|
+
export declare function entrySaid(entry: RecordEntry): string;
|
|
51
|
+
/**
|
|
52
|
+
* The mark around what the runtime tells an application of a turn a personal
|
|
53
|
+
* agent asked over PAP or PACT, before the request (`asked_for_said`,
|
|
54
|
+
* `ASKED_FOR_TAG` in agent_runtimes.loop.apps.pap_company).
|
|
55
|
+
*/
|
|
56
|
+
export declare const ASKED_FOR_TAG = "asked-for";
|
|
57
|
+
/**
|
|
58
|
+
* What a person asked, as they are shown it: without what the runtime told
|
|
59
|
+
* the application before their words (PAP_DATALAYER, decided 2026-10-14).
|
|
60
|
+
* The record keeps it for the application's builder; the person never wrote
|
|
61
|
+
* it, so *Your conversations* and a thread opened again leave it out.
|
|
62
|
+
*/
|
|
63
|
+
export declare function askedOf(text: string): string;
|
|
41
64
|
/** A session in a sentence: how many calls, what stopped it, how it ended. */
|
|
42
65
|
export declare function sessionSentence(entries: readonly RecordEntry[]): string;
|
|
43
66
|
/**
|
package/lib/apps/apps/records.js
CHANGED
|
@@ -30,12 +30,55 @@ export function entryOf(raw) {
|
|
|
30
30
|
createdAt: String(raw.created_at ?? ''),
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* How a run ended, in the `output` entry every run ends with, kept whatever
|
|
35
|
+
* the application's `record.include` says (PAP_DATALAYER R-01): its words
|
|
36
|
+
* only when it keeps `outputs`.
|
|
37
|
+
*/
|
|
38
|
+
export const RUN_END_WORDS = {
|
|
39
|
+
answered: 'Answered',
|
|
40
|
+
stopped: 'Stopped',
|
|
41
|
+
gone: 'Its client went before the answer',
|
|
42
|
+
};
|
|
43
|
+
/** How the run an entry ends ended: `answered`, `stopped`, `gone`; `''` for any other entry. */
|
|
44
|
+
export function runEndOf(entry) {
|
|
45
|
+
const status = entry.kind === 'output' ? entry.payload.status : undefined;
|
|
46
|
+
return typeof status === 'string' && status in RUN_END_WORDS ? status : '';
|
|
47
|
+
}
|
|
48
|
+
/** An entry in words: its summary, or how its run ended when its words are not kept. */
|
|
49
|
+
export function entrySaid(entry) {
|
|
50
|
+
return entry.summary || RUN_END_WORDS[runEndOf(entry)] || '';
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The mark around what the runtime tells an application of a turn a personal
|
|
54
|
+
* agent asked over PAP or PACT, before the request (`asked_for_said`,
|
|
55
|
+
* `ASKED_FOR_TAG` in agent_runtimes.loop.apps.pap_company).
|
|
56
|
+
*/
|
|
57
|
+
export const ASKED_FOR_TAG = 'asked-for';
|
|
58
|
+
/**
|
|
59
|
+
* What a person asked, as they are shown it: without what the runtime told
|
|
60
|
+
* the application before their words (PAP_DATALAYER, decided 2026-10-14).
|
|
61
|
+
* The record keeps it for the application's builder; the person never wrote
|
|
62
|
+
* it, so *Your conversations* and a thread opened again leave it out.
|
|
63
|
+
*/
|
|
64
|
+
export function askedOf(text) {
|
|
65
|
+
const open = `<${ASKED_FOR_TAG}>`;
|
|
66
|
+
const close = `</${ASKED_FOR_TAG}>`;
|
|
67
|
+
if (!text.startsWith(open)) {
|
|
68
|
+
return text;
|
|
69
|
+
}
|
|
70
|
+
const end = text.indexOf(close);
|
|
71
|
+
if (end < 0) {
|
|
72
|
+
throw new Error(`What was asked opens <${ASKED_FOR_TAG}> and never closes it.`);
|
|
73
|
+
}
|
|
74
|
+
return text.slice(end + close.length).trimStart();
|
|
75
|
+
}
|
|
33
76
|
/** A session in a sentence: how many calls, what stopped it, how it ended. */
|
|
34
77
|
export function sessionSentence(entries) {
|
|
35
78
|
const calls = entries.filter(entry => entry.kind === 'tool_call').length;
|
|
36
79
|
const checks = entries.filter(entry => entry.kind === 'check');
|
|
37
|
-
const
|
|
38
|
-
const
|
|
80
|
+
const ends = entries.map(runEndOf).filter(Boolean);
|
|
81
|
+
const answers = ends.filter(end => end === 'answered').length;
|
|
39
82
|
const parts = [
|
|
40
83
|
calls === 0
|
|
41
84
|
? 'No tool called'
|
|
@@ -44,11 +87,11 @@ export function sessionSentence(entries) {
|
|
|
44
87
|
if (checks.length) {
|
|
45
88
|
parts.push(`${checks.length} step${checks.length === 1 ? '' : 's'} a check did not let pass`);
|
|
46
89
|
}
|
|
47
|
-
if (
|
|
90
|
+
if (ends[ends.length - 1] === 'stopped') {
|
|
48
91
|
parts.push('stopped');
|
|
49
92
|
}
|
|
50
|
-
else if (
|
|
51
|
-
parts.push(`${
|
|
93
|
+
else if (answers) {
|
|
94
|
+
parts.push(`${answers} answer${answers === 1 ? '' : 's'}`);
|
|
52
95
|
}
|
|
53
96
|
return `${parts.join(', ')}.`;
|
|
54
97
|
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { windowTurnErrorOf } from '../../chat/base/loopWindow';
|
|
6
6
|
import { AGUI_NAME } from '@datalayer/reactor/ui';
|
|
7
|
+
import { askedOf } from '../apps/records';
|
|
7
8
|
/** Where a visit's session is kept in the host's storage: `<prefix>:<app>:<visit>`. */
|
|
8
9
|
export const EMBED_SESSION_KEY_PREFIX = 'datalayer-app:session';
|
|
9
10
|
/**
|
|
@@ -115,7 +116,14 @@ export function messagesOfThread(messages) {
|
|
|
115
116
|
typeof id === 'string' &&
|
|
116
117
|
typeof content === 'string' &&
|
|
117
118
|
content.trim()) {
|
|
118
|
-
|
|
119
|
+
// A turn a personal agent asked: what the runtime told the application
|
|
120
|
+
// before the person's words is never shown to them (decided 2026-10-14).
|
|
121
|
+
drawn.push({
|
|
122
|
+
id,
|
|
123
|
+
role,
|
|
124
|
+
content: role === 'user' ? askedOf(content) : content,
|
|
125
|
+
createdAt: new Date(),
|
|
126
|
+
});
|
|
119
127
|
}
|
|
120
128
|
}
|
|
121
129
|
return drawn;
|
|
@@ -7,7 +7,7 @@ import { useContributions, useSignalValue } from '@datalayer/reactor/react';
|
|
|
7
7
|
import { useCoreStore } from '@datalayer/core/lib/state';
|
|
8
8
|
import { useIAMStore } from '@datalayer/core/lib/state/substates/IAMState';
|
|
9
9
|
import { LoopChatTurn } from '../../core';
|
|
10
|
-
import { RECORD_KIND_WORDS, listSessions, readSession, sessionSentence, } from '../../apps/records';
|
|
10
|
+
import { RECORD_KIND_WORDS, entrySaid, listSessions, readSession, sessionSentence, } from '../../apps/records';
|
|
11
11
|
/** What the feed says. */
|
|
12
12
|
export const APP_ACTIVITY_WORDS = {
|
|
13
13
|
title: 'Activity',
|
|
@@ -40,7 +40,7 @@ function useRead(load, key, when = true) {
|
|
|
40
40
|
function Session({ context, session, }) {
|
|
41
41
|
const [open, setOpen] = useState(false);
|
|
42
42
|
const entries = useRead(() => readSession(context, session.sessionUid), `${session.sessionUid}:${context.token}`, open);
|
|
43
|
-
return (_jsxs(Box, { as: "details", onToggle: (event) => setOpen(event.currentTarget.open), borderTop: "1px solid", borderColor: "border.muted", py: 2, children: [_jsxs(Box, { as: "summary", cursor: "pointer", fontSize: 1, children: [session.createdAt ? (_jsx(RelativeTime, { datetime: session.createdAt })) : ('A session'), session.version ? ` · version ${session.version}` : '', entries.value ? ` · ${sessionSentence(entries.value)}` : ''] }), !open ? null : entries.loading ? (_jsx(Spinner, { size: "small" })) : entries.error ? (_jsx(Text, { role: "alert", sx: { fontSize: 1 }, children: entries.error })) : (_jsx(Box, { as: "ol", pl: 3, mt: 2, mb: 0, fontSize: 1, children: (entries.value ?? []).map(entry => (_jsxs(Box, { as: "li", mb: 1, children: [_jsx(Label, { sx: { mr: 2 }, children: RECORD_KIND_WORDS[entry.kind] ?? entry.kind }), entry
|
|
43
|
+
return (_jsxs(Box, { as: "details", onToggle: (event) => setOpen(event.currentTarget.open), borderTop: "1px solid", borderColor: "border.muted", py: 2, children: [_jsxs(Box, { as: "summary", cursor: "pointer", fontSize: 1, children: [session.createdAt ? (_jsx(RelativeTime, { datetime: session.createdAt })) : ('A session'), session.version ? ` · version ${session.version}` : '', entries.value ? ` · ${sessionSentence(entries.value)}` : ''] }), !open ? null : entries.loading ? (_jsx(Spinner, { size: "small" })) : entries.error ? (_jsx(Text, { role: "alert", sx: { fontSize: 1 }, children: entries.error })) : (_jsx(Box, { as: "ol", pl: 3, mt: 2, mb: 0, fontSize: 1, children: (entries.value ?? []).map(entry => (_jsxs(Box, { as: "li", mb: 1, children: [_jsx(Label, { sx: { mr: 2 }, children: RECORD_KIND_WORDS[entry.kind] ?? entry.kind }), entrySaid(entry)] }, entry.uid))) }))] }));
|
|
44
44
|
}
|
|
45
45
|
export function AppActivity({ appUid }) {
|
|
46
46
|
const token = useIAMStore(state => state.token) ?? '';
|
|
@@ -24,6 +24,10 @@ export function PapSignInCard({ context, send, }) {
|
|
|
24
24
|
const outcome = signInReturnOf(event.data, company);
|
|
25
25
|
if (outcome) {
|
|
26
26
|
setReturned(outcome);
|
|
27
|
+
// One return per card: a card that heard its sign-in come back (a denial
|
|
28
|
+
// too) leaves the next one at that company to the card that started it,
|
|
29
|
+
// never sending twice into a run under way (found on :3063, 13 October 2026).
|
|
30
|
+
channel.close();
|
|
27
31
|
}
|
|
28
32
|
};
|
|
29
33
|
return () => channel.close();
|
|
@@ -255,8 +255,9 @@ export function transcriptOfRecord(entries, member) {
|
|
|
255
255
|
}
|
|
256
256
|
answered = true;
|
|
257
257
|
}
|
|
258
|
-
else if (entry.kind === 'output' && !answered) {
|
|
259
|
-
// A record kept without its conversations: the answer's summary
|
|
258
|
+
else if (entry.kind === 'output' && !answered && entry.summary) {
|
|
259
|
+
// A record kept without its conversations: the answer's summary —
|
|
260
|
+
// none when it keeps no outputs either, only how the run ended.
|
|
260
261
|
pending.push({
|
|
261
262
|
key: `${entry.uid}:said`,
|
|
262
263
|
at,
|
package/lib/specs/apps.js
CHANGED
|
@@ -1779,12 +1779,14 @@ export const EXCHANGE_DESK_APP_0_0_2 = {
|
|
|
1779
1779
|
},
|
|
1780
1780
|
],
|
|
1781
1781
|
verified: {
|
|
1782
|
-
live: [
|
|
1782
|
+
live: [
|
|
1783
|
+
"Drilled on r1 on 14 October 2026 (runtime image 0.0.34): shipped at its own domain, asked by a person's own agent signed in through Datalayer with orders:read and orders:write, asked to exchange order ord_7Hk2 for size L, it proposed the exchange (Exchange order ord_7Hk2 for size L., awaiting the person's approval) and went on to tell them in its own words that nothing was done yet.",
|
|
1784
|
+
],
|
|
1783
1785
|
recorded: [
|
|
1784
1786
|
"Its exchange_order runs in process in Datalayer's own tests against a stand-in for Manzanita's back office: one exchange per confirmed operation, a retry answered as already done.",
|
|
1785
1787
|
],
|
|
1786
1788
|
unverified: [
|
|
1787
|
-
"Drilled on r1 on 13 October 2026, twice: shipped at its own domain, it answered a personal agent signed out, and a person signed in through Datalayer granted orders:read and orders:write. The second time it knew who had signed in, but asked to exchange, it looked for the order first and proposed nothing; it now proposes the exchange at once, and Manzanita checks the order when it is done. Drilled a third time the same evening: signed in, asked to exchange, it said it could not — asked by a person's own agent, it was not given its exchange_order (fixed, not
|
|
1789
|
+
"Drilled on r1 on 13 October 2026, twice: shipped at its own domain, it answered a personal agent signed out, and a person signed in through Datalayer granted orders:read and orders:write. The second time it knew who had signed in, but asked to exchange, it looked for the order first and proposed nothing; it now proposes the exchange at once, and Manzanita checks the order when it is done. Drilled a third time the same evening: signed in, asked to exchange, it said it could not — asked by a person's own agent, it was not given its exchange_order (fixed). Drilled a fourth time the same night, given it: proposing the exchange ended its answer, and the personal agent was told it could not answer just now (fixed, released in runtime image 0.0.34).",
|
|
1788
1790
|
],
|
|
1789
1791
|
},
|
|
1790
1792
|
},
|
|
@@ -1814,8 +1816,8 @@ export const EXCHANGE_DESK_APP_0_0_2 = {
|
|
|
1814
1816
|
documents: [],
|
|
1815
1817
|
alternatives: [],
|
|
1816
1818
|
},
|
|
1817
|
-
enabled:
|
|
1818
|
-
unavailable_because:
|
|
1819
|
+
enabled: true,
|
|
1820
|
+
unavailable_because: '',
|
|
1819
1821
|
tags: ['example', 'companies', 'python'],
|
|
1820
1822
|
icon: 'apps',
|
|
1821
1823
|
emoji: '🏪',
|
|
@@ -7029,11 +7031,14 @@ export const APP_SOURCES = {
|
|
|
7029
7031
|
},
|
|
7030
7032
|
],
|
|
7031
7033
|
verified: {
|
|
7034
|
+
live: [
|
|
7035
|
+
"Drilled on r1 on 14 October 2026 (runtime image 0.0.34): shipped at its own domain, asked by a person's own agent signed in through Datalayer with orders:read and orders:write, asked to exchange order ord_7Hk2 for size L, it proposed the exchange (Exchange order ord_7Hk2 for size L., awaiting the person's approval) and went on to tell them in its own words that nothing was done yet.",
|
|
7036
|
+
],
|
|
7032
7037
|
recorded: [
|
|
7033
7038
|
"Its exchange_order runs in process in Datalayer's own tests against a stand-in for Manzanita's back office: one exchange per confirmed operation, a retry answered as already done.",
|
|
7034
7039
|
],
|
|
7035
7040
|
unverified: [
|
|
7036
|
-
"Drilled on r1 on 13 October 2026, twice: shipped at its own domain, it answered a personal agent signed out, and a person signed in through Datalayer granted orders:read and orders:write. The second time it knew who had signed in, but asked to exchange, it looked for the order first and proposed nothing; it now proposes the exchange at once, and Manzanita checks the order when it is done. Drilled a third time the same evening: signed in, asked to exchange, it said it could not — asked by a person's own agent, it was not given its exchange_order (fixed, not
|
|
7041
|
+
"Drilled on r1 on 13 October 2026, twice: shipped at its own domain, it answered a personal agent signed out, and a person signed in through Datalayer granted orders:read and orders:write. The second time it knew who had signed in, but asked to exchange, it looked for the order first and proposed nothing; it now proposes the exchange at once, and Manzanita checks the order when it is done. Drilled a third time the same evening: signed in, asked to exchange, it said it could not — asked by a person's own agent, it was not given its exchange_order (fixed). Drilled a fourth time the same night, given it: proposing the exchange ended its answer, and the personal agent was told it could not answer just now (fixed, released in runtime image 0.0.34).",
|
|
7037
7042
|
],
|
|
7038
7043
|
},
|
|
7039
7044
|
},
|
|
@@ -7044,8 +7049,6 @@ export const APP_SOURCES = {
|
|
|
7044
7049
|
deployment: {
|
|
7045
7050
|
hosted: {},
|
|
7046
7051
|
},
|
|
7047
|
-
enabled: false,
|
|
7048
|
-
unavailable_because: "Asked by a person's own agent, it is not given its exchange_order until a fix is released.",
|
|
7049
7052
|
tags: ['example', 'companies', 'python'],
|
|
7050
7053
|
emoji: '🏪',
|
|
7051
7054
|
},
|