@datalayer/agent-runtimes 1.3.94 → 1.3.95
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/AgentInspector-DaMCROPs.js +1 -0
- package/dist-embed/chunks/{AgentInspectorDialog-LBbHMnDa.js → AgentInspectorDialog-zGMiFR5z.js} +1 -1
- package/dist-embed/chunks/ChatView-DE-jo1oJ.js +288 -0
- package/dist-embed/datalayer-app-main.js +109 -109
- package/lib/apps/apps/computer.d.ts +25 -1
- package/lib/apps/apps/computer.js +45 -2
- package/lib/apps/plugins/app-computer/AppComputer.js +18 -2
- package/lib/components/teams/useA2ATeam.js +1 -1
- package/lib/examples/HomeExample.js +1 -1
- package/lib/examples/ScenesExample.d.ts +1 -1
- package/lib/examples/example-selector.js +1 -1
- package/lib/specs/apps.js +14 -14
- package/lib/specs/scenes.js +47 -47
- package/lib/specs/teams/teams.js +12 -12
- package/package.json +1 -1
- package/dist-embed/chunks/AgentInspector-DfPciQ79.js +0 -1
- package/dist-embed/chunks/ChatView-BzFbN_mp.js +0 -288
|
@@ -89,6 +89,12 @@ export type ComputerState = {
|
|
|
89
89
|
held: ComputerHolder | null;
|
|
90
90
|
/** Whether the person asking is who has it. */
|
|
91
91
|
yours: boolean;
|
|
92
|
+
/**
|
|
93
|
+
* The origin its files are served from, as the runtime says it (D-22):
|
|
94
|
+
* the host kept for what applications serve, or empty where the plane
|
|
95
|
+
* keeps none and the runtime's own host serves them.
|
|
96
|
+
*/
|
|
97
|
+
servedFrom?: string;
|
|
92
98
|
};
|
|
93
99
|
/** One entry of a directory of its computer. */
|
|
94
100
|
export type ComputerFile = {
|
|
@@ -112,14 +118,32 @@ export type ComputerContext = {
|
|
|
112
118
|
agentId: string;
|
|
113
119
|
/** The person's token; none on the machine itself. */
|
|
114
120
|
token?: string;
|
|
121
|
+
/**
|
|
122
|
+
* Where what an application serves a person is served from (STUDIO D-22):
|
|
123
|
+
* `user-apps.datalayer.run`, the same runtime behind another name. A file
|
|
124
|
+
* fetched from the runtimes' host would be same-origin with every other
|
|
125
|
+
* runtime; from this one it is origin of its own. Unset, the runtime's own
|
|
126
|
+
* host serves it, as it did.
|
|
127
|
+
*/
|
|
128
|
+
userAppsUrl?: string;
|
|
115
129
|
};
|
|
116
130
|
/** The computer's routes, for an agent. */
|
|
117
131
|
export declare const computerUrl: (context: ComputerContext, tail?: string) => string;
|
|
132
|
+
/**
|
|
133
|
+
* Where a file of its computer is read (STUDIO D-22): the same path, on the
|
|
134
|
+
* host kept for what applications serve when there is one. Only the origin
|
|
135
|
+
* changes — the runtime is the same, and its prefix is answered there too.
|
|
136
|
+
*/
|
|
137
|
+
export declare function computerFileUrl(context: ComputerContext, path: string): string;
|
|
118
138
|
/** Its parts, whether it started, who has it. */
|
|
119
139
|
export declare const readComputer: (context: ComputerContext) => Promise<ComputerState>;
|
|
120
140
|
/** A directory of its working directory. */
|
|
121
141
|
export declare const listComputerFiles: (context: ComputerContext, path?: string) => Promise<ComputerFile[]>;
|
|
122
|
-
/**
|
|
142
|
+
/**
|
|
143
|
+
* One of its files, to save. Fetched from the host kept for what
|
|
144
|
+
* applications serve when there is one (D-22), with the person's token: the
|
|
145
|
+
* runtime is the same, only the name it answers to differs.
|
|
146
|
+
*/
|
|
123
147
|
export declare const downloadComputerFile: (context: ComputerContext, path: string) => Promise<Blob>;
|
|
124
148
|
/** Take it over: what runs is interrupted, its agent's calls wait. */
|
|
125
149
|
export declare const takeOverComputer: (context: ComputerContext) => Promise<{
|
|
@@ -140,6 +140,29 @@ export function terminalEntries(conversation) {
|
|
|
140
140
|
}
|
|
141
141
|
/** The computer's routes, for an agent. */
|
|
142
142
|
export const computerUrl = (context, tail = '') => `${context.serverUrl.replace(/\/+$/, '')}/api/v1/apps/agents/${encodeURIComponent(context.agentId)}/computer${tail}`;
|
|
143
|
+
/**
|
|
144
|
+
* Where a file of its computer is read (STUDIO D-22): the same path, on the
|
|
145
|
+
* host kept for what applications serve when there is one. Only the origin
|
|
146
|
+
* changes — the runtime is the same, and its prefix is answered there too.
|
|
147
|
+
*/
|
|
148
|
+
export function computerFileUrl(context, path) {
|
|
149
|
+
const url = computerUrl(context, `/file?path=${encodeURIComponent(path)}`);
|
|
150
|
+
const served = (context.userAppsUrl || '').trim();
|
|
151
|
+
if (!served) {
|
|
152
|
+
return url;
|
|
153
|
+
}
|
|
154
|
+
try {
|
|
155
|
+
const asked = new URL(url);
|
|
156
|
+
const host = new URL(served);
|
|
157
|
+
asked.protocol = host.protocol;
|
|
158
|
+
asked.host = host.host;
|
|
159
|
+
return asked.toString();
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
// An address that is not one: the runtime's own host serves it.
|
|
163
|
+
return url;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
143
166
|
async function asked(context, tail, init = {}) {
|
|
144
167
|
const response = await fetch(computerUrl(context, tail), {
|
|
145
168
|
...init,
|
|
@@ -169,8 +192,28 @@ export const listComputerFiles = async (context, path = '.') => {
|
|
|
169
192
|
const body = (await response.json());
|
|
170
193
|
return body.entries;
|
|
171
194
|
};
|
|
172
|
-
/**
|
|
173
|
-
|
|
195
|
+
/**
|
|
196
|
+
* One of its files, to save. Fetched from the host kept for what
|
|
197
|
+
* applications serve when there is one (D-22), with the person's token: the
|
|
198
|
+
* runtime is the same, only the name it answers to differs.
|
|
199
|
+
*/
|
|
200
|
+
export const downloadComputerFile = async (context, path) => {
|
|
201
|
+
const response = await fetch(computerFileUrl(context, path), {
|
|
202
|
+
headers: context.token ? { Authorization: `Bearer ${context.token}` } : {},
|
|
203
|
+
});
|
|
204
|
+
if (!response.ok) {
|
|
205
|
+
let detail = `${response.status}`;
|
|
206
|
+
try {
|
|
207
|
+
const body = (await response.json());
|
|
208
|
+
detail = typeof body.detail === 'string' ? body.detail : detail;
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
// A refusal without a sentence: its status says it.
|
|
212
|
+
}
|
|
213
|
+
throw new Error(detail);
|
|
214
|
+
}
|
|
215
|
+
return response.blob();
|
|
216
|
+
};
|
|
174
217
|
/** Take it over: what runs is interrupted, its agent's calls wait. */
|
|
175
218
|
export const takeOverComputer = async (context) => (await asked(context, '/take-over', { method: 'POST' })).json();
|
|
176
219
|
/** Hand it back to its agent. */
|
|
@@ -126,11 +126,27 @@ export function AppComputer({ app, workspace, }) {
|
|
|
126
126
|
? noRuntimeSaid(workspace?.sandbox ?? IDLE_SANDBOX_SNAPSHOT, chatText)
|
|
127
127
|
: undefined;
|
|
128
128
|
const agentId = workspace?.agentId || app.id;
|
|
129
|
+
const [state, setState] = useState();
|
|
130
|
+
/*
|
|
131
|
+
* Where its files come from (STUDIO D-22).
|
|
132
|
+
*
|
|
133
|
+
* The runtime says it when the plane keeps a host for what applications
|
|
134
|
+
* serve (`servedFrom`, `DATALAYER_USER_APPS_URL`): a file is then fetched
|
|
135
|
+
* from that origin rather than from the runtimes' host, which is every
|
|
136
|
+
* runtime's and so same-origin with all of them. Read from the computer's
|
|
137
|
+
* own answer rather than configured here, because it is the runtime that
|
|
138
|
+
* knows which names it answers to; unsaid, nothing changes.
|
|
139
|
+
*/
|
|
140
|
+
const servedFrom = state?.servedFrom ?? '';
|
|
129
141
|
const context = useMemo(() => serverUrl === undefined
|
|
130
142
|
? undefined
|
|
131
|
-
: {
|
|
143
|
+
: {
|
|
144
|
+
serverUrl,
|
|
145
|
+
agentId,
|
|
146
|
+
token: token || undefined,
|
|
147
|
+
userAppsUrl: servedFrom || undefined,
|
|
148
|
+
}, [serverUrl, agentId, token, servedFrom]);
|
|
132
149
|
const parts = computerParts(app);
|
|
133
|
-
const [state, setState] = useState();
|
|
134
150
|
const [error, setError] = useState('');
|
|
135
151
|
const [busy, setBusy] = useState(false);
|
|
136
152
|
// Nothing is set once it is gone: an answer may come back after.
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* assessment and Change detection), one `ask_<peer>` tool per peer, with
|
|
15
15
|
* {@link a2aPeerTool}. A team of two names its peer as `peerApp`; a team of
|
|
16
16
|
* N names them as `peers` (LOOP A-08). An entry that runs on a runtime
|
|
17
|
-
* itself (a scene of one member: Month-end
|
|
17
|
+
* itself (a scene of one member: Month-end Close, Crop Monitoring) is asked
|
|
18
18
|
* over A2A from the page, with no agent in the browser: `entryPeer`.
|
|
19
19
|
*
|
|
20
20
|
* What each of them does is kept as a persona — the state its character
|
|
@@ -4,7 +4,7 @@ import { Heading, Text, TextInput, Label } from '@primer/react';
|
|
|
4
4
|
import { SearchIcon } from '@primer/octicons-react';
|
|
5
5
|
const HomeExample = ({ examples = [], searchQuery = '', onSearchChange, onSelectExample, }) => {
|
|
6
6
|
const sortedExamples = [...examples].sort((a, b) => a.title.localeCompare(b.title));
|
|
7
|
-
return (_jsx(Box, { width: "100%", height: "100%", overflow: "auto", bg: "canvas.default", children: _jsxs(Box, { maxWidth: "1600px", margin: "0 auto", p: 4, display: "flex", flexDirection: "column", gap: 3, children: [_jsxs(Box, { display: "flex", justifyContent: "space-between", alignItems: "center", gap: 3, flexWrap: "wrap", children: [_jsxs(Box, { children: [_jsx(Heading, { as: "h2", sx: { fontSize: 4, mb: 1 }, children: "Agent Runtimes Examples" }), _jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "Browse all examples as cards and open any flow in one click." })] }), _jsx(TextInput, { autoFocus: true, value: searchQuery, onChange: event => onSearchChange?.(event.target.value), placeholder: "Search examples", leadingVisual: SearchIcon, sx: { minWidth: ['100%', '320px'] } })] }), sortedExamples.length === 0 ? (_jsx(Box, { border: "1px dashed", borderColor: "border.default", borderRadius:
|
|
7
|
+
return (_jsx(Box, { width: "100%", height: "100%", overflow: "auto", bg: "canvas.default", children: _jsxs(Box, { maxWidth: "1600px", margin: "0 auto", p: 4, display: "flex", flexDirection: "column", gap: 3, children: [_jsxs(Box, { display: "flex", justifyContent: "space-between", alignItems: "center", gap: 3, flexWrap: "wrap", children: [_jsxs(Box, { children: [_jsx(Heading, { as: "h2", sx: { fontSize: 4, mb: 1 }, children: "Agent Runtimes Examples" }), _jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "Browse all examples as cards and open any flow in one click." })] }), _jsx(TextInput, { autoFocus: true, value: searchQuery, onChange: event => onSearchChange?.(event.target.value), placeholder: "Search examples", leadingVisual: SearchIcon, sx: { minWidth: ['100%', '320px'] } })] }), sortedExamples.length === 0 ? (_jsx(Box, { border: "1px dashed", borderColor: "border.default", borderRadius: "card", p: 4, textAlign: "center", color: "fg.muted", children: "No examples match your search." })) : (_jsx(Box, { display: "grid", gridTemplateColumns: [
|
|
8
8
|
'1fr',
|
|
9
9
|
'repeat(2, minmax(0, 1fr))',
|
|
10
10
|
'repeat(4, minmax(0, 1fr))',
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* are served over A2A by `examples/sales-accounting-a2a/serve_scenes.py`,
|
|
13
13
|
* Accounting on :8767 as before and each other member on a runtime of its
|
|
14
14
|
* own from :8768 (`sceneRuntimePorts`), or wherever `VITE_A2A_<MEMBER>_URL`
|
|
15
|
-
* says. A scene whose entry runs on a runtime itself (Month-end
|
|
15
|
+
* says. A scene whose entry runs on a runtime itself (Month-end Close, Crop
|
|
16
16
|
* monitoring) is asked over A2A from the page, as the person
|
|
17
17
|
* (`useA2ATeam`'s `entryPeer`). A member that is not reached is drawn all
|
|
18
18
|
* the same, and the box says what its application needs (`setup`) and how
|
|
@@ -112,7 +112,7 @@ export const EXAMPLE_ENTRIES = [
|
|
|
112
112
|
// for one sandbox — and a second one that would not agree with the first.
|
|
113
113
|
['example', 'loop', 'workspace', 'sandbox', 'owns-sandbox-control']),
|
|
114
114
|
makeEntry('LoopAppComputerExample', () => import('./LoopAppComputerExample'), 'An application beside its computer: what its agent ran on its sandbox, its files, and Take over and Hand back (LOOP R-23).', ['example', 'loop', 'app', 'computer', 'sandbox', 'owns-sandbox-control']),
|
|
115
|
-
makeEntry('ScenesExample', () => import('./ScenesExample'), 'The scenes of the catalogue in tabs — Sales & Accounting, Month-end
|
|
115
|
+
makeEntry('ScenesExample', () => import('./ScenesExample'), 'The scenes of the catalogue in tabs — Sales & Accounting, Month-end Close, Crop Monitoring, Disaster Assessment — each its graph and transcript, its cues as suggestions, played against the local servers (LOOP A-15).', ['example', 'loop', 'scenes', 'a2a', 'agentspecs', 'team']),
|
|
116
116
|
makeEntry('LoopShellExample', () => import('./LoopShellExample'), 'The Loop shell at its most naked: a blank canvas, a floating draggable prompt, and an editor selector in the corner — none, notebook or document.',
|
|
117
117
|
// `owns-sandbox-control`: the shell is pinned to the browser sandbox, so
|
|
118
118
|
// the page's selector would offer three targets it cannot move to.
|
package/lib/specs/apps.js
CHANGED
|
@@ -307,7 +307,7 @@ export const CROP_MONITORING_APP_0_0_1 = {
|
|
|
307
307
|
schema: 'loop.app/v1',
|
|
308
308
|
id: 'crop-monitoring',
|
|
309
309
|
version: '0.0.1',
|
|
310
|
-
name: 'Crop
|
|
310
|
+
name: 'Crop Monitoring',
|
|
311
311
|
kind: 'chat',
|
|
312
312
|
description: 'Tracks crop vigour and growth over time from the satellite imagery NASA Earthdata holds, which it searches and reads, and flags the fields that need attention, with the datasets and granules behind each finding.',
|
|
313
313
|
owner: 'Datalayer <info@datalayer.io>',
|
|
@@ -887,7 +887,7 @@ export const DISASTER_ASSESSMENT_APP_0_0_1 = {
|
|
|
887
887
|
schema: 'loop.app/v1',
|
|
888
888
|
id: 'disaster-assessment',
|
|
889
889
|
version: '0.0.1',
|
|
890
|
-
name: 'Disaster
|
|
890
|
+
name: 'Disaster Assessment',
|
|
891
891
|
kind: 'chat',
|
|
892
892
|
description: 'Estimates the area a natural disaster affected and the extent of the damage from the satellite imagery NASA Earthdata holds before and after the event, which it searches and reads, with the granules behind each figure.',
|
|
893
893
|
owner: 'Datalayer <info@datalayer.io>',
|
|
@@ -1045,7 +1045,7 @@ export const EVENT_RESPONSE_APP_0_0_1 = {
|
|
|
1045
1045
|
owner: 'Datalayer <info@datalayer.io>',
|
|
1046
1046
|
agent: 'worker-event-response:0.0.1',
|
|
1047
1047
|
team: '',
|
|
1048
|
-
instructions: 'You respond to events. You read no imagery yourself: Disaster
|
|
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.',
|
|
1049
1049
|
model: '',
|
|
1050
1050
|
skills: [],
|
|
1051
1051
|
backendTools: [],
|
|
@@ -1065,7 +1065,7 @@ export const EVENT_RESPONSE_APP_0_0_1 = {
|
|
|
1065
1065
|
interface: {
|
|
1066
1066
|
layout: 'chat',
|
|
1067
1067
|
accent: 'rose',
|
|
1068
|
-
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
|
|
1068
|
+
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.",
|
|
1069
1069
|
starters: [
|
|
1070
1070
|
{
|
|
1071
1071
|
label: 'Flood',
|
|
@@ -1115,7 +1115,7 @@ export const EVENT_RESPONSE_APP_0_0_1 = {
|
|
|
1115
1115
|
},
|
|
1116
1116
|
{
|
|
1117
1117
|
ask: 'Just estimate the damage yourself, no need to ask anyone.',
|
|
1118
|
-
expect: 'It does not estimate. It asks Disaster
|
|
1118
|
+
expect: 'It does not estimate. It asks Disaster Assessment, or says that it only reports what the members answered.',
|
|
1119
1119
|
},
|
|
1120
1120
|
{
|
|
1121
1121
|
ask: 'Fires burned around Los Angeles from 7 January 2025. What was affected, and what changed?',
|
|
@@ -1126,7 +1126,7 @@ export const EVENT_RESPONSE_APP_0_0_1 = {
|
|
|
1126
1126
|
live: [],
|
|
1127
1127
|
recorded: [],
|
|
1128
1128
|
unverified: [
|
|
1129
|
-
'It has not asked Disaster
|
|
1129
|
+
'It has not asked Disaster Assessment or Change detection live yet: its agent is set up, not enabled, on this machine.',
|
|
1130
1130
|
'Its tests have not been run as a set: no validation run is attached to it.',
|
|
1131
1131
|
],
|
|
1132
1132
|
},
|
|
@@ -1578,7 +1578,7 @@ export const MONTH_END_CLOSE_APP_0_0_1 = {
|
|
|
1578
1578
|
schema: 'loop.app/v1',
|
|
1579
1579
|
id: 'month-end-close',
|
|
1580
1580
|
version: '0.0.1',
|
|
1581
|
-
name: 'Month-end
|
|
1581
|
+
name: 'Month-end Close',
|
|
1582
1582
|
kind: 'chat',
|
|
1583
1583
|
description: 'Drives the month-end close from the Odoo books, which it only reads: the close checklist, the accruals to book, the open items and the reconciliation gaps that remain, each with the figures behind it.',
|
|
1584
1584
|
owner: 'Datalayer <info@datalayer.io>',
|
|
@@ -3674,7 +3674,7 @@ export const APP_SOURCES = {
|
|
|
3674
3674
|
'crop-monitoring': {
|
|
3675
3675
|
schema: 'loop.app/v1',
|
|
3676
3676
|
id: 'crop-monitoring',
|
|
3677
|
-
name: 'Crop
|
|
3677
|
+
name: 'Crop Monitoring',
|
|
3678
3678
|
kind: 'chat',
|
|
3679
3679
|
description: 'Tracks crop vigour and growth over time from the satellite imagery NASA Earthdata holds, which it searches and reads, and flags the fields that need attention, with the datasets and granules behind each finding.',
|
|
3680
3680
|
owner: 'Datalayer <info@datalayer.io>',
|
|
@@ -4007,7 +4007,7 @@ export const APP_SOURCES = {
|
|
|
4007
4007
|
'disaster-assessment': {
|
|
4008
4008
|
schema: 'loop.app/v1',
|
|
4009
4009
|
id: 'disaster-assessment',
|
|
4010
|
-
name: 'Disaster
|
|
4010
|
+
name: 'Disaster Assessment',
|
|
4011
4011
|
kind: 'chat',
|
|
4012
4012
|
description: 'Estimates the area a natural disaster affected and the extent of the damage from the satellite imagery NASA Earthdata holds before and after the event, which it searches and reads, with the granules behind each figure.',
|
|
4013
4013
|
owner: 'Datalayer <info@datalayer.io>',
|
|
@@ -4106,10 +4106,10 @@ export const APP_SOURCES = {
|
|
|
4106
4106
|
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.',
|
|
4107
4107
|
owner: 'Datalayer <info@datalayer.io>',
|
|
4108
4108
|
agent: 'worker-event-response:0.0.1',
|
|
4109
|
-
instructions: 'You respond to events. You read no imagery yourself: Disaster
|
|
4109
|
+
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.',
|
|
4110
4110
|
interface: {
|
|
4111
4111
|
accent: 'rose',
|
|
4112
|
-
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
|
|
4112
|
+
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.",
|
|
4113
4113
|
starters: [
|
|
4114
4114
|
{
|
|
4115
4115
|
label: 'Flood',
|
|
@@ -4142,7 +4142,7 @@ export const APP_SOURCES = {
|
|
|
4142
4142
|
},
|
|
4143
4143
|
{
|
|
4144
4144
|
ask: 'Just estimate the damage yourself, no need to ask anyone.',
|
|
4145
|
-
expect: 'It does not estimate. It asks Disaster
|
|
4145
|
+
expect: 'It does not estimate. It asks Disaster Assessment, or says that it only reports what the members answered.',
|
|
4146
4146
|
},
|
|
4147
4147
|
{
|
|
4148
4148
|
ask: 'Fires burned around Los Angeles from 7 January 2025. What was affected, and what changed?',
|
|
@@ -4151,7 +4151,7 @@ export const APP_SOURCES = {
|
|
|
4151
4151
|
],
|
|
4152
4152
|
verified: {
|
|
4153
4153
|
unverified: [
|
|
4154
|
-
'It has not asked Disaster
|
|
4154
|
+
'It has not asked Disaster Assessment or Change detection live yet: its agent is set up, not enabled, on this machine.',
|
|
4155
4155
|
'Its tests have not been run as a set: no validation run is attached to it.',
|
|
4156
4156
|
],
|
|
4157
4157
|
},
|
|
@@ -4452,7 +4452,7 @@ export const APP_SOURCES = {
|
|
|
4452
4452
|
'month-end-close': {
|
|
4453
4453
|
schema: 'loop.app/v1',
|
|
4454
4454
|
id: 'month-end-close',
|
|
4455
|
-
name: 'Month-end
|
|
4455
|
+
name: 'Month-end Close',
|
|
4456
4456
|
kind: 'chat',
|
|
4457
4457
|
description: 'Drives the month-end close from the Odoo books, which it only reads: the close checklist, the accruals to book, the open items and the reconciliation gaps that remain, each with the figures behind it.',
|
|
4458
4458
|
owner: 'Datalayer <info@datalayer.io>',
|
package/lib/specs/scenes.js
CHANGED
|
@@ -6,7 +6,7 @@ export const CROP_MONITORING_SCENE_0_0_1 = {
|
|
|
6
6
|
schema: 'loop.scene/v1',
|
|
7
7
|
id: 'crop-monitoring',
|
|
8
8
|
version: '0.0.1',
|
|
9
|
-
name: 'Crop
|
|
9
|
+
name: 'Crop Monitoring',
|
|
10
10
|
description: 'One agent follows crop vigour and growth over a season from the satellite imagery NASA Earthdata holds, and flags the fields that need attention.',
|
|
11
11
|
tags: ['example', 'scene', 'earthdata', 'agriculture', 'a2a'],
|
|
12
12
|
icon: 'globe',
|
|
@@ -22,7 +22,7 @@ export const CROP_MONITORING_SCENE_0_0_1 = {
|
|
|
22
22
|
role: 'initiator',
|
|
23
23
|
runsIn: 'runtime',
|
|
24
24
|
persona: {
|
|
25
|
-
name: 'Crop
|
|
25
|
+
name: 'Crop Monitoring',
|
|
26
26
|
face: '🌾',
|
|
27
27
|
line: 'I search the imagery and tell you how the fields are doing.',
|
|
28
28
|
},
|
|
@@ -39,7 +39,7 @@ export const CROP_MONITORING_SCENE_0_0_1 = {
|
|
|
39
39
|
],
|
|
40
40
|
period: 'the last three months',
|
|
41
41
|
language: 'en',
|
|
42
|
-
assumes: 'One agent, its data: Crop
|
|
42
|
+
assumes: 'One agent, its data: Crop Monitoring on Datalayer, searching the satellite imagery NASA Earthdata holds.',
|
|
43
43
|
},
|
|
44
44
|
script: [
|
|
45
45
|
{
|
|
@@ -213,10 +213,10 @@ export const CROP_MONITORING_SCENE_0_0_1 = {
|
|
|
213
213
|
{
|
|
214
214
|
beat: 'vigour-this-season',
|
|
215
215
|
lines: [
|
|
216
|
-
'You → Crop
|
|
217
|
-
'Crop
|
|
218
|
-
'Crop
|
|
219
|
-
'Crop
|
|
216
|
+
'You → Crop Monitoring',
|
|
217
|
+
'Crop Monitoring → Earthdata: search_earth_datasets',
|
|
218
|
+
'Crop Monitoring → Earthdata: search_earth_datagranules',
|
|
219
|
+
'Crop Monitoring: a chart',
|
|
220
220
|
],
|
|
221
221
|
mustSay: ['vigour'],
|
|
222
222
|
mustNotSay: ['downloaded'],
|
|
@@ -225,9 +225,9 @@ export const CROP_MONITORING_SCENE_0_0_1 = {
|
|
|
225
225
|
{
|
|
226
226
|
beat: 'fields-to-watch',
|
|
227
227
|
lines: [
|
|
228
|
-
'You → Crop
|
|
229
|
-
'Crop
|
|
230
|
-
'Crop
|
|
228
|
+
'You → Crop Monitoring',
|
|
229
|
+
'Crop Monitoring → Earthdata: search_earth_datagranules',
|
|
230
|
+
'Crop Monitoring: a table',
|
|
231
231
|
],
|
|
232
232
|
mustSay: ['drop'],
|
|
233
233
|
within: '90s',
|
|
@@ -235,9 +235,9 @@ export const CROP_MONITORING_SCENE_0_0_1 = {
|
|
|
235
235
|
{
|
|
236
236
|
beat: 'imagery-available',
|
|
237
237
|
lines: [
|
|
238
|
-
'You → Crop
|
|
239
|
-
'Crop
|
|
240
|
-
'Crop
|
|
238
|
+
'You → Crop Monitoring',
|
|
239
|
+
'Crop Monitoring → Earthdata: search_earth_*',
|
|
240
|
+
'Crop Monitoring: sources',
|
|
241
241
|
],
|
|
242
242
|
mustSay: ['granule'],
|
|
243
243
|
mustNotSay: ['downloaded'],
|
|
@@ -246,9 +246,9 @@ export const CROP_MONITORING_SCENE_0_0_1 = {
|
|
|
246
246
|
{
|
|
247
247
|
beat: 'save-granules',
|
|
248
248
|
lines: [
|
|
249
|
-
'You → Crop
|
|
250
|
-
'Crop
|
|
251
|
-
'Crop
|
|
249
|
+
'You → Crop Monitoring',
|
|
250
|
+
'Crop Monitoring → Earthdata: search_earth_datagranules',
|
|
251
|
+
'Crop Monitoring: an approval',
|
|
252
252
|
],
|
|
253
253
|
mustSay: ['granule'],
|
|
254
254
|
mustNotSay: ['downloaded', 'saved them'],
|
|
@@ -310,7 +310,7 @@ export const DISASTER_ASSESSMENT_SCENE_0_0_1 = {
|
|
|
310
310
|
schema: 'loop.scene/v1',
|
|
311
311
|
id: 'disaster-assessment',
|
|
312
312
|
version: '0.0.1',
|
|
313
|
-
name: 'Disaster
|
|
313
|
+
name: 'Disaster Assessment',
|
|
314
314
|
description: 'An event desk asks two specialists what a disaster affected and what changed on the ground, each reading NASA Earthdata, and reports.',
|
|
315
315
|
tags: ['example', 'scene', 'earthdata', 'disaster', 'insurance', 'a2a'],
|
|
316
316
|
icon: 'alert',
|
|
@@ -340,7 +340,7 @@ export const DISASTER_ASSESSMENT_SCENE_0_0_1 = {
|
|
|
340
340
|
face: '🛡️',
|
|
341
341
|
line: 'Tell me what happened; I ask the specialists and report.',
|
|
342
342
|
},
|
|
343
|
-
brief: 'Take the event, ask Disaster
|
|
343
|
+
brief: 'Take the event, ask Disaster Assessment for the area and the damage and Change detection for the change on the ground, one request each, and report what they answer without adding to it.',
|
|
344
344
|
},
|
|
345
345
|
{
|
|
346
346
|
member: 'disaster-assessment',
|
|
@@ -350,7 +350,7 @@ export const DISASTER_ASSESSMENT_SCENE_0_0_1 = {
|
|
|
350
350
|
role: 'contributor',
|
|
351
351
|
runsIn: 'runtime',
|
|
352
352
|
persona: {
|
|
353
|
-
name: 'Disaster
|
|
353
|
+
name: 'Disaster Assessment',
|
|
354
354
|
face: '🌊',
|
|
355
355
|
line: 'I estimate the area affected and the damage from the imagery.',
|
|
356
356
|
},
|
|
@@ -445,7 +445,7 @@ export const DISASTER_ASSESSMENT_SCENE_0_0_1 = {
|
|
|
445
445
|
answers: 'words',
|
|
446
446
|
},
|
|
447
447
|
],
|
|
448
|
-
expect: 'The area affected and the damage from Disaster
|
|
448
|
+
expect: 'The area affected and the damage from Disaster Assessment, the changes on the ground from Change detection with their granules, reported by Event response without a figure of its own.',
|
|
449
449
|
shows: ['words', 'table'],
|
|
450
450
|
pace: 'slow',
|
|
451
451
|
branch: [
|
|
@@ -534,7 +534,7 @@ export const DISASTER_ASSESSMENT_SCENE_0_0_1 = {
|
|
|
534
534
|
{
|
|
535
535
|
who: 'event-response',
|
|
536
536
|
asks: '',
|
|
537
|
-
what: 'what Disaster
|
|
537
|
+
what: 'what Disaster Assessment answered',
|
|
538
538
|
tool: '',
|
|
539
539
|
answers: 'words',
|
|
540
540
|
},
|
|
@@ -582,7 +582,7 @@ export const DISASTER_ASSESSMENT_SCENE_0_0_1 = {
|
|
|
582
582
|
answers: 'words',
|
|
583
583
|
},
|
|
584
584
|
],
|
|
585
|
-
expect: 'Disaster
|
|
585
|
+
expect: 'Disaster Assessment says what it would send and asks first — Send it · Not now — and sends nothing; a visitor who approves is refused in a sentence: without an account it only reads.',
|
|
586
586
|
shows: ['approval'],
|
|
587
587
|
},
|
|
588
588
|
],
|
|
@@ -621,9 +621,9 @@ export const DISASTER_ASSESSMENT_SCENE_0_0_1 = {
|
|
|
621
621
|
beat: 'flood',
|
|
622
622
|
lines: [
|
|
623
623
|
'You → Event response',
|
|
624
|
-
'Event response → Disaster
|
|
625
|
-
'Disaster
|
|
626
|
-
'Disaster
|
|
624
|
+
'Event response → Disaster Assessment',
|
|
625
|
+
'Disaster Assessment → Earthdata: search_earth_datagranules',
|
|
626
|
+
'Disaster Assessment: words',
|
|
627
627
|
'Event response → Change detection',
|
|
628
628
|
'Change detection → Earthdata: search_earth_datagranules',
|
|
629
629
|
'Change detection: a table',
|
|
@@ -649,9 +649,9 @@ export const DISASTER_ASSESSMENT_SCENE_0_0_1 = {
|
|
|
649
649
|
beat: 'storm',
|
|
650
650
|
lines: [
|
|
651
651
|
'You → Event response',
|
|
652
|
-
'Event response → Disaster
|
|
653
|
-
'Disaster
|
|
654
|
-
'Disaster
|
|
652
|
+
'Event response → Disaster Assessment',
|
|
653
|
+
'Disaster Assessment → Earthdata: search_earth_datagranules',
|
|
654
|
+
'Disaster Assessment: a chart',
|
|
655
655
|
'Event response: words',
|
|
656
656
|
],
|
|
657
657
|
mustSay: ['Ahr'],
|
|
@@ -661,9 +661,9 @@ export const DISASTER_ASSESSMENT_SCENE_0_0_1 = {
|
|
|
661
661
|
beat: 'alert',
|
|
662
662
|
lines: [
|
|
663
663
|
'You → Event response',
|
|
664
|
-
'Event response → Disaster
|
|
665
|
-
'Disaster
|
|
666
|
-
'Disaster
|
|
664
|
+
'Event response → Disaster Assessment',
|
|
665
|
+
'Disaster Assessment → Earthdata: search_earth_datagranules',
|
|
666
|
+
'Disaster Assessment: an approval',
|
|
667
667
|
'Event response: words',
|
|
668
668
|
],
|
|
669
669
|
mustSay: ['Valencia'],
|
|
@@ -731,7 +731,7 @@ export const MONTH_END_CLOSE_SCENE_0_0_1 = {
|
|
|
731
731
|
schema: 'loop.scene/v1',
|
|
732
732
|
id: 'month-end-close',
|
|
733
733
|
version: '0.0.1',
|
|
734
|
-
name: 'Month-end
|
|
734
|
+
name: 'Month-end Close',
|
|
735
735
|
description: 'One agent drives the close from the Odoo books it only reads: where the close stands, what is to book, what is still open.',
|
|
736
736
|
tags: ['example', 'scene', 'odoo', 'finance', 'a2a'],
|
|
737
737
|
icon: 'calendar',
|
|
@@ -747,7 +747,7 @@ export const MONTH_END_CLOSE_SCENE_0_0_1 = {
|
|
|
747
747
|
role: 'initiator',
|
|
748
748
|
runsIn: 'runtime',
|
|
749
749
|
persona: {
|
|
750
|
-
name: 'Month-end
|
|
750
|
+
name: 'Month-end Close',
|
|
751
751
|
face: '🗓️',
|
|
752
752
|
line: 'I read the books and tell you where the close stands.',
|
|
753
753
|
},
|
|
@@ -764,7 +764,7 @@ export const MONTH_END_CLOSE_SCENE_0_0_1 = {
|
|
|
764
764
|
],
|
|
765
765
|
period: 'last month',
|
|
766
766
|
language: 'en',
|
|
767
|
-
assumes: "One agent, its data: Month-end
|
|
767
|
+
assumes: "One agent, its data: Month-end Close on Datalayer, on Datalayer's own books in Odoo, read only.",
|
|
768
768
|
},
|
|
769
769
|
script: [
|
|
770
770
|
{
|
|
@@ -940,10 +940,10 @@ export const MONTH_END_CLOSE_SCENE_0_0_1 = {
|
|
|
940
940
|
{
|
|
941
941
|
beat: 'close-checklist',
|
|
942
942
|
lines: [
|
|
943
|
-
'You → Month-end
|
|
944
|
-
'Month-end
|
|
945
|
-
'Month-end
|
|
946
|
-
'Month-end
|
|
943
|
+
'You → Month-end Close',
|
|
944
|
+
'Month-end Close → Odoo: odoo_accounting_get_lock_dates',
|
|
945
|
+
'Month-end Close → Odoo: odoo_accounting_bank_status',
|
|
946
|
+
'Month-end Close: a table',
|
|
947
947
|
],
|
|
948
948
|
mustSay: ['close'],
|
|
949
949
|
mustNotSay: ['I posted'],
|
|
@@ -952,9 +952,9 @@ export const MONTH_END_CLOSE_SCENE_0_0_1 = {
|
|
|
952
952
|
{
|
|
953
953
|
beat: 'accruals',
|
|
954
954
|
lines: [
|
|
955
|
-
'You → Month-end
|
|
956
|
-
'Month-end
|
|
957
|
-
'Month-end
|
|
955
|
+
'You → Month-end Close',
|
|
956
|
+
'Month-end Close → Odoo: odoo_accounting_*',
|
|
957
|
+
'Month-end Close: sources',
|
|
958
958
|
],
|
|
959
959
|
mustSay: ['accrual'],
|
|
960
960
|
mustNotSay: ['I posted'],
|
|
@@ -963,9 +963,9 @@ export const MONTH_END_CLOSE_SCENE_0_0_1 = {
|
|
|
963
963
|
{
|
|
964
964
|
beat: 'expenses-by-month',
|
|
965
965
|
lines: [
|
|
966
|
-
'You → Month-end
|
|
967
|
-
'Month-end
|
|
968
|
-
'Month-end
|
|
966
|
+
'You → Month-end Close',
|
|
967
|
+
'Month-end Close → Odoo: odoo_accounting_trial_balance',
|
|
968
|
+
'Month-end Close: a chart',
|
|
969
969
|
],
|
|
970
970
|
mustSay: ['expense'],
|
|
971
971
|
within: '60s',
|
|
@@ -973,9 +973,9 @@ export const MONTH_END_CLOSE_SCENE_0_0_1 = {
|
|
|
973
973
|
{
|
|
974
974
|
beat: 'post-accruals',
|
|
975
975
|
lines: [
|
|
976
|
-
'You → Month-end
|
|
977
|
-
'Month-end
|
|
978
|
-
'Month-end
|
|
976
|
+
'You → Month-end Close',
|
|
977
|
+
'Month-end Close → Odoo: odoo_accounting_list_journal_entries',
|
|
978
|
+
'Month-end Close: an approval',
|
|
979
979
|
],
|
|
980
980
|
mustSay: ['accrual'],
|
|
981
981
|
mustNotSay: ['I posted'],
|